欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

webpack4打包优化配置

程序员文章站 2022-05-30 17:45:00
...

1、对图片进行压缩和优化

image-webpack-loader可以帮助我们对图片进行压缩和优化

cnpm install image-webpack- --save-dev
复制代码
 {
      test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
      use: [
        'file-loader',
       {
         loader: 'image-webpack-loader',
         options: {
           mozjpeg: {
             progressive: true,
             quality: 65
           },
           optipng: {
             enabled: false,
           },
           pngquant: {
             quality: '65-90',
             speed: 4
           },
           gifsicle: {
             interlaced: false,
           },
           webp: {
             quality: 75
           }
         }
       },
      ]
    }
复制代码

2、区分环境变量

  • 日常的前端开发工作中,一般都会有两套构建环境
  • 一套开发时使用,构建结果用于本地开发调试,不进行代码压缩,打印 debug 信息,包含 sourcemap 文件
  • 一套构建后的结果是直接应用于线上的,即代码都是压缩后,运行时不打印 debug 信息,静态文件不包括 sourcemap
  • webpack 4.x 版本引入了 mode 的概念
  • 指定使用 production mode 时,默认会启用各种性能优化的功能,包括构建结果优化以及 webpack 运行性能优化
  • 指定使用 development mode 的话,则会开启 debug 工具,运行时打印详细的错误信息,以及更加快速的增量编译构建

2.2、获取mode参数

optimize-css-assets-webpack-plugin 用于优化或者压缩CSS资源

cnpm install image-webpack- --save-dev
复制代码
const UglifyJSPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports=(env,argv) => ({
    optimization: {
        minimizer: argv.mode == 'production'?[            
            new UglifyJSplugin({
                  cache: true,//启用缓存
                  parallel: true,// 使用多进程运行改进编译速度
                  sourceMap:true//生成sourceMap映射文件
            }),
            new OptimizeCssAssetsWebpackPlugin({})
        ]:[]
    }
})
复制代码

3、拆分webpack配置

可以把 webpack 的配置按照不同的环境拆分成多个文件,运行时直接根据环境变量加载对应的配置即可

  • webpack.base.js:基础部分,即多个文件*享的配置
  • webpack.development.js:开发环境使用的配置
  • webpack.production.js:生产环境使用的配置
  • webpack.test.js:测试环境使用的配置
  • 使用webpack-merge 合并环境配置
const { smart } = require('webpack-merge')
const webpack = require('webpack')
const base = require('./webpack.base.js')
module.exports = smart(base, {
  module: {
    rules: [],
  }
})
复制代码

4、设置忽略打包模块

IgnorePlugin用于忽略某些特定的模块,让 webpack 不把这些指定的模块打包进去

import 'vue-scroll from  'vue-scroll';
new webpack.IgnorePlugin(/^\.\/locale/,/vue-scroll/)

复制代码

5、设置无需解析文件

noParse 字段,可以用于配置哪些模块文件的内容不需要进行解析, 不需要解析依赖(即无依赖) 的第三方大型类库等,可以通过这个字段来配置,以提高整体的构建速度

module.exports = {
// ...
module: {
  noParse: /jquery|lodash/, // 正则表达式
  // 或者使用函数
  noParse(content) {
    return /jquery|lodash/.test(content)
  },
}
}...
复制代码

6、resolve解析

6.1extensions

指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配

resolve: {
  extensions: [".js",".vue",".json",".css"]
},
复制代码

6.2 alias

配置别名可以加快webpack查找模块的速度

每当引入lodash 模块的时候,它会直接引入lodash,而不需要从node_modules文件夹中按模块的查找规则查找

resolve: {
   alias:{
    "lodash":path.resolve(__dirname,'node_modules/lodash');
   }
},
复制代码

6.2 modules

  • 对于直接声明依赖名的模块(如 vue ),webpack 会类似 Node.js 一样进行路径搜索,搜索node_modules目录
  • 这个目录就是使用resolve.modules字段进行配置的 默认配置
resolve: {
    modules: ['node_modules'],
}
复制代码

6.2 mainFiles

当目录下没有 package.json 文件时,我们说会默认使用目录下的 index.js 这个文件,其实这个也是可以配置的

resolve: {
  mainFiles: ['index'], // 你可以添加其他默认使用的文件名
}
复制代码

7、打包第三方类库

平时使用工具函数时,会直接引用过来例如:

import _ from 'lodash';
console.log(_.join([1, 2, 3],','));
复制代码

利用webpack.ProvidePlugin lodash 函数会自动添加到当前模块的上下文,无需显示声明

  new webpack.ProvidePlugin({
      _:'lodash'
  })
复制代码

8、DLL

dll为后缀的文件称为动态链接库,在一个动态链接库中可以包含给其他模块调用的函数和数据

  • 把基础模块独立出来打包到单独的动态连接库里
  • 当需要导入的模块在动态连接库里的时候,模块不能再次被打包,而是去动态连接库里获取
  • DllPlugin插件: 用于打包出一个个动态连接库
  • DllReferencePlugin: 在配置文件中引入DllPlugin插件打包好的动态连接库
const path=require('path');
const DllPlugin=require('webpack/lib/DllPlugin');
module.exports={
    entry: {
        vue:['vue','vue-router']
    },// 把 vue, vue-router 相关模块的放到一个单独的动态链接库
    output: {
        path: path.resolve(__dirname,'dist/dll'),// 输出的文件都放到 dist/dll 目录下
        filename: '[name].dll.js',//输出的动态链接库的文件名称,[name] 代表当前动态链接库的名称
        library: '_dll_[name]',//存放动态链接库的全局变量名称,例如对应 vue 来说就是 _dll_vue
    },
    plugins: [
        new DllPlugin({
            context: __dirname,
            // 动态链接库的全局变量名称,需要和 output.library 中保持一致
            // 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
            // 例如 vue.manifest.json 中就有 "name": "_dll_vue"
            name: '_dll_[name]',
            // 描述动态链接库的 manifest.json 文件输出时的文件名称
            path: path.join(__dirname, 'dist/dll', '[name].manifest.json')
        })
    ]
}
复制代码

9、HappyPack

  • Node.js 之上的 Webpack 是单线程模型
  • 构建需要解析和处理文件,文件读写和计算密集型的操作太多后速度会很慢
  • happypack 就能让Webpack把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
npm i happypack --save-dev
复制代码
const HappyPack = require('happypack');
    rules: [
    {
        test: /\.js$/,
        // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
        use: ['happypack/loader?id=babel'],
        exclude: path.resolve(__dirname, 'node_modules'),
    },
    {
        test: /\.css$/,
        // 把对 .css 文件的处理转交给 id 为 css 的 HappyPack 实例
        use: ['happypack/loader?id=css']
    }
]
new Happypack({
            //ID是标识符的意思,ID用来代理当前的happypack是用来处理一类特定的文件的
            id: 'js',
            use: [{
                loader: 'babel-loader',
                //options=query都是向插件传递参数的
                options: {
                    presets: [["@babel/preset-env", { modules: false }], "@babel/preset-react"],
                    plugins: [
                        ["@babel/plugin-proposal-decorators", { "legacy": true }],
                        ["@babel/plugin-proposal-class-properties", { "loose": true }],
                    ]
                }
            }]
        }),
        new Happypack({
            //ID是标识符的意思,ID用来代理当前的happypack是用来处理一类特定的文件的
            id: 'css',
            use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
            threads: 4,//你要开启多少个子进程去处理这一类型的文件
            verbose: true//是否要输出详细的日志 verbose
        })
复制代码

10、打包模块输出分析

通过使用webpack-bundle-analyzer可以看到项目各模块的大小,可以按需优化

安装

cnpm i webpack-bundle-analyzer --save-dev
复制代码

配置webpack

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [
  new BundleAnalyzerPlugin(
           {
              analyzerMode: 'server',
              analyzerHost: '127.0.0.1',
              analyzerPort: 8889,
              reportFilename: 'report.html',
              defaultSizes: 'parsed',
              openAnalyzer: true,
              generateStatsFile: false,
              statsFilename: 'stats.json',
              statsOptions: null,
              logLevel: 'info'
            }
       ),
]
复制代码

配置package.json

"analyz": "NODE_ENV=production npm_config_report=true npm run build"
复制代码

分析结果

webpack --profile --json > stats.json

复制代码

转载于:https://juejin.im/post/5cf0fc7df265da1bc07e2043