webpack系列——使用DllPlugin預編譯vux

轉戰掘金第一帖,原連接 zhihu,GitHub地址dllPlugin_vux_multipagejavascript

說明

  1. 廢話太多直接看配置就行
  2. 項目之間區別會很大,特別這個是vue多頁,因此挑有用的看,最重要的是想分享配置思路。

背景

技術框架:Android hybrid + vue H5(多頁)css

問題: 項目參照網上多頁vue的配置自定義入口和打包。但問題就是多頁致使項目開發編譯和打包速度很慢,有一部分緣由來自設備太垃圾。html

體會一下官網的說法vue

vux官網圖

思路:

  1. 首先是百度一些提升webpack打包和編譯速度的方案,最後肯定有配置空間且效果比較好的是babel-loader 的緩存和dll預編譯
  2. babel-loader 對比配置沒啥用,放棄了
  3. dll預編譯主要針對vux這個最大最重的包,然而各類都沒成功,放棄了。
  4. 後來進度沒那麼趕,研究了一下,**首先是參考vue-cli配置命令的思路,參照網友的配置,再從vux官網獲得一些配置的啓發。**三者整合終於成功,一下是配置

配置

版本java

"vue": "2.5.13",
"vue-loader": "^13.3.0",
"vux": "^2.9.2",
"vux-loader": "^1.1.30",
"webpack": "^3.6.0",
複製代碼

安裝插件node

assets-webpack-plugin
clean-webpack-plugin
複製代碼

因爲各類vue-cli版本區別,可能插件有出入,少了就安裝就好webpack

package.json 配置 啓動命令ios

"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "dll": "node build/buildDll.js"
},
複製代碼

buildDll.js 模仿build.jsgit

const ora = require('ora')
const rm = require('rimraf')
const path = require('path');
const chalk = require('chalk')
const webpack = require('webpack');
const dllConfig = require('./webpack.dll.config.js');

const spinner = ora({
  color: 'green',
  text: 'Dll生產中...'
})
spinner.start()

rm(path.resolve(__dirname, '../dll'), err => {
  if (err) throw err
  webpack(dllConfig, function (err, stats) {
    spinner.stop()
    if (err) throw err
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + '\n\n')

    console.log(chalk.cyan(' dll succeed !.\n'))
  })
});
複製代碼

webpack.dll.config.jsgithub

  1. DllPlugin 配置映射
  2. ExtractTextPlugin 好像沒用,CleanWebpackPlugin 常規配置
  3. AssetsPlugin 生成文件名,配合HtmlWebpackPlugin增長打包後dll的緩存
  4. babel-loader 來處理vux包中的js文件(重要)
  5. 利用merge將vuxLoader和vux-ui引入配置(重要)
const path = require('path');
const webpack = require('webpack'); //調用webpack內置DllPlugin插件
const ExtractTextPlugin = require('extract-text-webpack-plugin'); // 提取css
const AssetsPlugin = require('assets-webpack-plugin'); // 生成文件名,配合HtmlWebpackPlugin增長打包後dll的緩存
const CleanWebpackPlugin = require('clean-webpack-plugin'); //清空文件夾
const vueLoaderConfig = require('./vue-loader.conf');
const vuxLoader = require('vux-loader');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; // 統計

const dllConfig = {
  entry: {
    // libs: ['vconsole/dist/vconsole.min.js', 'axios', 'qs']
    libs: ['sockjs-client/dist/sockjs.js', 'better-scroll/dist/bscroll.esm.js', 'vconsole/dist/vconsole.min.js', 'axios', 'qs', 'vux/index.js']
  },
  output: {
    path: path.resolve(__dirname, '../dll'),
    filename: '[name].[chunkhash:7].js',
    library: '[name]_library'
  },
  resolve: {
    extensions: ['.js', '.vue', '.json', '.scss'],
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.resolve(__dirname, '../dll/[name]-mainfest.json'),
      name: '[name]_library',
      context: __dirname // 執行的上下文環境,對以後DllReferencePlugin有用
    }),
    new ExtractTextPlugin('[name].[contenthash:7].css'),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
    }),
    new AssetsPlugin({
      filename: 'bundle-config.json',
      path: './dll'
    }),
    new CleanWebpackPlugin(['dll'], {
      root: path.join(__dirname, '../'), // 絕對路徑
      verbose: true, // 是否顯示到控制檯
      dry: false // 不刪除全部
    }),
    new BundleAnalyzerPlugin(), // 使用統計
  ],
  module: {
    rules: [{
      test: /\.vue$/,
      loader: 'vue-loader',
      options: vueLoaderConfig
    }, {
      test: /\.js$/,
      loader: 'babel-loader',
      include: path.resolve(__dirname, './node_modules/vux'),
      // exclude: path.resolve(__dirname, './node_modules/vux'),
    }, {
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [{
          loader: 'css-loader',
          options: {
            minimize: true //啓用壓縮
          }
        }]
      })
    }, {
      test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
      loader: 'url-loader',
      query: {
        limit: 10000,
        name: 'img/[name].[hash:7].[ext]'
      }
    }, {
      test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
      loader: 'url-loader',
      query: {
        limit: 10000,
        name: 'fonts/[name].[hash:7].[ext]'
      }
    }]
  },
};
module.exports = vuxLoader.merge(dllConfig, {
  plugins: [
    'vux-ui', // v-cart/mixin.js 須要這個插件
    // 'duplicate-style',
  ] // 數組方式插件配置
});
複製代碼

修改webpack.dev.conf.js

配置 CopyWebpackPlugin,DllReferencePlugin

// ...
plugins: [
  // ...
  new CopyWebpackPlugin([
    /* ... */
    /* dll使用 */
    {
      from: path.resolve(__dirname, '../dll'), // dll設置,改成dll
      to: config.dev.assetsSubDirectory,
      ignore: ['.*']
    }
  ]),
  new vConsolePlugin({
    filter: [],  // 須要過濾的入口文件
    enable: true // 發佈代碼前記得改回 false
  }),
  /* mhs dll使用, 連接dll */
  new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: require('../dll/libs-mainfest.json') // 指向生成的manifest.json
  })
]
// ...
複製代碼

在配置HtmlWebpackPlugin 的文件中配置路徑

// ...
try {
  bundleConfig = require('../dll/bundle-config.json');
} catch(err) {
  bundleConfig = '';
}
// ...
return new HtmlWebpackPlugin({ // 返回一個HtmlWebpackPlugin配置
  filename: `${fileName}.html`,
  template: 'template.html',
  title,
  minify,
  inject: true,
  chunks,
  chunksSortMode: 'dependency',
  vhost: dev ? '' : '../../' + config.build.virtualHost, // 資源放置的目錄
  libJsName: dev && bundleConfig ? '/' + bundleConfig.libs.js : '', // 只須要注意這裏,這樣變量能夠在index.html中使用
});
複製代碼

模板html(一般是index.html)添加

<script type="text/javascript" src="<%=htmlWebpackPlugin.options.libJsName %>"></script>
複製代碼

運行

首先打dll包

npm run dll
複製代碼

運行

npm run start
複製代碼

總結

  1. 沒有配置vuxLoader和vux-ui 是照抄網上配置文件失敗的緣由。和以前element-ui不一樣,vux居然有本身的loader和插件,這是獲得官網配置的啓發。
  2. 中間由於不能解析因此配置了babel-loader,這裏根據報錯配的(報什麼解決什麼)
  3. 本人對webpack源碼不瞭解,也就根據文檔和vue-cli 的例子摸索弄到這個水平,有不少表述不專業,讀者領會精神就好

GitHub地址

dllPlugin_vux_multipage

相關文章
相關標籤/搜索