webpack主要內容

webpack的核心概念:
·    entry 一個可執行模塊或庫的入口文件。
·    chunk 多個文件組成的一個代碼塊,例如把一個可執行模塊和它全部依賴的模塊組合和一個 chunk 這體現了webpack的打包機制。
·    loader 文件轉換器,例如把es6轉換爲es5,scss轉換爲css。
·    plugin 插件,用於擴展webpack的功能,在webpack構建生命週期的節點上加入擴展hook爲webpack加入功能。
從啓動webpack構建到輸出結果經歷了一系列過程,它們是:
1.    解析webpack配置參數,合併從shell傳入和webpack.config.js文件裏配置的參數,生產最後的配置結果。
2.    註冊全部配置的插件,好讓插件監聽webpack構建生命週期的事件節點,以作出對應的反應。
3.    從配置的entry入口文件開始解析文件構建AST語法樹,找出每一個文件所依賴的文件,遞歸下去。
4.    在解析文件遞歸的過程當中根據文件類型和loader配置找出合適的loader用來對文件進行轉換。
5.    遞歸完後獲得每一個文件的最終結果,根據entry配置生成代碼塊chunk。
6.    輸出全部chunk到文件系統。
須要注意的是,在構建生命週期中有一系列插件在合適的時機作了合適的事情,好比UglifyJsPlugin會在loader轉換遞歸完後對結果再使用UglifyJs壓縮覆蓋以前的結果。
 
 
webpack是react項目標配的打包工具,和NPM搭配起來使用管理模塊實在很是方便。
  webapck 把全部的靜態資源都看作是一個 module,經過 webpack,將這些 module 組成到一個 bundle 中去,從而實如今頁面上引入一個 bundle.js,來實現全部靜態資源的加載。
 
 
webpack 打包後源碼有讀過嗎 模塊之間怎麼依賴的
每一個模塊都會被賦予一個id(正常是從0開始的數字),模塊之間經過內置的__webpack_require__函數來模擬CommonJS,從而創建聯繫
 
webpack打包流程
流程圖:  https://img.alicdn.com/tps/TB1GVGFNXXXXXaTapXXXXXXXXXX-4436-4244.jpg
 
webpack中的ESlint怎麼配置
1).安裝
須要這幾個npm包:
·    eslint
·    eslint-loader
·    eslint-plugin-html (用以lint一些在html文件裏面經過script包裹的js代碼,它默認的匹配規則是不帶type屬性,或者是`/^(application|text)/(x-)?(javascript|babel|ecmascript-6)$/i`,具體的內容請查閱相關文檔,經過cli啓動lint的時候定義文件後綴名時eslint --ext .html,.js)
·    eslint-config-standard (和javascript-style-standard風格指南須要的包)
·    eslint-plugin-promise
·    eslint-plugin-standard
·    eslint-friendly-formatter (生成的報告格式)
2).配置ESlint
關於eslint的配置方式。比較多元化:
·    js註釋
·    .eslintrc.*文件
·    package.json裏面配置eslintConfig字段
可使用任何一個配置來配置ESlint,對於ESlint如何配置,這個裏就不贅述了.
3).配置webpack
在webpack中的js模塊處進行eslint-loader的配置,示例代碼以下所示:
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // exclude: /node_modules/ 能夠不用定義這個字段的屬性值,eslint會自動忽略node_modules
enforce: 'pre', // 在babel-loader對源碼進行編譯前進行lint的檢查
include: /src/, // src文件夾下的文件須要被lint
use: [{
loader:'babel-loader'
},{
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter') // 編譯後錯誤報告格式
}
}],
query: {
cacheDirectory: true
}
}
]
}
4).配置package.json
在package.json中配置npm命令:
{
        ...
        "lint": "eslint --ext .js src"
        ...
}
而後執行npm run lint 來進行代碼的靜態檢查
 
 

定位 Webpack 速度慢的緣由

打包的命令webpack後加三個參數:
  • --colors 輸出結果帶彩色,好比:會用紅色顯示耗時較長的步驟
  • --profile 輸出性能數據,能夠看到每一步的耗時
  • --display-modules 默認狀況下 node_modules 下的模塊會被隱藏,加上這個參數能夠顯示這些被隱藏的模塊
從命令行的結果裏具體分析速度慢的緣由。
 
 

經過Resolve設置,提升模塊分析依賴的速度

resolve主要是用來配置解析模塊路徑和分析依賴,可讓require模塊的定位更快。
1.resolve.alias
別名是 Webpack 的一個配置項,它的做用是把用戶的一個請求重定向到另外一個路徑 。若是在alias中定義了值,而後在代碼中require該值的時候,會重定向到alias指定的位置。
 
2.resolve.root和resolve.modulesDirectories
root是經過絕對路徑的方式來定義查找模塊的文件夾。能夠是一個數組,主要是用來增長模塊的搜尋位置使用的。
modulesDirectories是用來設置搜索的目錄名的,默認值:["web_modules", "node_modules"]。若是把值設置成["mydir"]
, webpack會查詢 「./mydir」, 「../mydir」, 「../../mydir」等。
注意: Passing"../someDir","app","."or an absolute path isn’t necessary here. Just use a directory name, not a path. Use only if you expect to have a hierarchy within these folders. Otherwise you may want to use theresolve.root
option instead.
 

配置module.noParse

module.noParse是webpack的另外一個頗有用的配置項,若是你 肯定一個模塊中沒有其它新的依賴就能夠配置這項,webpack將再也不掃描這個文件中的依賴。
module: {
    noParse: [/moment-with-locales/]
}
 

配置Loader的exclude或include來設定babel的使用範圍

對於不少的 npm 包來講,他們徹底沒有通過 babel 的必要(成熟的 npm 包會在發佈前將本身 es5,甚至 es3 化),讓這些包經過 babel 會帶來巨大的性能負擔。
使用 exclude,屏蔽掉 npm 裏的包,從而使整包的構建效率飛速提升。
module: {
   loaders: [ {
     test: /\.js(x)*$/,
     loader: 'babel-loader',
     exclude: function(path) {
         // 路徑中含有 node_modules 的就不去解析。
         var isNpmModule = !!path.match(node_modules/);
         return isNpmModule;
    },
    query: {
        presets: ['react', 'es2015-ie', 'stage-1']
    }
  } ]
}
甚至,在十分確信的狀況下,使用 include 來限定 babel 的使用範圍,進一步提升效率。
module: {
    loaders: [ {
       test: /\.js(x)*$/,
       loader: 'babel-loader',
       include: [  
          // 只去解析運行目錄下的 src 和 demo 文件夾
          path.join(process.cwd(), './src'),
          path.join(process.cwd(), './demo')
       ],
       query: {
           presets: ['react', 'es2015-ie', 'stage-1']
       }
    } ]
}
 

使用externals,把不須要打包的模塊排除在外

Webpack 能夠配置 externals來將依賴的庫指向全局變量,從而再也不打包這個庫。在頁面上引入 Web 上的公用 CDN 服務。
webpack中配置:
     externals: { moment: true }
 
頁面html上引入script:
<script src="//apps.bdimg.com/libs/moment/2.8.3/moment-with-locales.min.js"></script>
等於讓 Webpack 知道,對於 moment這個模塊就不要打包啦,直接指向 window.moment就好。不過別忘了加載moment-with-locales.min.js,讓全局中有 moment這個變量。
 

使用DLL & DllReference

除了正在開發的源代碼以外,一般還會引入不少第三方 NPM 包,這些包咱們不會進行修改,可是仍然須要在每次 build 的過程當中消耗構建性能,那有沒有什麼辦法能夠減小這些消耗呢?DLLPlugin 就是一個解決方案,他經過前置這些依賴包的構建,來提升真正的 build 和 rebuild 的構建效率。
首先,咱們來寫一個 DLLPlugin 的 config 文件。定義webpack-dll-config.js文件:
const path = require('path');
const webpack=require('webpack');
 
const vendors=[
    'react',
    'react-dom',
    'react-router',
    'history',
    'immutable',
    'redux',
    'react-redux',
    'redux-router',
    'redux-thunk',
    'moment',
    'es6-promise',
    'whatwg-fetch',
    'lodash'
];
 
module.exports={
    entry:{
        'vendor':vendors,
    },
    output:{
        path:path.join(__dirname, 'dist'),
        filename:'[name].dll.js',//[name]的部分由entry的名字替換
        /**
         * output.library
         * 將會定義爲 window.${output.library}
         * 在此次的例子中,將會定義爲`window.vendor_library`
         */
        library:'[name]_library',
    },
    plugins:[
        new webpack.DllPlugin({
            /**
             * path 定義 manifest 文件生成的位置
             */
            path:'manifest.json',
            /**
             * name 是dll暴露的對象名,要跟 output.library 保持一致;
             * dll bundle 輸出到那個全局變量上
             */
            name: '[name]_library',
            context:__dirname //是解析包路徑的上下文,這個要跟接下來配置的 webpack.config.js 一致。
        })
    ]
}
執行 命令【webpack --config webpack-dll-config.js 】就會在 dist 目錄下生成 dll bundle 和在根目錄生成對應的 manifest文件。manifest 文件的格式大體以下,由包含的 module 和對應的 id 的鍵值對構成。
接下來經過 DLLReferencePlugin 來使用剛纔生成的 DLL Bundle。在默認的webpack-config.js中添加plugins:
new webpack.DllReferencePlugin({
      context: __dirname,//context 須要跟dll中的保持一致,這個用來指導 Webpack 匹配 manifest 中庫的路徑;
      manifest: require('./manifest.json')
    }),
最後在頁面中要引入兩個js
<body>
    <script src="dist/vendor.dll.js"></script>
    <script src="dist/bundle.js"></script></body>
使用DLL這樣的方式的能夠把第三方包和本身的代碼包分離,有修改也只須要發佈本身的代碼包。

關於優化插件OPTIMIZATION

 webpack 提供了一些能夠優化瀏覽器端性能的優化插件,如UglifyJsPlugin,OccurrenceOrderPlugin 和 DedupePlugin,都很實用,也都在消耗構建性能(UglifyJsPlugin 很是耗性能),若是你是在開發環境下,這些插件最好都不要使用,畢竟腳本大一些,跑的慢一些這些比起每次構建要耗費更多時間來講,顯然仍是後者更會消磨開發者的耐心,所以,只在正產環境中使用 OPTIMIZATION。
 

CommonsChunkPlugin

 當你的 webpack 構建任務中有多個入口文件,而這些文件都 require 了相同的模塊,若是你不作任何事情,webpack 會爲每一個入口文件引入一份相同的模塊,顯然這樣作,會使得相同模塊變化時,全部引入的 entry 都須要一次 rebuild,形成了性能的浪費,CommonsChunkPlugin 能夠將相同的模塊提取出來單獨打包,進而減少 rebuild 時的性能消耗。
  同時將多個入口文件相同的js打包處一個共同的後,也能夠利用緩存,使加載第二頁面的時候不須要再加載共同文件。
commonsPlugin = newwebpack.optimize.CommonsChunkPlugin('common', 'common.[hash].js')
相關文章
相關標籤/搜索