【webpack优化】项目中webpack的配置和优化

本篇将不逐一介绍webpack配置项的意义和作用,配置项不熟悉可参考webpack官方文档(https://www.webpackjs.com/)。

或者也可以参考我的另一篇文章 webpack之深入浅出

现在仅从项目实践角度出发,结合开发过程中遇到的优化问题,具体给出webpack( 项目中webpack版本为3.12.0,webpack 4.x略有不同 )配置项的实现目的和优化方案。优化方案的最终结果将在两个维度体现出来:构建性能效率打包资源体积。本文将默认按照项目webpack从上到下的配置项,逐次展开,添加优化项。

1、resolve

resolve解析项目中的模块,但是如果检索每个文件夹就会浪费资源,降低效率。所以要设定或者排除,哪些文件夹需要检索,哪些不需要。

resolve: {
   
    ...

    // resolve.modules -> webpack 解析模块时应该搜索的目录,可以设置 node_moudles 目录
    modules: [path.resolve(__dirname, "src"), "node_modules"]
    
},

2、loaders

A、删除冗余loaders

项目默认使用sass处理样式文件。所以不需要配置less,stylus等其他类型的loaders。初始化的时候,将冗余loader配置删除,仅保留项目使用的文件。

function generateLoaders () {
    // 动态创建loader ...
}

 return {  //返回css类型对应的loader组成的对象 generateLoaders()来生成loader
    css: generateLoaders(),
    // postcss: generateLoaders(),
    // less: generateLoaders('less'),
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders('sass'),
    // stylus: generateLoaders('stylus'),
    // styl: generateLoaders('stylus')
  }

// 删除冗余css-loaders,把postcss, less, sylus, styl 等项目中未使用的loaders配置删除。

B、简化loader的检索范围

和resolve.moudels类似,loader也会检索项目中出现的正则匹配的文件。所以仍需要设置需要检索的文件夹,提高效率

// 比如 js文件

{
      test: /\.js$/,
      //loader: 'babel-loader',
      loader: 'happypack/loader?id=happy-babel-js',
        
      // 以下为新增优化配置
      // 目的在于只检索src下的js文件即可,不需要检索其他文件夹,提高检索效率  
      include: [resolve('src')]
},

...

3、sourceMap

sourcemap 一个反应原文件映射关系的文件,在开发环境调试阶段尤为重要,可以在原代码中直接报出出错的行数和列数,方便定位。但是在生产环境中,则不需要。所以,不同环境之间设置有所不同。

A、devtool

不同的devtool的配置,直接影响到项目构建速度。具体可查看官方文档 https://www.webpackjs.com/configuration/devtool/#devtool

经综合比较,得出开发环境和生产环境模式下的配置:

// dev 开发环境

// cheap-module-eval-source-map is faster for development
devtool: 'cheap-module-eval-source-map',


// production 生产环境
devtool: 'cheap-module-source-map';
或者直接设置为false (不设置source-map)

B、productionSourceMap

打包时,不需要sourcemap来映射文件关系,所以生产模式下关闭 sourcemap。

module.exports = {
    build: {
        ...

        productionScourceMap: false
    }
}

4、plugins

不同于loader作为解释转化器的角色,plugins作为webpack功能的拓展,会在webpack构建的某个节点(生命周期)执行某些任务。

A、webpack-parallel-uglify-plugin

该插件的作用在于:

1、压缩输出js文件

2、设置缓存文件,加速构建。

3、删除js注释、冗余变量等。

// npm i -D webpack-parallel-uglify-plugin
// config.js

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');

plugins: [

    ...

    new ParallelUglifyPlugin ({
    // 设置缓存路径,不改动的调用缓存,第二次及后面build时提速
    cacheDir: '.cache/',  
    // 混淆压缩js文件 
    uglifyJS:{
        output: {
          beautify: false,
          comments: false
        },
        warnings: false,
        compress: {
          // 删除所有的 `console` 语句,可以兼容ie浏览器
          drop_console: true,
          // 内嵌定义了但是只用到一次的变量
          collapse_vars: true,
          // 提取出出现多次但是没有定义成变量去引用的静态值
          reduce_vars: true,
        }
      }
    
    })

    
]

B、extract-text-webpack-plugin

该插件的作用在于单独提取css文件,不直接将style注入html的head中,单独打包。

// npm i -D extract-text-webpack-plugin

var ExtractTextPlugin = require('extract-text-webpack-plugin')

// extract css into its own file
    new ExtractTextPlugin({

     // 输出文件名更改为 文件指纹命方式,避免缓存  
      filename: utils.assetsPath('css/[name].[contenthash].css')
    }),

C、CompressionWebpackPlugin

该插件的作用在于开启GZIP压缩,可以使输出文件的体积显著变小。

// npm i -D compression-webpack-plugin

var CompressionWebpackPlugin = require('compression-webpack-plugin')

new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      // 正则匹配需要 Gzip压缩的文件格式 productionGzipExtensions -> [js, css, json]
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      // 只处理比这个值大的资源。按字节计算
      threshold: 10240,
      // 只有压缩率比这个值小的资源才会被处理
      minRatio: 0.8
})

D、HappyPack

该插件的作用在于充分发挥电脑多核CPU,把任务分解给多个子进程去并发的执行,提高构建速度。

// npm i -D happypack

const HappyPack = require('happypack');
const os = require('os');

// 获取电脑硬件的cpu核心数,准备开启多线程构建
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module.exports = {

    // 要告诉 happypack 处理哪些类型的文件 比如 vue,js文件
    moudles: {
        rules: [
            {
              test: /\.vue$/,
              loader: 'happypack/loader?id=vue',
            },
            {
              test: /\.js$/,
              //loader: 'babel-loader',
              loader: 'happypack/loader?id=happy-babel-js', 
              include: [resolve('src'), resolve('test')]
            },
        ]
    },

    // plugins
    plugins: [
        new HappyPack({
          // //用id来标识 happypack处理那里类文件
        id: 'happy-babel-js',
        loaders: ['babel-loader?cacheDirectory=true'],
          // 共享进程池
        threadPool: happyThreadPool,
       }),
        new HappyPack({
        id: 'vue',
        loaders: [{
            loader:'vue-loader',
            options:vueLoaderConfig
          }],
        threadPool: happyThreadPool,
       }),
    ]
}

E、image-webpack-loader

该插件作用在于处理项目中图片的体积,可以显著减少各种格式图片的体积.(这个属于loader优化,暂且放在这部分)

// npm i -D image-webpack-loader
// 具体可参照文档 https://www.npmjs.com/package/image-webpack-loader

rules: [
{

    test: /\.(gif|png|jpe?g|svg)$/i,
    use: [
    'file-loader',
    {
      loader: 'image-webpack-loader',
      options: {
        mozjpeg: {
          progressive: true,
          quality: 65
        },
        // optipng.enabled: false will disable optipng
        optipng: {
          enabled: false,
        },
        pngquant: {
          quality: [0.65, 0.90],
          speed: 4
        },
        gifsicle: {
          interlaced: false,
        },
        // the webp option will enable WEBP

        // 其中注意 webp格式 只支持谷歌浏览器 所以可以不用配置
        webp: {
          quality: 75
        }
      }
    },
}]

F、webpack-bundle-analyzer

该插件的作用在于分析打包情况,可以以图表的方式直观给出打包过后资源依赖的大小,有针对性的去优化依赖。

// npm i -D webpack-bundle-analyzer

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

// npm run build -> Analyze package size
new BundleAnalyzerPlugin({
      analyzerMode: 'server',
      analyzerHost: '127.0.0.1',
       // 自动开启 8889 端口显示资源大小
      analyzerPort: 8889,
      reportFilename: 'report.html',
      defaultSizes: 'parsed',
      openAnalyzer: false,
      generateStatsFile: false,
      statsFilename: 'stats.json',
      statsOptions: null,
      logLevel: 'info'
}),

以上方案在项目实践中得到了检验,有效的提高了项目构建的效率,减少打包后dist包的体积。

欢迎补充~~.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值