webpack实战项目中代码打包和优化总结

网上关于webpack的优化的已经很多了,只是都比较零散,结合实战项目自己做个总结

webpack 优化,实际项目中主要做到了一下几点:

1、 文件压缩(css, js, html, 字体文件, 图片文件)
2、 babel-loader 避免不必要的转义
3、 babel-转义结果进行缓存
4、 公共模块的提取
5、 loader 转为多进程
6、 按需加载
7、 DllPlugin 增加开发时打包速度
8、 Gzip进行文件压缩,webpack压缩文件,后台可以再次进行压缩

接下来针对每一个细节点进行详细说明

1、文件压缩(html, css, js, 字体文件,图片文件的压缩和转码)

HtmlWebpackPlugin 官网链接 https://webpack.docschina.org/plugins/html-webpack-plugin/#src/components/Sidebar/Sidebar.jsx

关于 HtmlWebpackPlugin 的插件使用就不过多赘述,参考官方文档,主要是用来压缩代码以及自动将打包后生成的就是文件插入到html中

如图中所示的<script></script>标签对js的引入都是该插件的功劳,具体用法和配置如下

plugins: [
 new HtmlWebpackPlugin({
  filename: config.build.index, // 指定项目的生成名称
  template: 'index.html', // 将模板指向根那个目录
  inject: true, // 指定生成的<script></script>放在那个目录
  // 去掉空格、注释、多余的应用等等都在这里配置
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
  },
  chunksSortMode: 'dependency', // 成产环境下的第三方依赖进行压缩
 }),
]

js 压缩用法同上,就不细讲了参见官方文档
https://webpack.docschina.org/guides/migrating/#uglifyjsplugin-sourcemap
css、图片、字体文件压缩主要通过 loader 来进行

配置如下:

 const webpackConfig = {
    module: {
      rules: [
        {
          loader: 'css-loader',
          options: {
            sourceMap: options.sourceMap
          }
        }
        {
          test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000, // 限制压缩文件的大小
            name: utils.assetsPath('media/[name].[hash:7].[ext]') // 文件的路径
          }
        },
        {
          test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
          }
        }
      ]
    }
  }


2、3 关于babel 的转码和转码缓存

const webpackConfig = {
 module: {
  rules: [
   {
      test: /\.js$/,
      loader: 'babel-loader?cacheDirectory=true', // 将转译结果缓存至文件系统
      include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]  // 针对特定的文件进行转码 通过include来配置,效率比 exclude 要高 
   },
  ]
 }
}

4、公共模块的提取配置文件如下

plugins配置如下

const webpackConfig = {
 plugins: [
 new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks (module) {
    return (
      module.resource &&
      /\.js$/.test(module.resource) &&
      module.resource.indexOf(
        path.join(__dirname, '../node_modules')
      ) === 0
    )
  }
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest',
  minChunks: Infinity
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: 'app',
  async: 'vendor-async',
  children: true,
  minChunks: 3
 }),
]
}

主要是目的是将第三方依赖抽取到公共模块放到vendor.js,然后针对动态引入的静态文件做进一步的抽离放到 manifest.js 中

5、多进程转码

具体用法和配置如下:

const HappyPack = require('happypack') // 引入第三方依赖
const happyThreadPool = HappyPack.ThreadPool({size: 5}) // 设定五个线程池这里默认设置5个进程
module.exports = {
 plugins: [
    new HappyPack({
      id: 'happyBabel', // 定义唯一id
      threadPool: happyThreadPool, // 指定进程池
      loaders: ['babel-loader?cacheDirectory=true']
    }),
  ],
 module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'happypack/loader?id=happyBabel', // 通过唯一id进行查找
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },
    ]
 }
}



6、按需加载配置如下,实际生产中减少渲染压力

{
     path: '/test',
     name: 'test',
     component: resolve => require(['@/test'], resolve)
}

7、DllPlugin 插件的使用(这里提供简单的配置,具体根据实际需要)
首先在你的build文件加下新建 webpack.dall.config.js 文件,内容如下

const path = require('path')
const webpack = require('webpack')

module.exports = {
  entry: {
    vendor: [
      'aws-sdk',
      'axios',
      'moment',
      'vue',
      'vue-awesome-swiper',
      'vue-router',
      'vuex',
    ]
  },
  output: {
    path: path.resolve(__dirname, '../static'), // 这里通过绝对路径指定生成文件
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.resolve(__dirname, '../static', '[name]-manifest.json'),
      name: '[name]_library'
    }),
  ]
} 

控制台输入 webpack --config build/webpack.dall.config.js
或者 在package.json文件中进行如下配置 运行 npm/cnpm/yarn build build:dall

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "test": "cross-env NODE_ENV=test env_config=test node build/build.js",
    "lint": "eslint --ext .js,.vue src",
    "build": "cross-env NODE_ENV=production env_config=prod node build/build.js",
    "build:dall": "webpack --config build/webpack.dall.config.js"
  },

将会看到static目录项生成 vendor.dall.js 和 vende-manifest.json文件,生成文件如下

接下来在生 build 下的 webpack.prod.conf.js 进行引用

到这个时候我们进行一口深呼吸,以为打工打工告成,结果发现每次打包,然并卵,各位可怜的程序员,别急,万里长征还剩最后一步,生成的js文件你不引用还能怪谁啊亲

看清楚了怎么引用

找到你的index.html文件手动引入 vendor.dll.js如下

第一次运行速度依然没啥改变,当你再次运行的时候你会有飞一般的感觉
 

8、Gzip 文件压缩 根据实际情况,具体配置如下

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}



以上是个人在实际生产项目中的webpack打包以及代码压缩的优化,从一开始的发版打包项目 接近一份到到 20几秒将近一半时间的缩短,从一开始发版后端人员的抱怨:好没好,你们打包这么这么慢 到 我靠!!!这么快就好了。这是一种自我价值的体现和别人对你的肯定。

更多的干货请点击这里 https://blog.csdn.net/woleigequshawanyier

欢迎各位看官的批评和指正,共同学习和成长

希望该文章对您有帮助,也希望得到您的鼓励和支持

猜你喜欢

转载自blog.csdn.net/woleigequshawanyier/article/details/84893918