可前往個人Github/blog進行閱讀,如有幫助,賞個star😊javascript
你可能也注意到了,html文件中的關於js的引用是咱們手動寫的,那假如咱們改了輸出路徑或打包編譯以後的文件名,那咱們豈不是還要手動去修改html文件中的引用?咱們怎麼作到,像create-react-app中那樣一旦你修改了某個文件內容,頁面會本身刷新?咱們來一步一步實現它們,固然,這一小節不只僅只是爲了完成這兩點。css
public的index.html應該自動編譯到dist目錄,而且全部的js引用是自動添加的。你可使用html-webpack-plugin插件來處理這個優化。html
在控制檯執行如下代碼:java
npm install --save-dev html-webpack-plugin
複製代碼
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,
},
})
]
});
複製代碼
更多配置請點擊官方READMEnode
<!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,用瀏覽器打開它試試看是否是能正確輸出內容了!react
這個操做是爲了防止由於瀏覽器緩存帶來的業務代碼更新,而頁面卻沒變化的問題,你想一想看,假如客戶端請求js文件的時候發現名字是同樣的,那麼它頗有可能不發新的數據包,而直接用以前緩存的文件,固然,這和緩存策略有關。webpack
那咱們怎麼給導出文件的安排一個不肯定的名字呢?很簡單,[hash]或[chunkhash]
修改webpck.prod.config.js
:git
const merge = require('webpack-merge');
const common = require('./webpack.common.config.js');
const HtmlWebpackPlugin = require('html-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,
},
})
]
});
複製代碼
其中,name
就是模塊名稱,咱們在entry中進行過配置,在這裏從新設置會代替以前common中的設置,chunkhash
是文件內容的hash,webpack默認採用md5的方式對文件進行hash。8是hash的長度,若是不設置,webpack會設置默認值爲20。github
如今你從新打包,去看看生成的js文件的名字~web
在上面的修改後,由於js文件名字不一樣,你以後再打包,會把以前打包以後的js文件也留下,咱們只想要最新打包編譯的文件,就須要先清除dist目錄,再從新生成。
npm install --save-dev clean-webpack-plugin
複製代碼
這個插件不被官方文檔所收錄,能夠去github查看它的配置文檔
修改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文件了!~
咱們先看下,咱們以前打包編譯的時候,控制檯的信息:
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中的公共代碼。
webpack3版本是經過配置CommonsChunkPlugin插件來抽離公共的模塊。webpack4版本,官方廢棄了CommonsChunkPlugin,而是改用配置optimization.splitChunks的方式,更加方便。
添加代碼至 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
import React from 'react';
function App() {
return (
<div className="App"> <h1>I am changed</h1> </div>
);
}
export default App;
複製代碼
再打包一次,你會發現index.bundle.js(不被緩存)的hash值變了,可是freamework.bundle.js(能被緩存)的hash值沒變,成了成了!!
咱們須要把打包生成的js文件儘量壓縮,以便減小文件體積,更快地被用戶加載。
咱們須要一個插件: uglifyjs-webpack-plugin
來作這份工做
在控制檯執行如下代碼:
npm install uglifyjs-webpack-plugin --save-dev
複製代碼
增長以下代碼至 webpack.prod.config.js
:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
複製代碼
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開發環境,支持熱更新,至關舒服。
在控制檯執行如下代碼:
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。
像以前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相關的屬性,加油!