react 文件 md5_从零配置webpack 4+react脚手架(二)
前言:
你可能也注意到了,html文件中的關于js的引用是我們手動寫的,那假如我們改了輸出路徑或打包編譯之后的文件名,那我們豈不是還要手動去修改html文件中的引用?我們怎么做到,像create-react-app中那樣一旦你修改了某個文件內容,頁面會自己刷新?我們來一步一步實現它們,當然,這一小節不僅僅只是為了完成這兩點。
上一節:從零配置webpack 4+react腳手架(一)
自動編譯html并引入js文件
public的index.html應該自動編譯到dist目錄,并且所有的js引用是自動添加的。你可以使用html-webpack-plugin插件來處理這個優化。
安裝HtmlWebpackPlugin
在控制臺執行以下代碼:
npm install --save-dev html-webpack-plugin在webpack.prod.config.js中配置plugins屬性
const merge = require('webpack-merge'); const common = require('./webpack.common.config.js');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = merge(common, {mode: 'production',plugins: [new HtmlWebpackPlugin({filename: 'index.html',// 這里有小伙伴可能會疑惑為什么不是 '../public/index.html'// 我的理解是無論與要用的template是不是在一個目錄,都是從根路徑開始查找template: 'public/index.html',inject: 'body',minify: {removeComments: true,collapseWhitespace: true,},})] });- filename:打包之后的html文件名字
- template:以我們自己定義的html為模板生成,不然我們還要到打包之后的html文件中寫
- inject:在body最底部引入js文件,如果是head,就是在head中引入js
- minify:壓縮html文件,更多配置點我
- removeComments:去除注釋
- collapseWhitespace:去除空格
更多配置請點擊官方README
刪除index.html中手動引入的script標簽
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>從零配置webpack4+react腳手架</title> </head> <body><div id="root"></div> </body> </html>現在我們再來打包試試,看看dist中是不是多出了html文件,并且自動引入了script,用瀏覽器打開它試試看是不是能正確輸出內容了!
給打包出的js文件換個不確定名字
這個操作是為了防止因為瀏覽器緩存帶來的業務代碼更新,而頁面卻沒變化的問題,你想想看,假如客戶端請求js文件的時候發現名字是一樣的,那么它很有可能不發新的數據包,而直接用之前緩存的文件,當然,這和緩存策略有關。
那我們怎么給導出文件的安排一個不確定的名字呢?很簡單,[hash]或[chunkhash]
修改webpck.prod.config.js:
其中,name就是模塊名稱,我們在entry中進行過配置,在這里重新設置會代替之前common中的設置,chunkhash是文件內容的hash,webpack默認采用md5的方式對文件進行hash。8是hash的長度,如果不設置,webpack會設置默認值為20。
現在你重新打包,去看看生成的js文件的名字~
打包編譯前清理dist目錄
在上面的修改后,因為js文件名字不同,你之后再打包,會把之前打包之后的js文件也留下,我們只想要最新打包編譯的文件,就需要先清除dist目錄,再重新生成。
安裝clean-webpack-plugin
npm install --save-dev clean-webpack-plugin這個插件不被官方文檔所收錄,可以去github查看它的配置文檔
使用clean-webpack-plugin
修改webpck.prod.config.js:
const merge = require('webpack-merge'); const common = require('./webpack.common.config.js');const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = merge(common, {mode: 'production',output: {filename: 'js/[name].[chunkhash:8].bundle.js',},plugins: [new HtmlWebpackPlugin({filename: 'index.html',template: 'public/index.html',inject: 'body',minify: {removeComments: true,collapseWhitespace: true,},}),new CleanWebpackPlugin()] });這里需要注意:之前引入CleanWebpackPlugin的寫法是const CleanWebpackPlugin = require('clean-webpack-plugin');
而且在下面new的時候需要傳入參數,dist文件路徑。但是現在必須這樣引入:const {CleanWebpackPlugin} = require('clean-webpack-plugin');
而且,不用再寫路徑參數
現在再來執行看看,是不是只有一個js文件了!~
代碼分割
我們先看下,我們之前打包編譯的時候,控制臺的信息:
我們看到,這個打包之后的bundle.js文件大小為129kb,隨著業務代碼越來越多,這個包會變得越來越大,你每次修改了代碼并發布,用戶都需要重新下載這個包,但是想想看,我們修改的代碼只是整個代碼的一小部分,還有許多其他不變的代碼,例如 react 和 react-dom ,那我們把這部分不變的代碼單獨打包。
修改 webpack.common.config.js ,增加一個入口:
entry: {index: './src/index.js',framework: ['react','react-dom'],},重新打包,發現react和react-dom 被編譯成framework.js,但是我們的index.bundle.js還是129kb,沒有變過。
這是因為我們還沒有抽離index.js中的公共代碼。
添加代碼至 webpack.prod.config.js :
module.exports = {//...optimization: {splitChunks: {chunks: 'all',minSize: 30000,maxSize: 0,minChunks: 1,cacheGroups: {framework: {test: "framework",name: "framework",enforce: true},vendors: {priority: -10,test: /node_modules/,name: "vendor",enforce: true,},}}},//... };cacheGroups對象,定義了需要被抽離的模塊,其中test屬性是比較關鍵的一個值,他可以是一個字符串,也可以是正則表達式,還可以是函數。如果定義的是字符串,會匹配入口模塊名稱,會從其他模塊中把包含這個模塊的抽離出來。name是抽離后生成的名字,和入口文件模塊名稱相同,這樣抽離出來的新生成的framework模塊會覆蓋被抽離的framework模塊,雖然他們都叫framework。
vendors這個緩存組,它的test設置為 /node_modules/ 表示只篩選從node_modules文件夾下引入的模塊,所以所有第三方模塊才會被拆分出來。
重新打包,我們發現index.bundle.js文件大小只有:1.69kb
我們隨意修改一下app.js中的內容,比如
再打包一次,你會發現index.bundle.js(不被緩存)的hash值變了,但是freamework.bundle.js(能被緩存)的hash值沒變,成了成了!!
壓縮JS文件
我們需要把打包生成的js文件盡可能壓縮,以便減少文件體積,更快地被用戶加載。
我們需要一個插件: uglifyjs-webpack-plugin 來做這份工作
安裝uglifyjs-webpack-plugin
在控制臺執行以下代碼:
npm install uglifyjs-webpack-plugin --save-dev引入uglifyjs-webpack-plugin
增加如下代碼至 webpack.prod.config.js :
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');optimization內配置minimizer參數
minimizer: [new UglifyJsPlugin(),//... ],現在optimization參數應該是現在這樣:
optimization: {minimizer: [new UglifyJsPlugin()],splitChunks: {chunks: 'all',minSize: 30000,maxSize: 0,minChunks: 1,cacheGroups: {framework: {priority: 100,test: "framework",name: "framework",enforce: true},vendors: {priority: -10,test: /node_modules/,name: "vendor",enforce: true,},}}},重新打包編譯看看~我們的index.bundle.js減少了0.1kb,當然,隨著業務代碼越來越多,這部分差距會漸漸變大。
自動編譯打包
我們每次修改代碼,查看結果都要經歷以此 npm run build ,大大降低了開發效率,這難以忍受!
webpack給我們提供了devServer開發環境,支持熱更新,相當舒服。
安裝webpack-dev-server
在控制臺執行以下代碼:
npm install webpack-dev-server --save-dev增加代碼至 webpack.dev.config.js :
是不是都快忘記這個之前創建的配置文件了?沒關系,反正也沒代碼,它是專門用來配置我們開發環境的
const path = require('path'); const merge = require('webpack-merge'); const common = require('./webpack.common.config.js');const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = merge(common, {mode: 'development',output: {filename: 'js/[name].[hash:8].bundle.js',},devServer: {contentBase: path.resolve(__dirname, '../dist'),open: true,port: 9000,compress: true,hot: true},plugins: [new HtmlWebpackPlugin({template: 'public/index.html',inject: 'body',hash: false}),new webpack.HotModuleReplacementPlugin()] });HotModuleReplacementPlugin是webpack熱更新的插件,設置devServer.hot為true,并且在plugins中引入HotModuleReplacementPlugin插件即可。
還需要注意的是我們開啟了hot,那么導出不能使用chunkhash,需要替換為hash。
修改我們的package.json
像之前build的時候,我們是通過配置package.json做到的,現在我們同樣加入以下代碼來模擬:
"scripts": {"test": "echo "Error: no test specified" && exit 1","build": "webpack --config ./config/webpack.prod.config.js", + "start": "webpack-dev-server --inline --config ./config/webpack.dev.config.js"},接下來,在控制臺執行
npm run start是不是自動開了一個端口為9000的網頁,上面是我們寫的頁面內容,這和我們的配置都是一一對應的。
現在你隨意修改app.js中的代碼,再回到頁面看下是不是也跟著變了,那我們就整合webpack-dev-server成功!
下面一小節我們會配置css相關的屬性,加油!
這是我的github/blog,歡迎star,會陸續推出更多學習文章。
總結
以上是生活随笔為你收集整理的react 文件 md5_从零配置webpack 4+react脚手架(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql消除重复行的关键字_MySQL
- 下一篇: 额头黑怎么去除