阅读 53

webpack系列——使用DllPlugin预编译vux

转战掘金第一帖,原链接 zhihu,GitHub地址dllPlugin_vux_multipage

说明

  1. 废话太多直接看配置就行
  2. 项目之间区别会很大,特别这个是vue多页,所以挑有用的看,最重要的是想分享配置思路。

背景

技术框架:Android hybrid + vue H5(多页)

问题: 项目参照网上多页vue的配置自定义入口和打包。但问题就是多页导致项目开发编译和打包速度很慢,有一部分原因来自设备太垃圾。

体会一下官网的说法

vux官网图

思路:

  1. 首先是百度一些提高webpack打包和编译速度的方案,最后确定有配置空间且效果比较好的是babel-loader 的缓存和dll预编译
  2. babel-loader 对比配置没啥用,放弃了
  3. dll预编译主要针对vux这个最大最重的包,然而各种都没成功,放弃了。
  4. 后来进度没那么赶,研究了一下,**首先是参考vue-cli配置命令的思路,参照网友的配置,再从vux官网得到一些配置的启发。**三者整合终于成功,一下是配置

配置

版本

"vue": "2.5.13",
"vue-loader": "^13.3.0",
"vux": "^2.9.2",
"vux-loader": "^1.1.30",
"webpack": "^3.6.0",
复制代码

安装插件

assets-webpack-plugin
clean-webpack-plugin
复制代码

由于各种vue-cli版本区别,可能插件有出入,少了就安装就好

package.json 配置 启动命令

"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "dll": "node build/buildDll.js"
},
复制代码

buildDll.js 模仿build.js

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.js

  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

关注下面的标签,发现更多相似文章
评论