react 引用本地js_从零配置webpack 4+react脚手架(二)
前言:
你可能也注意到了,html文件中的關(guān)于js的引用是我們手動(dòng)寫的,那假如我們改了輸出路徑或打包編譯之后的文件名,那我們豈不是還要手動(dòng)去修改html文件中的引用?我們怎么做到,像create-react-app中那樣一旦你修改了某個(gè)文件內(nèi)容,頁面會(huì)自己刷新?我們來一步一步實(shí)現(xiàn)它們,當(dāng)然,這一小節(jié)不僅僅只是為了完成這兩點(diǎn)。
上一節(jié):從零配置webpack 4+react腳手架(一)
自動(dòng)編譯html并引入js文件
public的index.html應(yīng)該自動(dòng)編譯到dist目錄,并且所有的js引用是自動(dòng)添加的。你可以使用html-webpack-plugin插件來處理這個(gè)優(yōu)化。
安裝HtmlWebpackPlugin
在控制臺執(zhí)行以下代碼:
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',// 這里有小伙伴可能會(huì)疑惑為什么不是 '../public/index.html'// 我的理解是無論與要用的template是不是在一個(gè)目錄,都是從根路徑開始查找template: 'public/index.html',inject: 'body',minify: {removeComments: true,collapseWhitespace: true,},})] });- filename:打包之后的html文件名字
- template:以我們自己定義的html為模板生成,不然我們還要到打包之后的html文件中寫
- inject:在body最底部引入js文件,如果是head,就是在head中引入js
- minify:壓縮html文件,更多配置點(diǎn)我
- removeComments:去除注釋
- collapseWhitespace:去除空格
更多配置請點(diǎn)擊官方README
刪除index.html中手動(dòng)引入的script標(biāo)簽
<!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>現(xiàn)在我們再來打包試試,看看dist中是不是多出了html文件,并且自動(dòng)引入了script,用瀏覽器打開它試試看是不是能正確輸出內(nèi)容了!
給打包出的js文件換個(gè)不確定名字
這個(gè)操作是為了防止因?yàn)闉g覽器緩存帶來的業(yè)務(wù)代碼更新,而頁面卻沒變化的問題,你想想看,假如客戶端請求js文件的時(shí)候發(fā)現(xiàn)名字是一樣的,那么它很有可能不發(fā)新的數(shù)據(jù)包,而直接用之前緩存的文件,當(dāng)然,這和緩存策略有關(guān)。
那我們怎么給導(dǎo)出文件的安排一個(gè)不確定的名字呢?很簡單,[hash]或[chunkhash]
修改webpck.prod.config.js:
其中,name就是模塊名稱,我們在entry中進(jìn)行過配置,在這里重新設(shè)置會(huì)代替之前common中的設(shè)置,chunkhash是文件內(nèi)容的hash,webpack默認(rèn)采用md5的方式對文件進(jìn)行hash。8是hash的長度,如果不設(shè)置,webpack會(huì)設(shè)置默認(rèn)值為20。
現(xiàn)在你重新打包,去看看生成的js文件的名字~
打包編譯前清理dist目錄
在上面的修改后,因?yàn)閖s文件名字不同,你之后再打包,會(huì)把之前打包之后的js文件也留下,我們只想要最新打包編譯的文件,就需要先清除dist目錄,再重新生成。
安裝clean-webpack-plugin
npm install --save-dev clean-webpack-plugin這個(gè)插件不被官方文檔所收錄,可以去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的時(shí)候需要傳入?yún)?shù),dist文件路徑。但是現(xiàn)在必須這樣引入:const {CleanWebpackPlugin} = require('clean-webpack-plugin');
而且,不用再寫路徑參數(shù)
現(xiàn)在再來執(zhí)行看看,是不是只有一個(gè)js文件了!~
代碼分割
我們先看下,我們之前打包編譯的時(shí)候,控制臺的信息:
我們看到,這個(gè)打包之后的bundle.js文件大小為129kb,隨著業(yè)務(wù)代碼越來越多,這個(gè)包會(huì)變得越來越大,你每次修改了代碼并發(fā)布,用戶都需要重新下載這個(gè)包,但是想想看,我們修改的代碼只是整個(gè)代碼的一小部分,還有許多其他不變的代碼,例如 react 和 react-dom ,那我們把這部分不變的代碼單獨(dú)打包。
修改 webpack.common.config.js ,增加一個(gè)入口:
entry: {index: './src/index.js',framework: ['react','react-dom'],},重新打包,發(fā)現(xiàn)react和react-dom 被編譯成framework.js,但是我們的index.bundle.js還是129kb,沒有變過。
這是因?yàn)槲覀冞€沒有抽離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屬性是比較關(guān)鍵的一個(gè)值,他可以是一個(gè)字符串,也可以是正則表達(dá)式,還可以是函數(shù)。如果定義的是字符串,會(huì)匹配入口模塊名稱,會(huì)從其他模塊中把包含這個(gè)模塊的抽離出來。name是抽離后生成的名字,和入口文件模塊名稱相同,這樣抽離出來的新生成的framework模塊會(huì)覆蓋被抽離的framework模塊,雖然他們都叫framework。
vendors這個(gè)緩存組,它的test設(shè)置為 /node_modules/ 表示只篩選從node_modules文件夾下引入的模塊,所以所有第三方模塊才會(huì)被拆分出來。
重新打包,我們發(fā)現(xiàn)index.bundle.js文件大小只有:1.69kb
我們隨意修改一下app.js中的內(nèi)容,比如
再打包一次,你會(huì)發(fā)現(xiàn)index.bundle.js(不被緩存)的hash值變了,但是freamework.bundle.js(能被緩存)的hash值沒變,成了成了!!
壓縮JS文件
我們需要把打包生成的js文件盡可能壓縮,以便減少文件體積,更快地被用戶加載。
我們需要一個(gè)插件: uglifyjs-webpack-plugin 來做這份工作
安裝uglifyjs-webpack-plugin
在控制臺執(zhí)行以下代碼:
npm install uglifyjs-webpack-plugin --save-dev引入uglifyjs-webpack-plugin
增加如下代碼至 webpack.prod.config.js :
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');optimization內(nèi)配置minimizer參數(shù)
minimizer: [new UglifyJsPlugin(),//... ],現(xiàn)在optimization參數(shù)應(yīng)該是現(xiàn)在這樣:
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,當(dāng)然,隨著業(yè)務(wù)代碼越來越多,這部分差距會(huì)漸漸變大。
自動(dòng)編譯打包
我們每次修改代碼,查看結(jié)果都要經(jīng)歷以此 npm run build ,大大降低了開發(fā)效率,這難以忍受!
webpack給我們提供了devServer開發(fā)環(huán)境,支持熱更新,相當(dāng)舒服。
安裝webpack-dev-server
在控制臺執(zhí)行以下代碼:
npm install webpack-dev-server --save-dev增加代碼至 webpack.dev.config.js :
是不是都快忘記這個(gè)之前創(chuàng)建的配置文件了?沒關(guān)系,反正也沒代碼,它是專門用來配置我們開發(fā)環(huán)境的
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熱更新的插件,設(shè)置devServer.hot為true,并且在plugins中引入HotModuleReplacementPlugin插件即可。
還需要注意的是我們開啟了hot,那么導(dǎo)出不能使用chunkhash,需要替換為hash。
修改我們的package.json
像之前build的時(shí)候,我們是通過配置package.json做到的,現(xiàn)在我們同樣加入以下代碼來模擬:
"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"},接下來,在控制臺執(zhí)行
npm run start是不是自動(dòng)開了一個(gè)端口為9000的網(wǎng)頁,上面是我們寫的頁面內(nèi)容,這和我們的配置都是一一對應(yīng)的。
現(xiàn)在你隨意修改app.js中的代碼,再回到頁面看下是不是也跟著變了,那我們就整合webpack-dev-server成功!
下面一小節(jié)我們會(huì)配置css相關(guān)的屬性,加油!
這是我的github/blog,歡迎star,會(huì)陸續(xù)推出更多學(xué)習(xí)文章。
總結(jié)
以上是生活随笔為你收集整理的react 引用本地js_从零配置webpack 4+react脚手架(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一加3t刷机后还卡_OPPO A5?A7
- 下一篇: layui 如何去dom_layui 的