第一種方法
這種方法比較簡單。就是用 webpack.ProvidePlugin
這個插件
plugins: [
new webpack.ProvidePlugin({
$:'fitflex',
watchInDepth:'watch-in-depth'
}),
}),
],
'fitflex'
和'watch-in-depth
是我寫的兩個npm 包, 在node_modules
裏面, 這樣我們可以將其轉化爲兩個全局變量 $
和 watchInDepth
這兩個全局變量可以直接在入口文件index.js
裏面使用,不需要import
,也不需要require
第二種方法
就是用webpack.DllPlugin
和 webpack.DllReferencePlugin
。
爲什麼我們要用一種比較麻煩的方法呢? 如果你用的框架比較大,代碼量比較多,那麼你不想在打包編譯的時候一直帶上它們,而只想打包一次。這裏借用了微軟的DLL
概念,就是所謂的動態鏈接庫(dynamic link library)。
第一步:需要給第三方框架打包
webpack.dll.config.js
npm run build --config webpack.dll.config.js
const webpack = require('webpack');
const path = require('path');
module.exports ={
resolve:{
extensions: [".js", ".jsx"]
},
entry: {
myDll:['fitflex', 'watch-in-depth']
},
output: {
filename:'[name].dll.js',
path: path.join(__dirname, "dist", "dll"),
library:'[name]_dll_[hash]',
},
plugins:[
new webpack.DllPlugin({
name:'[name]_dll_[hash]',
path:path.join(__dirname, 'dist','dll','[name].manifest.json')
})
]
}
這裏我們看到,我們把這個myDll.dll.js
文件,以及它的myDll.manifest.json
放在了 dist
目錄下的子目錄 dll
到時候我們把打包後的文件放到dist
目錄下,就可以用dll
了
接下來是 webpack.common.js
這裏我就不放 webpack.prod.js
和wepback.dev.js
了,懂的人自然懂,因爲和它們無關。
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: {
app: [
// 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000', // only for webpack-hot-middleware
path.resolve(__dirname, './src/index.js'),
],
},
output: {
filename: '[name].[hash].js',
path: path.resolve(__dirname, 'dist'),
// publicPath: '/'// used for Node.js middleware
},
plugins: [
new ManifestPlugin(),
new CleanWebpackPlugin({
verbose:true,
cleanOnceBeforeBuildPatterns: [ '!myDll']
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.NamedModulesPlugin(),
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
title: 'production',
minify: {
collapseWhitespace: true,
minifyCSS: true,
},
filename: 'index.html',
template: 'index.html',
hash: true,
}),
// new webpack.ProvidePlugin({
// $:'fitflex',
// watchInDepth:'watch-in-depth'
// }),
new webpack.DllReferencePlugin({
context:__dirname,
manifest: path.join('dist', 'dll', `myDll.manifest.json`),
}),
],
optimization: {
moduleIds: 'hashed',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
module: {
rules: [
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
],
},
// {
// test: require.resolve('./src/index.js'),
// use: 'imports-loader?this=>window'
// },
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
}
};
這裏我們需要關注四點。
第一個就是非常魔性的插件 clean-webpack-plugin
,老版挺直觀,新版在require
的時候很魔性,特別是option
裏面的屬性名,我無力吐槽,本來用要刪什麼文件,不刪什麼文件,用exclude
, 或者include
搞定的玩意兒,非要搞個很長的名字,欺負我們不是以英語爲母語的國家嗎?
這裏我們把有myDll
名字的文件排除出清除名單。因爲我們的目的就是希望dll
文件編譯打包一次就不再重複編譯了。
第二
就是主角:webpack.DllReferencePlugin
這個插件的目的是讓編譯的文件可以識別myDll.manifesion.json
從而把index.js
裏面的模塊正確的加載進來。
第三
我們需要在index.html
裏面加上
<script src="./dll/myDll.dll.js"></script>
保證正確引入dll
文件。
第四
index.js
裏面怎麼引入模塊呢?
const $ = require('fitflex');
const watchInDepth = require('watch-in-depth');
還是用require
的老方法。
接下來展示下目錄
最後再吐槽一下官方的在github上的例子,好好的一個項目非要拆開寫分成 vendor
和user
,讓後讓我在如何把這兩者聯繫起來,這個問題上陷入了一天的沉思。
好了,最後再做個廣告,儘管恰不到飯,還是歡迎大家star我寫的這兩個包。
可以直接 npm install
哦。