準備工作
目前webpack作爲目前國內最火的打包及加載工具之一,經常在react工程中使用,接下來我們來詳細瞭解下webpack的使用姿勢
在接下來的操作步驟之前,需要先配置修改react工程下的package.json,增加devDependencies如下:
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"less-loader": "^2.2.2",
"portfinder": "^0.4.0",
"react-hot-loader": "^1.3.0",
"style-loader": "^0.13.0",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0",
"react": "^0.14.0",
"react-dom": "^0.14.0",
"react-router": "^2.0.0-rc5"
然後根據package.json使用npm install安裝依賴包,接下來就要開始我們的webpack之旅
- 其中react的工程文件結構爲
- project
- demo01
- index.html
- main.js
- components
- list.js
- webpack.config.js
- project
- 工程文件具體內容(除 webpack.config.js之外)就不再贅述,網上均有類似內容,然後執行webpack,會出現webpack:command not found的錯誤提示,經資料查證,方法之一需在~/.bash_profile中添加如下設置: export NODE_PATH=”/usr/local/lib/node_modules,然而這個並不現實(並不是全局安裝的webpack),方法之二是在package.json中加入
“scripts”: {
“build”: “webpack”
}
然後執行npm run build 即可實現webpack操作,接下來我們需要詳細分析下webpack.config.js配置文件可以包含哪些內容~
webpack.config.js配置詳解
最爲基礎的有以下幾項:
- entry: 定義了打包的入口文件,數組中的所有文件會按順序打包並尋找相關依賴(webpack建議使用commonJS的方式引入及定義依賴),數組數大於一經常是爲多頁面工程設計所需
- output: 定義輸出文件的位置,常用參數有:
- path: 打包文件存放的絕對路徑
- publicPath: 網站運行時的訪問路徑
filename: 打包後的文件名
如圖爲我們最原始的webpack.config.js文件
此時執行npm run build,則並不會在demo01文件夾下生成build/bundle_1.js,而是會報出You may need an appropriate loader to handle this file type這樣的紅色錯誤,這是因爲我們用了react!!! 沒有相關的預處理怎麼可以,這也是webpack最爲強大的地方,圖片,js,css等均可通過loader的方式引入進來{
module: {
loaders: [
{ test: /.js$/, loader: “react” }
]
}
}
其中test正則匹配所需處理文件,loader爲所需加載器,那如果需要多個loader去處理這些文件呢,我們可以將其中的loader替換成 loaders: [‘babel?presets[]=react,presets[]=es2015’] 其中presets後的爲預處理工具,輔助babel處理第二步的transform過程,詳細可見babel官網 (當使用loaders則不可再使用query選項)
那麼此時執行npm run build 便會執行webpack打包過程,接下來我們談談webpack其他配置項
升級配置項及優化性能
- debug:debug模式開始,webpack該配置項共有七種,有inline-source-map,debug等,目前我採用devtool: ‘#source-map’方式(僅在開發時使用,影響性能)
- output: 通過配置output.libraryTarget,可以自定義輸出的模塊類型,包括AMD,CommonJS,變量等,通過設置library,可以定義其模塊名稱
plugins: 引入對應插件,插件列表在webpack官網可搜索到,其中較爲主要的幾個有:
- new webpack.optimize.CommonsChunkPlugin,該插件的引入可抽離文件的公共部分,譬如entry有 vendor: [“jquery”, “underscore”, …]的相關依賴時,我們可通過把全部vendor依賴打包在vendor.bundle.js中
當entry存在多個文件需要打包時,使用CommonsChunk插件可將多個文件中的公共部分抽取出來,實現按需加載及緩存,提升頁面性能 - new webpack.optimize.LimitChunkCountPlugin({maxChunks: 15}),new webpack.optimize.MinChunkSizePlugin({minChunkSize: 10000})爲第一個的優化項,限制chunk的數目及chunk的最小大小,防止盲目的抽取公共部分,進而提高性能~
- new webpack.optimize.UglifyJsPlugin()和uglifyjs類似,壓縮對應的js文件,如果使用css loader,則也可以壓縮css文件
- extract-text-webpack-plugin實現css文件的單獨抽離,而不是均包含在最終生成的 js文件中,有三種配置方式 ,new ExtractTextPlugin(“[name].css”)將每個entry下的css抽離成多個文件,
new ExtractTextPlugin(“style.css”, {
allChunks: true
})則將全部css文件合成一個,如若配合CommonsChunkPlugin使用,則可實現和CommonsChunkPlugin同樣的css效果~
- new webpack.optimize.CommonsChunkPlugin,該插件的引入可抽離文件的公共部分,譬如entry有 vendor: [“jquery”, “underscore”, …]的相關依賴時,我們可通過把全部vendor依賴打包在vendor.bundle.js中
resolve: 其中最常用的有alias及 extensions,其中alias作用爲別名定義,可定義webpack打包的文件別名(防止長文件的多次書寫),譬如 alias下定義moment: “moment/min/moment-with-locales.min.js”,後期便可使用require(‘moment’)得到moment-with-locales.min.js文件,同時譬如我們不需要引入node_modules的react的全部,而只需引入下面的部分react.min.js,則也可以通過react別名定義,重寫其查找路徑,從而減少其打包時間,’react’:’react/dist/react.min.js’
extensions則自動擴展文件後綴名,意味着我們require模塊可以省略不寫後綴名總結與反思
以前看網上教程一直以爲是蠻簡單的一件事,但當自己全部重頭做起及優化還是一件比較費腦筋的事情,官網儘管是英文的而且內容繁雜,但是官網往往是最靠譜的(當然官網內容仍不是很完全,從babel-loader的github介紹上我們也可找出關於webpack的不少優化項,可以下週再續)
本來還有react-hot-loader這個利器需要加進來,但限於篇幅,下週再續
- 絕大多數是總結項目經驗及網上教程,官網而來,也許有紕漏或不準確的地方,希望後期會更正
更新
- 剛剛看到一篇很好的webpack文章,裏面有很多補充優化了本文提到的webpack配置,https://segmentfault.com/a/1190000005770042 參考
- https://github.com/babel/babel-loader 參考自babel-loader官網,裏面的 query: {
presets: [‘es2015’],
plugins: [‘transform-runtime’]
}中的plugins可以減少文件的依賴次數,可以起到優化性能的作用,而 loader: ‘babel?cacheDirectory’的cacheDirectory則可以實現loader結果的緩存~,也可以起到優化性能的作用,但僅限於該babel-loader