前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Webpack 项目打包压缩优化

Webpack 项目打包压缩优化

原创
作者头像
KID.
修改2023-10-23 17:51:24
4460
修改2023-10-23 17:51:24
举报

针对与webpack项目打包,我们正常做的最多的就是脚手架安装,后run build直接部署,不会去做过多的处理。

对webpack学习,使用webpack打包优化,主要注重两点

  • 面向开发者:提示打包速度
  • 面向用户:缩小打包体积

webpack 优化常用

打包速度优化

代码语言:txt
复制
npm i speed-measure-webpack-plugin -D

使用

代码语言:txt
复制
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

const smp = new SpeedMeasurePlugin();

// 将webpack配置内容用wrap包裹起来
const webpackConfig = smp.wrap({
  plugins: [new MyPlugin(), new MyOtherPlugin()],
});

执行打包命令后,可以看出哪个插件打包耗时比较高,已进行针对优化打包速度

使用thread-loader进行多线程打包优化

  • 安装thread-loader
代码语言:txt
复制
npm install --save-dev thread-loader

使用时在配置loader时将thread-loader加在比较耗时的loader前面

代码语言:txt
复制
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve('src'),
        use: [
          "thread-loader", // 在耗时的loader前加上thread-loader进行多线程打包
          // 耗时的 loader (例如 babel-loader)
        ],
      },
    ],
  },

官方提供了thread-loader的配置参数,可以修改参数达到提速的效果。

代码语言:txt
复制
 use: [
  {
    loader: "thread-loader",
    // 有同样配置的 loader 会共享一个 worker 池
    options: {
      // 产生的 worker 的数量,默认是 (cpu 核心数 - 1),或者,
      // 在 require('os').cpus() 是 undefined 时回退至 1
      workers: 2,

      // 一个 worker 进程中并行执行工作的数量
      // 默认为 20
      workerParallelJobs: 50,

      // 额外的 node.js 参数
      workerNodeArgs: ['--max-old-space-size=1024'],

      // 允许重新生成一个僵死的 work 池
      // 这个过程会降低整体编译速度
      // 并且开发环境应该设置为 false
      poolRespawn: false,

      // 闲置时定时删除 worker 进程
      // 默认为 500(ms)
      // 可以设置为无穷大,这样在监视模式(--watch)下可以保持 worker 持续存在
      poolTimeout: 2000,

      // 池分配给 worker 的工作数量
      // 默认为 200
      // 降低这个数值会降低总体的效率,但是会提升工作分布更均一
      poolParallelJobs: 50,

      // 池的名称
      // 可以修改名称来创建其余选项都一样的池
      name: "my-pool"
    },
  },
  // 耗时的 loader(例如 babel-loader)
];

现在的脚手架大多更新迭代很快,可能会出现 使用了多线程但是速度并未提升很多的可能。除了工具还需要阅读代码,查看使用的插件在项目中的场景,综合考虑解决办法

打包体积优化

  • 安装 webpack-bundle-analyzer 会弹出一个网页来显示项目打包后的体积大小,根据打包提及来优化 使用
代码语言:txt
复制
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
      // 只需要在plugin中new一个实例就可以了。 
    new BundleAnalyzerPlugin()
  ]
}

webpack 分包处理

我们可以自行决定将webpack中哪内容分包出去。

例如我们要将项目中的react-dom@material-ui/xxx相关内容分包出去

  • 创建 webpack.dll.config,js用来写分包的配置文件
代码语言:txt
复制
const path = require('path')
const webpack = require('webpack')
modules.exports = {
    mode:'production', // 只在生产环境才使用
    entry:{
        common:[
            // 想要分包的依赖
            'react-dom',
            '@material-ui/core',
            '@material-ui/icons',
            '@material-ui/lab'
        ]
    },
    output:{
        path:path.resolve(__dirname, "../dll"), //文件生成的路径再上一级的dll文件夹
        fillname:'[name].dll.js', // [name]会与入口文件名称相同,
        library:'[name]_[hash]' // [hash] 会自动生成hash值
    },
    plugins:[
        new webpack.DllPlugin({
            path: path.resolve(__dirname, "../dll", "[name]-manifest.json"),
            name: '[name]_[hash]' // 要与library名称相同
        })
    ]
}

随后需要在package.json中配置分包命令

代码语言:txt
复制
"scripts": {
    "build-dll":"webpack --config config/webpack.dll.config.js" //config/webpack.dll.config.js 是分包的配置文件地址
}

运行时需要安装webpack-cli 如果没有安装,会提示安装

代码语言:txt
复制
npm run build-dll

运行成功后,dll文件夹下会生成 对应的 common-manifest.jsonconmon.dll.js文件

  • 生产分包需要需要在webpack中将分的包排除出去 在项目打包的webpack配置文件中
代码语言:txt
复制
plugins:[
    new webpack.DllReferencePlugin({
        context:path.resolve(__dirname, '../'),
        manifest:path.resolve(__dirname, '../dll/common-manifest.json') //对应生成的manifest文件路径
    })
]

此时运行npm run build webpack-bundle-analyzer弹出页面,分包出去的依赖就已经消失了。体积也会缩小。

  • 引入分包文件 引入分包文件需要安装 copy-webpack-pluginhtml-webpack-tags-pluginnpm i copy-webpack-plugin html-webpack-tags-plugin -Dcopy-webpack-plugin使用如果webpack版本可能会报错,报错可以尝试修改copy-webpack-plugin的版本后再重新打包
  • 使用
代码语言:txt
复制
const CopyWebpackPlugin  =require('copy-webpack-plugin')
const HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin')
plugins:[
    new webpack.DllReferencePlugin({
        context:path.resolve(__dirname, '../'),
        manifest:path.resolve(__dirname, '../dll/common-manifest.json') //对应生成的manifest文件路径
    }),
    // 将生成的dll文件拷贝到打包生成的目录
    new CopyWebpackPlugin = ({
        patterns:[
            {
                from:"./dll/common.dll.js", // 分包生成的文件
                to:"./static/js" //打包生成目录
            }
        ]
    })
    // 将拷贝过来的分包文件进行引用
    new HtmlWebpackTagsPlugin({
        tags:['/static/js/common.dll.js'],
        append:false
    })
]

这里可能会存在打包后生成的连接名称替换不成功,大多是因为speed-measure-webpack-plugin可能会有冲突,将speed-measure-webpack-plugin禁用可以解决。

代码语言:txt
复制
const smp = new SpeedMeasurePlugin({
    disable:true
});

常用的webpack plugin

plugin名称

作用

HotModuleReplacementPlugin

模块热更新

clean-webpack-plugin

目录清理

html-webpack-plugin

自动生成一个index.html文件,将打包的js文件自动通过<script>标签引用

uglifyjs-webpack-plugin

js压缩

mini-css-extract-plugin

分离样式文件,将ss提取为单独文件

DefinePlugin

定义全局常量,应用:在不用环境下引入不通的配置

speed-measure-webpack-plugin

输出打包内容速度

webpack-bundle-analyzer

可视化webpack输入文件体积

常用loader 介绍

loader名称

作用

css-loader

用于处理css文件,是的在js文件中可以引入

style-loader

将css文件注入到index.html中的style标签上

less-loader

处理less代码

sass-loader

处理sass代码

babel-loader

把ES6转ES5

ts-loader

把typescript 转成es5

file-loader

打包图片,打包字体图标

webpack-bundle-analyzer

可视化webpack输入文件体积

html-withimg-loader

打包HTML文件中的图片

eslint-loader

用于检查常见的代码错误,和书写规范检查

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • webpack 优化常用
    • 打包速度优化
      • 使用thread-loader进行多线程打包优化
        • 打包体积优化
        • webpack 分包处理
        • 常用的webpack plugin
        • 常用loader 介绍
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档