webpack优化不完全指南
2018-01-14 15:13
295 查看
基础篇
最基本的一个webpack配置const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: __dirname + "/app/main.js", //已多次提及的唯一入口文件 output: { path: __dirname + "/build", filename: "bundle-[hash].js" }, devtool: 'none', devServer: { contentBase: "./public", //本地服务器所加载的页面所在的目录 historyApiFallback: true, //不跳转 inline: true, hot: true }, module: { rules: [{ test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" } }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [{ loader: "css-loader", options: { modules: true, localIdentName: '[name]__[local]--[hash:base64:5]' } }, { loader: "postcss-loader" }], }) } } ] }, plugins: [ new webpack.BannerPlugin(), new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数 }), new webpack.optimize.OccurrenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin("style.css") ] };
接下来基于这份配置进行一个优化:
首先我们得区分开发环境、生产环境以及测试环境(这个在国内用的公司少)实现思路(参考vue-cil),通用配置可以设置一个base文件然后exports,在其他的配置文件中require进来。
上面这个配置中new webpack.optimize.UglifyJsPlugin()就可以放入webpack.prod.conf.js中,因为代码压缩丑化只需要在生产环境中使用,在开发过程开启的话,不仅编译时间加长还不利于调试。
module与entry、output这个就可以放到webpack.base.cong.js文件中,这些配置是通用的不管在生产环境还是开发环境中都是用得到的。
devServer则是在开发过程中需要启动一个服务器然后再开启热替换功能。
在module中也可进行些优化,例如在后缀为.js文件的处理中添加:
include: [resolve('src'), resolve('test')]
这样loader加载器就只会匹配src/与/test目录下的文件,至于node_modules目录下的文件则跳过,假如没加这一限制条件的话,node_modules下那么多的js文件,想想都觉得恐怖,并且别人发布出来的包文件一般都是经过babel转成ES5标准的。
添加alias,如:
alias: {
'@': resolve('src')
}
这样当webpack遇到import('@xxx')的时候就会直接在src/目录下去寻找,能节省不少的目录查询时间
进阶篇
多页面优化
当我们的项目是多个页面的时候,我们需要用到HtmlWebpackPlugin插件,for(let i = 0; i< html.length; i++) { plugins.push( new HtmlWebpackPlugin({ filename:fileName, template: path.join('./src/html/', fileName), inject: true, minify: { removeComments: true, collapseWhitespace: false, removeAttributeQuotes: true }, chunksSortMode: 'dependency', chunks: ['manifest', 'vendor', cur] })) ) }
有多少个页面就push多少个HtmlWebpackPlugin进去,至于页面的获取我们可以通过walk-sync来做到,通过获取目录下的入口文件来判断有多少个页面存在。
我在优化过程中遇到个坑,当webpack从2.x升级为3.x的时候,
compilation.getStats().toJson()
这个函数的执行时间会大大加长,我看到其实在issue里头有人提出来了,不过作者并没有给合并到master中去。还有点就是:当页面是多页面的时候每一次小的改动都会把所有的html文件重新生成一次,针对这两个优化我在Githubfork了下html-webpack-plugin,并发布了html-webpack-plugin-multihtml。我们的项目一共是有49个页面之前rebuild是花费5-7s ,优化后保持在1s左右。
提取公共代码CommonsChunkPlugin
有些类库如utils, bootstrap之类的可能被多个页面共享,最好是可以合并成一个js,而非每个js单独去引用。这样能够节省一些空间。这时我们可以用到CommonsChunkPlugin,我们指定好生成文件的名字,以及想抽取哪些入口js文件的公共代码,webpack就会自动帮我们合并好。new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', chunks: Object.keys(entrys), minChunks: function (module, count) { return (module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0 && count > 8) } }),
这个是针对多页面优化的,CommonsChunkPlugin会自己计算当一个类库被引用的次数超过8次,就把它打包至vendor中,这样就不必全打包至一个index.js里头
externals提取常用库
externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖。externals主要是防止将某些import的包打包到bundle中,而是在运行时(runtime)再去从外部获取这些扩展依赖
配置也挺简单的接下来贴下代码:
index.html中引入 <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
webpack.config.js中配置 externals: { jquery: 'jQuery' }
这样就能在代码中通过import引用了:
import $ from 'jquery';
uglifyPlugin多线程压缩代码
在webpack的默认情况下,都是单线程跑的,有个叫webpack-uglify-parallel的插件,它能够充分调用计算机的资源,利用计算机的多核特性进行代码压缩。使用方法也挺简单的,把之前webpack.prod.conf.js中的
new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: true }, comments: false }),
替换为
var os = require('os'); var UglifyJsParallelPlugin = require('webpack-uglify-parallel'); module.exports = { /// ... rest of config plugins: [ new UglifyJsParallelPlugin({ workers: os.cpus().length, // usually having as many workers as cpu cores gives good results // other uglify options }) ] }
即可GitHub地址:webpack-uglify-parallel
Happypack
happypack 是 webpack 的一个插件,目的是通过多进程模型,来加速代码构建。目前我们项目中已经配置并且上线了,效果还可以,从最初的40s减少到30s的编译时间。配置按照GitHub上的来,也不难
var HappyPack = require('happypack'); var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); // 省略其余配置 module: { loaders: [ { test: /\.less$/, loader: ExtractTextPlugin.extract('style',path.resolve(__dirname,'./node_modules', 'happypack/loader') + '?id=less' ) } ] }, plugins: [ new HappyPack({ id: 'less', loaders: ['css!less'], threadPool: happyThreadPool, cache: true, verbose: true }) ]
我在优化我们项目的webpack遇到了两个坑,一个就是上面提到的,webpack2升级3编译时间增多,另一个就是devServer在低版本安卓机型上跑步起来。devServer这个使用"webpack-dev-server": "2.7.1"即可,因为2.9.x版本使用的是es6的写法安卓4.1以下不支持,ie9以下也不支持。
作者:Zore_
链接:https://juejin.im/post/5a49fb696fb9a0451e402718
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关文章推荐
- web调试优化-chrome开发者工具不完全指南
- web调试优化-chrome开发者工具不完全指南
- webpack 使用优化指南
- Webpack打包优化指南
- webpack体积优化篇二(GZ压缩)
- 性能优化 - 查看 webpack 打包后所有的依赖关系(webpack 可视化工具)
- windows上安装nodejs,升级npm,安装webpack指南
- 详解vue-cli + webpack 多页面实例配置优化方法
- Webpack性能优化 DLL 用法详解
- webpack打包优化解决方案
- 【一小时入门】webpack 入门指南
- Webpack 入门指南 - 1.安装
- webpack + react 优化:缩小js包体积
- 高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间
- 数据库优化完全指南
- webpack打包优化
- vue项目优化之页面的按需加载(vue+webpack)
- webpack--指南1--打包文件配置
- Webpack4.x 版本入门指南
- React+webpack+Less 组件样式覆盖优化