一次优化webpack打包的经历
来源:互联网 发布:linux 显卡性能测试 编辑:程序博客网 时间:2024/06/15 16:20
起因
如题,有个项目每次打包时间均有480s左右,之前忙于业务开发,无暇修复,小组成员深受其害。今天,分配了时间着手解决一下。
过程
打开收藏夹的一篇webpack优化教程,按步进行优化。
依次使用了
- dll打包第三方npm包
- happypack优化loader
happypack的readme更新不够及时,在找 ExtractTextPlugin 使用方法着实费了功夫
其中happypack 和 ExtractTextPlugin 抽取css共同使用的方法请参考这里
挫折
经历上步优化,打包时间稳定在了410s左右…
好像也没什么区别
转机
灵机一动,死马当活马医,将webpack打包时停滞时间最长的提示 addtional asset processing 直接googe,然后将查到的所有网页的解决方案都试一试,然后在尝试某一篇github上发现的一个优化方法时
webpack提供的UglifyJS插件由于采用单线程压缩,速度很慢 ,webpack-parallel-uglify-plugin插件可以并行运行UglifyJS插件,这可以有效减少构建时间,当然,该插件应用于生产环境而非开发环境,配置如下:var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');new ParallelUglifyPlugin({ cacheDir: '.cache/', uglifyJS:{ output: { comments: false }, compress: { warnings: false } } })
打包时间瞬间就降低到40s!!!!!感谢万能的谷歌!!
总结
打包配置最终如下
//--webpack.config.js// 一些通用的库var webpack = require('webpack');var path = require('path');var url = require('url');var webpackHotDevServer = require('webpack-dev-server');// 用到的插件var ExtractTextPlugin = require('extract-text-webpack-plugin');var HtmlWebpackPlugin = require('html-webpack-plugin');var WebpackBrowserPlugin = require('webpack-browser-plugin');var HappyPack = require('happypack');//多线程loader 加快编译速度var os = require('os');var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');// 编译输出的控制台信息美化插件var DashboardPlugin = require('webpack-dashboard/plugin');// 获取 node_modules 文件夹的路径var node_modules = path.resolve(__dirname, 'node_modules');// 使用压缩后的 ReactJS, 优化编译速度var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');var pathMapboxgl = path.resolve(__dirname, 'src/libs/mapbox-gl/mapbox-gl-dev.js');module.exports = { // 调试模式 // debug: true, // 设置webpack识别的base目录, 绝对路径 context: path.resolve(__dirname, './src/'), performance: { hints: "warning" }, cache: true, devtool: 'hidden-source-map', devServer: { // 设置热启动服务器的根目录,不然一些图片等静态资源是加不到的哦 // contentBase: path.join(__dirname, './src/'), contentBase: false, hot: true, inline: true, port: 3002, quiet: true, noInfo: true, clientLogLevel: 'error', stats: "errors-only", // lazy: true, // filename: "vendors.js" }, // 定义的实体 entry: { 'index': ['./app.jsx'], 'vendors': ['whatwg-fetch'] }, output: { // 这个是项目的输出路径,必须是绝对路径 path: path.resolve(__dirname, "dist"), // path: path.resolve(__dirname, ""), filename: 'js/[name].js?v=[hash:5]', // 添加 chunkFilename 为了实现 react-router的懒加载 chunkFilename: 'js/[name].chunk.js?v=[chunkhash:5]', // 编译后的包的访问位置 publicPath: './' }, resolve: { // root: path.resolve(__dirname, 'app'), alias: { 'mapboxgl': pathMapboxgl, 'reactmin': pathToReact }, extensions: ['.js', '.sass', '.jsx', '.jpg', '.jpeg', '.gif', '.png'] }, module: { noParse: [ /mapbox-gl.+\.js$/, ], rules: [ { test: /\.jsx$/, exclude: /(node_modules)/, use:'happypack/loader?id=jsx' }, { test: /\.js$/, exclude: /(node_modules[^\/gago\-.*]|bower_components|libs\/mapbox-gl)/, // loaders: ['babel-loader?cacheDirectory&presets[]=es2015,presets[]=react,presets[]=stage-0'] use: 'happypack/loader?id=js' },{ test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: ['style-loader'], loader: 'happypack/loader?id=scss', publicPath:'../' }) }, { test: /\.(jpg|jpeg|gif|png)$/, loader: 'url-loader?limit=8192&name=./images/[name].[ext]' }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: ['style-loader'], // use: ['css-loader', 'postcss-loader'], use: 'happypack/loader?id=css', publicPath:'../' }) }, { test: /\.(woff|woff2|eot|ttf|svg)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff&name=./fonts/[name].[ext]' } ] }, plugins: [ new webpack.DllReferencePlugin({ context: __dirname, /** * 在这里引入 manifest 文件 */ manifest: require('./dist/vendors-manifest.json') }), // new WebpackBrowserPlugin(), new HappyPack({ id: 'jsx', // threads: 4, threadPool: happyThreadPool, loaders: [{ loader: 'babel-loader', options: { presets: ['react', 'es2015', 'stage-0'], plugins: [ ['import', { libraryName: 'antd', style: 'css', }] ] } }] }), new HappyPack({ id: 'js', // threads: 4, threadPool: happyThreadPool, loaders: [{ loader: 'babel-loader', options: { presets: [ 'es2015','react', 'stage-0'], cacheDirectory: true } }] }), new HappyPack({ id: 'scss', // threads: 4, threadPool: happyThreadPool, loaders: ['css-loader', 'sass-loader'] }), new HappyPack({ id: 'css', // threads: 4, threadPool: happyThreadPool, loaders: ['css-loader', 'postcss-loader'], }), // 控制台输出美化 new DashboardPlugin(), new webpack.optimize.CommonsChunkPlugin({ // 模块的名字--在entry里面定义的 name: 'vendors', // 模块的输出文件名 filename: 'js/vendors.js' }), new webpack.HotModuleReplacementPlugin(), // 混淆代码 // new webpack.optimize.UglifyJsPlugin({ // compress: { // warnings: false // }, // sourceMap: false // }), new ParallelUglifyPlugin({ cacheDir: '.cache/', uglifyJS:{ output: { comments: false }, compress: { warnings: false } } }), // 使用 ProvidePlugin 加载使用率高的依赖库 new webpack.ProvidePlugin({ React: 'reactmin', mapboxgl: 'mapboxgl', jQuery: 'jquery', 'window.jQuery': 'jquery', $: 'jquery', }), new ExtractTextPlugin({ filename: 'css/[name].css?v=[chunkhash:5]', allChunks: false, // disable: true }), new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', chunks: ['index', 'vendors'] }), // 这是用于判断当前的环境(开发环境还是生产环境) new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(false), 'process.env': { 'NODE_ENV': JSON.stringify('production') } }) ]};
//--webpack.dll.config.jsconst {join} = require('path');const webpack = require('webpack');const node_modules = join(__dirname, 'node_modules');// 使用压缩后的 ReactJS, 优化编译速度const pathToReact = join(node_modules, 'react/dist/react.min.js');const pathMapboxgl = join(__dirname, 'src/libs/mapbox-gl/mapbox-gl-dev.js');const OutputDir = join(__dirname,'dist');module.exports = { entry: { vendors: ['mapboxgl','react', 'react-dom','react-router','echarts','jquery','lodash','material-ui'] }, output: { path: OutputDir, filename: 'js/[name].dll.js', /** * output.library * 将会定义为 window.${output.library} * 在这次的例子中,将会定义为`window.vendor_library` */ library: '[name]_library' }, resolve: { alias: { 'mapboxgl': pathMapboxgl, }, // extensions: ['.js', '.sass', '.jsx', '.jpg', '.jpeg', '.gif', '.png'] }, plugins: [ new webpack.DllPlugin({ /** * path * 定义 manifest 文件生成的位置 * [name]的部分由entry的名字替换 */ path: join(OutputDir, '[name]-manifest.json'), /** * name * dll bundle 输出到那个全局变量上 * 和 output.library 一样即可。 */ name: '[name]_library' }) ]};
0 0
- 一次优化webpack打包的经历
- 一次优化Lua算法的经历
- 一次非常有意思的sql优化经历
- 一次非常有意思的 SQL 优化经历
- 一次非常有意思的sql优化经历
- 一次非常有意思的SQL优化经历
- 一次非常有意思的 SQL 优化经历
- 一次非常有意思的sql优化经历
- 一次非常有意思的SQL优化经历
- 一次 MySQL 索引优化的经历
- 一次优化列表页卡顿的经历
- 一次非常有意思的 SQL 优化经历
- 记一次小小的优化经历
- 一次非常有意思的 SQL 优化经历
- 一次非常有意思的SQL优化经历
- 一次生产事故的优化经历
- 一次生产事故的优化经历
- 一次生产事故的优化经历
- 数据库
- 仿微信朋友圈【九宫格的实现】
- Git-GitLab 设置添加SSH
- 1.Unity3D商业游戏源码研究-变身吧主公-ResourcesMgr
- 排序算法六:选择排序之简单选择排序
- 一次优化webpack打包的经历
- 训练营第四天作业
- Ubuntu下idea/pycharm/clion等工具自动格式化快捷键设置
- 使用IDEA搭建SpringBoot项目且整合mongoDB和mysql
- 搭建Apache Httpd服务RHCE-Day9
- Zedboard---实验三阻塞非阻塞
- 极光推送的设备唯一性标识 RegistrationID
- Servlet_11th_Session的读写与作用域
- OkHttp Wiki翻译(二)调用