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/article/details/86150763
-  浏览器缓存机制介绍与缓存策略剖析 https://blog.csdn.net/woleigequshawanyier/article/details/86152516
-  webpack 性能调优与 Gzip 原理 https://blog.csdn.net/woleigequshawanyier/article/details/85273790
-  本地存储——从 Cookie 到 Web Storage、IndexDB  https://blog.csdn.net/woleigequshawanyier/article/details/86290178
- CDN 的缓存与回源机制解析 https://blog.csdn.net/woleigequshawanyier/article/details/86369933
- 服务端渲染的探索与实践 https://blog.csdn.net/woleigequshawanyier/article/details/86370471
- 解锁浏览器背后的运行机制 https://blog.csdn.net/woleigequshawanyier/article/details/86371159
- DOM 优化原理与基本实践 https://blog.csdn.net/woleigequshawanyier/article/details/86371425
- Event Loop 与异步更新策略 https://blog.csdn.net/woleigequshawanyier/article/details/86371850
- 回流(Reflow)与重绘(Repaint)https://blog.csdn.net/woleigequshawanyier/article/details/86372288
- Lazy-Load https://blog.csdn.net/woleigequshawanyier/article/details/84930082
- 事件的节流(throttle)与防抖(debounce)  https://blog.csdn.net/woleigequshawanyier/article/details/85345095
- 前端学习资料下载 https://blog.csdn.net/woleigequshawanyier/article/details/85274358
- 技术体系分类 https://blog.csdn.net/woleigequshawanyier


前端技术架构体系(没有链接的后续跟进):


- 调用堆栈 https://blog.csdn.net/woleigequshawanyier/article/details/85038675
- 作用域闭包 https://blog.csdn.net/woleigequshawanyier/article/details/85214354
- this全面解析 
- 深浅拷贝的原理 https://blog.csdn.net/woleigequshawanyier/article/details/85331237
- 原型prototype https://blog.csdn.net/woleigequshawanyier/article/details/85338995
- 事件机制、
- Event Loop https://www.jianshu.com/p/12b9f73c5a4f
- Promise机制、
- async / await原理、
- 防抖/节流原理  https://blog.csdn.net/woleigequshawanyier/article/details/85345095
- 模块化详解、
- es6重难点、
- 浏览器熏染原理、
- webpack配置(原理) https://blog.csdn.net/woleigequshawanyier/article/details/85273790
- 前端监控、
- 跨域和安全、
- 性能优化(参见上面性能优化相关)
- VirtualDom原理、
- Diff算法、
- 数据的双向绑定
- TCP协议(三次握手、四次挥手) https://blog.csdn.net/woleigequshawanyier/article/details/85223642
- DNS域名解析 https://blog.csdn.net/woleigequshawanyier/article/details/85222985

其它相关


- 前端学习资料下载 https://blog.csdn.net/woleigequshawanyier/article/details/85274358
- 技术体系分类 https://blog.csdn.net/woleigequshawanyier
- react-native 实战项目学习 https://github.com/15826954460/BXStage
- react-naitve 采坑笔记  https://blog.csdn.net/woleigequshawanyier/article/category/8512330

欢迎各位看官的批评和指正,共同学习和成长
希望该文章对您有帮助,你的 支持和鼓励会是我持续的动力

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值