React編譯環境配置:webpack3遷移至webpack4
這次我們以inputPassword元件為例,將編譯配置環境 從webpack3遷移至webpack4,新裝的webpack版本是4.14,但是配置檔案還是用的webpack3的配置。
先來看看pack.json檔案:
{ "name": "react-inputpassword", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack --config ./build/webpack.config.js", "start": "webpack-dev-server --config ./build/webpack.config.js", "dev": "webpack --config ./build/webpack.dev.config.js", "build": "webpack --progress --profile --colors --config ./build/webpack.pro.config.js" }, "repository": { "type": "git", "url": "git+https://github.com/jean0218/react-inputPassword.git" }, "author": "", "license": "ISC", "bugs": { "url": "https://github.com/jean0218/react-inputPassword/issues" }, "homepage": "https://github.com/jean0218/react-inputPassword#readme", "dependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.7.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "css-loader": "^0.28.11", "enzyme-adapter-inferno": "^1.3.0", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.11", "html-webpack-plugin": "^3.2.0", "react": "^16.4.1", "react-dom": "^16.4.1", "react-test-renderer": "^16.4.1", "style-loader": "^0.21.0", "webpack": "^4.14.0", "webpack-dev-server": "^3.1.4", "webpack-merge": "^4.1.3" }, "devDependencies": { "babel-jest": "^23.2.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "jest": "^23.3.0" } }
找到webpack配置檔案,放在build目錄下,原有webpack檔案配置如下:
webpack.base.config.js(webpack基礎配置)
const webpack = require('webpack'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const fileEntry = require('./fileEntry.js'); const webpackBaseConfig = { resolve: { extensions: [".js", ".json", ".jsx"], alias: { images: path.resolve(__dirname, '../examples/static/images'), } }, entry: { examples:path.resolve(__dirname, '../examples/index.js'), demo01:path.resolve(__dirname, '../examples/demo01.js') }, module: { noParse: /node_modules\/(jquey\.js)/, rules: [{ test: /\.(js|jsx)$/, use: [{ loader: 'babel-loader', options: { "presets": [ "es2015", 'stage-0', 'react' ] } }] },{ test: /\.(png|jpg|gif)$/, use: [{ loader: 'file-loader', options: { limit: 25000, name: 'images/[name][hash:6].[ext]', // 我們選擇載入的圖片格式為png,jpg,jpeg,gif,並限定當檔案小於25kb,轉換為base64編碼。 // 優勢:將一些小並且不常更新的圖片轉換base64編碼後,可以減少一次或多次http請求。 // 但這個limit應該定義成一個合適的值,因為如果將稍大些的圖片轉為base64後,會生成大量字元, // 反而降低我們的載入速度。 } }] },{ test: /\.(woff|woff2|eot|ttf|svg|otf)$/, loader: 'file-loader', options: { name: 'fonts/[name].[ext]' } }] }, plugins: [ new webpack.optimize.ModuleConcatenationPlugin(), ], } fileEntry.map(function(item) {//新檔案輸出 webpackBaseConfig.entry[item.fileName] = path.resolve(__dirname, item.sourceFile); const chunksSort = item.chunks const htmlPackage = new HtmlWebpackPlugin({ //favicon: 'path/to/yourfile.ico',//給生成的 html 檔案生成一個 favicon title: item.title, //生成的html文件的標題 template: path.resolve(__dirname, item.template), filename: item.targetFile, //輸出檔案的檔名稱,預設為index.html,可以配置輸出檔案指定目錄位置,例如'html/index.html' //filename配置的html檔案目錄是相對於webpackConfig.output.path路徑而言的,不是相對於當前專案目錄結構的。 //指定生成的html檔案內容中的link和script路徑是相對於生成目錄下的,寫路徑的時候請寫生成目錄下的相對路徑。 //hash: false,//true|false,是否為所有注入的靜態資源新增webpack每次編譯產生的唯一hash值 showErrors: true, //是否將錯誤資訊輸出到html頁面中,便於除錯 //inject: 'body', //所有JavaScript資源插入到body元素的底部 chunks: item.chunks, //允許插入到模板中的一些chunk,不配置此項預設會將entry中所有的thunk注入到模板中。 //在配置多個頁面時,每個頁面注入的thunk應該是不相同的,需要通過該配置為不同頁面注入不同的thunk; //excludeChunks: ,//這個與chunks配置項正好相反,用來配置不允許注入的thunk。 chunksSortMode: (argument, argument2) =>{ //none | auto| function,預設auto; 允許指定的thunk在插入到html文件前進行排序。 //function值可以指定具體排序規則;auto基於thunk的id進行排序; none就是不排序 var aIndex = chunksSort.indexOf(argument.names[0]); var bIndex = chunksSort.indexOf(argument2.names[0]); aIndex = aIndex < 0 ? chunksSort.length + 1 : aIndex; bIndex = bIndex < 0 ? chunksSort.length + 1 : bIndex; return aIndex - bIndex; } }); webpackBaseConfig.plugins.push(htmlPackage); }); module.exports = webpackBaseConfig;
其中的fileEntry.js檔案主要用於生成html檔案,這裡就不再貼出來了。
webpack.config.js(本地執行環境配置)
const webpack = require('webpack'); const path = require('path'); const webpackBaseConfig = require('./wepback.base.config.js'); const merge = require('webpack-merge'); const outputDir = 'dist'; const webpackConfig = merge(webpackBaseConfig, { devtool: 'cheap-module-eval-source-map', output: { path: path.resolve(__dirname, '../' + outputDir + '/'), filename: 'js/[name].js', chunkFilename: 'js/[name].chunks.js', }, module: { rules: [ { test: /\.css$/, use:[ 'style-loader', 'css-loader' ] } ], }, plugins: [ new webpack.HotModuleReplacementPlugin(), ], }); module.exports = webpackConfig;
我們來看看webpack4相對於3新增了哪些內容:
1、不止需要安裝webpack,還需要安裝webpack-cli
在webpack3中,webpack本身和它的cli以前都在同一個包中,但在第4版中,它們兩者已經分開,所以我們的webpack需要安裝兩個包,全域性安裝webpack
npm install webpack -g
再全域性安裝webpack-cli
npm install webpack-cli -g
安裝完成後出現版本提示,就說明該包已經安裝成功。
(這個安裝是在配置react-loadList元件時截圖的,除了專案不同其它都是一樣的)
2、新增了mode引數來表示生產還是開發
按照以上配置,我們執行 npm run start,檔案能正常編譯,但會看到如下警告:
這個警告告訴我們,'mode'選項沒有被設定,必須設定'mode'選項。webpack4新增了mode引數來表示生產還是開發,新增的引數有兩個可選值:development和production。不可預設,預設就會像上圖一樣報警告,其中
production 模式:
-
預設提供所有可能的優化,如程式碼壓縮/作用域提升等
-
不支援 watching
-
process.env.NODE_ENV 的值不需要再定義,預設是 production
development 模式:
-
主要優化了增量構建速度和開發體驗
-
process.env.NODE_ENV 的值不需要再定義,預設是 development
-
開發模式下支援註釋和提示,並且支援 eval 下的 source maps
可以在pack.json中配置
webpak --mode development
也可以配置檔案中配置:
mode:'development',
devtool: 'cheap-module-eval-source-map',
如果原有的檔案中有new webpack.DefinePlugin,加上mode選項後,則需要刪除
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") })
再執行npm run start,這個時候警告已經沒有了。
3、rules中需要增加type型別,指定模組型別
webpack 4之前,js 是 webpack 中的唯一模組型別,因而不能有效地打包其它型別的檔案。而 webpack 4 則提供了 5 種模組型別:
- javascript/auto: (webpack 3中的預設型別)支援所有的JS模組系統:CommonJS、AMD、ESM
- javascript/esm: EcmaScript 模組,在其他的模組系統中不可用(預設 .mjs 檔案)
- 相較於javascript/auto模式更嚴格,匯入的名稱必須存在於匯入的模組中
- 動態的模組(非ESM, 如CommonJs)只能通過import匯入,其它方式的匯入都會報錯
- javascript/dynamic: 僅支援 CommonJS & AMD,EcmaScript 模組不可用
- json: 可通過 require 和 import 匯入的 JSON 格式的資料(預設為 .json 的檔案)
- webassembly/experimental: WebAssembly 模組(處於試驗階段,預設為 .wasm 的檔案)
(我在看到這塊時,產生了一個疑問,這些都是js的模型,圖片、字型類的不需要增加type型別麼?待以後有機會再補充)
5、CommonsChunkPlugin需要替換
本次更新內容中沒有這一項,暫時不編寫,以後更新。
這樣,我們的webpack3成功遷移至4了,相對於2遷移至3是不是簡單了很多。
參考: