這段時間在對公司的打包構建速度和app.js文件大小進行優化。使用到了webpack的DllPlugin和DllReferencePlugin。今天就來簡單講講它們的使用。javascript
其實對於這兩個插件網上已經有不少各類各樣的文章了。不過筆者認爲,那些文章都寫得很棒,可是對於部分須要注意的地方都沒有說明。這裏筆者就根據本身的理解講講我的的理解。若是有什麼不對的地方但願能有人指出,小弟在此先謝過了。html
首先咱們來說講DLLPlugin這個插件吧。這個插件的做用是建立dll文件和manifest文件。dll文件就是就是咱們須要引入的文件,manifest文件是引導webpack引入到當前項目的文件。好吧,直接貼代碼:vue
webpack.dll.conf.jsjava
var path = require('path') var webpack = require('webpack') var CleanWebpackPlugin = require('clean-webpack-plugin') var config = require('../config') var __root = xxx // 這裏是你的根路徑 // 這裏是靜態資源路徑,若是使用vue-cli的,就是根目錄下的static目錄; // 若是使用@vue/cli的就是根目錄下的public目錄。使用其餘的腳手架須要根據具體狀況考慮。 var static = xxx module.exports = { context: __root, // 這裏配置的context就是後面dll的context entry: { 'core': ['vue', 'vue-router', 'vuex'], 'asset': ['axios', 'fastclick'] }, output: { path: path.resolve(static, 'lib'), filename: '[name]-[chunkhash:7].dll.js', library: 'lib_[name]', // *** 這裏不要添加libraryTarget,不然webpack打包時會出錯。 // (提示是__WEBPACK__EXTERNAL__MODULE__xxx未定義) *** // libraryTarget: 'umd' }, resolve: { modules: [path.resolve(__root, 'node_modules')], extensions: ['.js', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js' } }, // 這裏沒有寫loaders,若是有須要能夠自行添加loaders plugins: [ // *** 這裏很關鍵 *** new webpack.DllPlugin({ // 由於上面寫了context,因此這裏能夠不指定context // 這裏manifest的名字必需要有變量,由於相似上面的core和asset會分別建立一個manifest, // 若是名稱相同,manifest會生成不規範的json,在引用時會報錯。 path: path.resolve(__root, 'static/manifest/[name].manifest.json'), name: 'lib_[name]' // *** 這裏的名字必須與output.library一致 *** }), // 這個是用來穩定hash值,防止出現webpack的hash出現莫名的變化 new webpack.HashedModuleIdsPlugin(), new webpack.NamedChunksPlugin() ... 其餘插件 ] }
上面就是webpack.dll.conf.js的主要配置。執行以後會在static文件夾(在vue-cli生成的項目中用於存放不須要webpack構建的靜態文件【@vue/cli中的目錄名爲Public】)下生成兩個文件夾(lib文件夾和mainfest文件夾)。其中lib下的文件爲咱們已經打包好的組件庫,mainfest下的文件在引入項目時有用(是一個JSON文件)。node
webpack.conf.jswebpack
var path = require('path') // 獲取dll文件的manifest function getDllManifest () { var plugins = [] Object.keys({ 'core': ['vue', 'vue-router', 'vuex'], 'asset': ['axios', 'fastclick'] }).forEach((name) => { plugins.push( new webpack.DllReferencePlugin({ context: __root, // 這裏的context必須與DllPlugin中的context保持一致 manifest: path.resolve(__root, 'static/manifest/[name].manifest.json').replace(/\[name\]/gi, name) }) ) }) return plugins } module.exports = { entry: { app: './src/main.js' }, output: { path: path.resolve(__dirname, '..') filename: 'js/[name]js' }, ... 其餘代碼 plugins: [ // *** 因此這裏可能會引入多個DllReferencePlugin,具體要看有幾個manifest文件了。*** ...getDllManifest(), new HtmlWebpackPlugin({ filename: utils.assetsPath('page/retail.html'), template: path.join(config.dev.page, 'retail.html'), inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // dll文件須要插件將其引入到html文件中,以方便後續使用 new HTMLWebpackIncludeAssetsPlugin({ append: false, publicPath: config.build.assetsPublicPath, assets: [{ path: config.build.assetsSubDirectory, glob: '**/*.js', globPath: config.dll.static }], }), // 將dll文件拷貝到你的dist目錄下 new CopyWebpackPlugin([ { // 這裏是dll文件當前所在的文件目錄 from: static, // 這裏是生產環境的資源地址 to: config.build.assetsSubDirectory, // 過濾static中的部分文件 ignore: ['.*', 'manifest/*'] } ]) ] }
getDllManifest方法是將打包好的庫引入到項目中(就是在html中生成script標籤的方式引入,它會在app.js以前生成,保證代碼執行順序的正確性),並保證構建工具不會再次對它進行打包。以上就是生成和引用dll文件的配置。ios
注:git
output.library
必須與DllPlugin
配置中的name
字段保持統一。libraryTarget
,不然在運行時會報__WEBPACK__EXTERNAL__MODULE__xxx is not defined
錯誤。DllPlugin
的context
和DllReferencePlugin
的context
要保持一致。manifest
的名字最好是可配置的,這樣方便生成多個dll文件。講webpack構建優化的github