webpack实战项目中代码打包和优化总结
网上关于webpack的优化的已经很多了,只是都比较零散,结合实战项目自己做个总结
webpack 优化,实际项目中主要做到了一下几点:
[code]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的引入都是该插件的功劳,具体用法和配置如下
[code]plugins: [ new HtmlWebpackPlugin({ filename: config.build.index, // 指定项目的生成名称 template: 'index.html', // 将模板指向根那个目录 inject: true, // 指定生成的<script></script>放在那个目录 // 去掉空格、注释、多余的应用等等都在这里配置 minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, chunksSortMode: 'dependency', // 成产环境下的第三方依赖进行压缩 }), ][/code]
js 压缩用法同上,就不细讲了参见官方文档
https://webpack.docschina.org/guides/migrating/#uglifyjsplugin-sourcemap
css、图片、字体文件压缩主要通过 loader 来进行
配置如下:
[code] 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 的转码和转码缓存
[code]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配置如下
[code]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、多进程转码
具体用法和配置如下:
[code]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、按需加载配置如下,实际生产中减少渲染压力
[code]{ path: '/test', name: 'test', component: resolve => require(['@/test'], resolve) }
7、DllPlugin 插件的使用(这里提供简单的配置,具体根据实际需要)
首先在你的build文件加下新建 webpack.dall.config.js 文件,内容如下
[code]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
[code]"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 文件压缩 根据实际情况,具体配置如下
[code]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://www.geek-share.com/detail/2758015136.html
- 浏览器缓存机制介绍与缓存策略剖析 https://blog.csdn.net/woleigequshawanyier/article/details/86152516
- webpack 性能调优与 Gzip 原理 https://www.geek-share.com/detail/2756878164.html
- 本地存储——从 Cookie 到 Web Storage、IndexDB https://www.geek-share.com/detail/2758174077.html
- CDN 的缓存与回源机制解析 https://www.geek-share.com/detail/2758289318.html
- 服务端渲染的探索与实践 https://www.geek-share.com/detail/2758290029.html
- 解锁浏览器背后的运行机制 https://www.geek-share.com/detail/2758290961.html
- DOM 优化原理与基本实践 https://www.geek-share.com/detail/2758291438.html
- Event Loop 与异步更新策略 https://blog.csdn.net/woleigequshawanyier/article/details/86371850
- 回流(Reflow)与重绘(Repaint)https://www.geek-share.com/detail/2758292494.html
- Lazy-Load https://www.geek-share.com/detail/2755349729.html
- 事件的节流(throttle)与防抖(debounce) https://www.geek-share.com/detail/2757087836.html
- 前端学习资料下载 https://www.geek-share.com/detail/2756879693.html
- 技术体系分类 https://blog.csdn.net/woleigequshawanyier
前端技术架构体系(没有链接的后续跟进):
- 调用堆栈 https://www.geek-share.com/detail/2755957584.html
- 作用域闭包 https://www.geek-share.com/detail/2756472980.html
- this全面解析
- 深浅拷贝的原理 https://www.geek-share.com/detail/2757001066.html
- 原型prototype https://www.geek-share.com/detail/2757067030.html
- 事件机制、
- Event Loop https://www.jianshu.com/p/12b9f73c5a4f
- Promise机制、
- async / await原理、
- 防抖/节流原理 https://www.geek-share.com/detail/2757087836.html
- 模块化详解、
- es6重难点、
- 浏览器熏染原理、
- webpack配置(原理) https://www.geek-share.com/detail/2756878164.html
- 前端监控、
- 跨域和安全、
- 性能优化(参见上面性能优化相关)
- VirtualDom原理、
- Diff算法、
- 数据的双向绑定
- TCP协议(三次握手、四次挥手) https://www.geek-share.com/detail/2756552998.html
- DNS域名解析 https://www.geek-share.com/detail/2756549162.html
其它相关
- 前端学习资料下载 https://www.geek-share.com/detail/2756879693.html
- 技术体系分类 https://blog.csdn.net/woleigequshawanyier
- react-native 实战项目学习 https://github.com/15826954460/BXStage
- react-naitve 采坑笔记 https://blog.csdn.net/woleigequshawanyier/article/category/8512330
欢迎各位看官的批评和指正,共同学习和成长
希望该文章对您有帮助,你的 支持和鼓励会是我持续的动力
- vue-cli webpack2项目打包优化
- vue-cli webpack2项目打包优化分享
- webpack打包nodejs项目(前端代码)
- Webpack 2 视频教程 017 - Webpack 2 中分离打包项目代码与组件代码
- webpack3实战(1)打包一个CDN引入的jQuery项目
- 使用webpack打包vue项目,无法自动在浏览器中打开,情况总结
- webpack3实战(3)打包有es6、es7语法的js代码
- 详解webpack打包nodejs项目(前端代码)
- 前端项目模块化的实践2:使用 Webpack 打包基础设施代码
- Vue2+VueRouter2+webpack 构建项目实战(六)修复代码并通过验证,另发布代码
- webpack 项目打包 (build) 速度优化 --- Dll 方式
- webpack打包项目实战。看我怎么分项目管理
- webpack3实战(5)打包一个多页、jQuery、图片转base64、压缩混淆、异步模块加载的项目
- webpack进阶——DllPlugin优化打包性能(基于vue-cli)
- Vue项目实战(六)将接口用 webpack 代理到本地
- Webpack入门——使用Webpack打包Angular项目的一个例子
- webpack开发vue2项目中的一些坑(1、跨域 2、打包后后端访问一片空白3、加载第三方库的字体文件出错4、加载背景图出错)
- 工具学习——webpack 项目打包
- 关于webpack项目资源加载优化的几个实践(以react举例)
- WEB项目(B/S系统)打包安装(总结篇)