之前我們打包讼昆,實際上都是對
單頁面應(yīng)用
進行的打包
什么叫做單頁面應(yīng)用
呢会喝?
- 整個應(yīng)用里邊只有一個
html文件
澡罚,就是單頁面應(yīng)用列荔;比如我們之前的例子敬尺,當我們運行npm run build
的時候,dist目錄里肌毅,只有一個idnex.html
- 現(xiàn)在主流框架筷转,
vue
,react
都是單頁面應(yīng)用,所以webpack做打包的時候悬而,絕大多數(shù)場景都是對單頁面應(yīng)用進行打包呜舒;但是在一些特殊的場景下,比如兼容一些jquery
的老的項目笨奠,或者zepto
這樣的老的項目袭蝗,包括一些特別奇怪的場景之中,我們確實會遇到要對多頁面應(yīng)用進行打包的場景
那么該怎么實現(xiàn)對多頁面應(yīng)用的打包呢般婆?
之前到腥,我們通過html-webpack-plugin
這個插件,打包之后會在dist
目錄下生成一個index.html
文件蔚袍,并且文件里會引入打包生成的main.js
文件
-
現(xiàn)在假如我們有另外一個頁面
list.js
乡范,我們希望打包之后,webpack會生成一個list.html文件,而且在list.html文件里只引入打包生成的list.js
文件啤咽。而原來的index.html文件晋辆,只引入main.js
文件
-
我們先配置入口文件
-
我們可以這樣配置
html-webpack-plugin
,意思是打包的時候宇整,以src
目錄下的index.html
為模板瓶佳,分別生成一個index.html文件和list.html文件,filename
是html-webpack-plugin
這個插件的屬性鳞青,更多屬性可以到github去查
-
配置好以后霸饲,我們再重新打包为朋,可以看到,生成的dist文件夾下厚脉,有index.html和list.html文件了
-
但是無論是index.html 還是list.html 习寸,里邊都同時引入了
main.js
和list.js
;這不是我們想要的,我們的目標是 index.html文件里引入main.js
器仗,而list.html里引入list.js文件
-
針對這種問題融涣,我們該怎么解決呢,我們還可以給
html-webpack-plugin
再配置一個參數(shù)chunks
,這個配置的意思是精钮,這個html文件要引入的打包生成的js文件有哪些;其中runtime.js
和venfors.js
是兩個html文件都需要的
-
配置好后剃斧,我們再進行打包轨香,可以看到dist.html出了公用的js文件,只引入了
list.js
;而 index,html里只引了main.js
-
而這兩個文件也是可以正常運行的
經(jīng)過上邊的配置幼东,我們就實現(xiàn)了多頁面應(yīng)用的打包臂容。它的實現(xiàn)方式,實際上就是調(diào)整入口文件配置
根蟹。和配置多個html-webpack-plugin
而已
雖然我們上邊實現(xiàn)了多頁面應(yīng)用的配置脓杉,但是我們是手動的,只有兩個頁面简逮,如果有很多頁面球散,我們是不是要手動去增加多個入口文件,并且增加多個html-webpack-plugin
散庶? 很明顯這種方式是效率低下的蕉堰,有沒有方式能智能的幫我們實現(xiàn)這個目標呢?
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
const webpack = require('webpack');
// 寫一個函數(shù)悲龟,用來生成 plugins,這個函數(shù)接收 confis參數(shù)
const makePlugins = (configs) => {
// 創(chuàng)建一個plugins 數(shù)組屋讶,初始只有CleanWebpackPlugin 這個插件
const plugins = [
new CleanWebpackPlugin(['dist'], {
root: path.resolve(__dirname, '../')
})
]
// 獲取到 configs的entry配置,入口配置有幾個key须教,打包的時候皿渗,就生成幾個 html文件, 文件名是key值
Object.keys(configs.entry).forEach(item => {
plugins.push(
new HtmlWebpackPlugin({
template: 'src/index.html',
filename: `${item}.html`,
chunks:['runtime','vendors',item]
})
)
})
// 讀取到dll文件夾下的文件轻腺,然后遍歷乐疆,并根據(jù)后綴名,使用使用不同的插件
const files = fs.readdirSync(path.resolve(__dirname, '../dll'));
files.forEach((file) => {
if (/.*\.dll.js/.test(file)) {
plugins.push(
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, '../dll', file)
})
)
}
if (/.*\.manifest.json/.test(file)) {
plugins.push(
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, '../dll', file)
})
)
}
})
return plugins
}
// 把配置復(fù)制給一個變量 configs
const configs = {
entry: {
index: './src/index.js',
list: './src/list.js'
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [{
test: /\.jsx?$/,
include: path.resolve(__dirname, '../src'),
use: [{
loader: 'babel-loader'
}]
}, {
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/',
limit: 10240
}
}
}, {
test: /\.(eot|ttf|svg)$/,
use: {
loader: 'file-loader'
}
}]
},
optimization: {
runtimeChunk: {
name: 'runtime'
},
usedExports: true,
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'vendors',
}
}
}
},
performance: false,
output: {
path: path.resolve(__dirname, '../dist')
}
}
// 通過makePlugins 函數(shù)給 configs的plugins屬性賦值
configs.plugins = makePlugins(configs);
// 導(dǎo)出configs
module.exports = configs
通過上邊的配置约计。如果我們再增加頁面诀拭,值需要在src下新增一個js文件,然后再去入口文件新增一個配置就醒了煤蚌。
-
比如我們新增了 detail頁面
-
修改entry配置
-
再次打包耕挨,生成了detail.html,而且可以正常運行