1 Star 1 Fork 0

pipe / webpack_opt

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

🌴 webpack opt

本次基于webpack@5.54.0, 完成相关 webpack 优化,具体相关配置参数请查看官网

官网:https://webpack.docschina.org


安装 webpack 相关环境并完成配置

核心包: webpack , webpack-cli , webpack-dev-server , html-webpack-plugin , @babel/core , @babel/preset-env , babel-loader , clean-webpack-plugin


noParse 加快构建速度

防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。

所以总的结论是: 文件中没有任何导入就可以使用 noParse

列子:引用 jquery 时,使用 noParse 加快打包速度 1

  module: {
      noParse: /jquery|lodash/,
  }

IgnorePlugin

忽略第三方包中的一些不使用的文件,减少打包体积

moment.js 举例, 去除 webpack 中其他语言包,只导入之际所需要的语言包

  • 未使用 momentjs 打包体积660KB
  • 使用 momentjs 打包体积 2.14MB
  • 使用 monmentjs, 配合 IgnorePlugin 插件 打包体积1.01M
/* webpack.config.js */
const webpack = require('webpack')

module.exports = {
    ...,
    plugins: [
        new webpack.IgnorePlugin({
            resourceRegExp: /^\.\/locale$/,
            contextRegExp: /moment$/,
        })
    ]
}
/* index.js中使用momentjs */
import * as moment from 'moment';
import 'moment/locale/zh-cn';

console.log(moment.locale('zh-cn'));
console.log(moment(1316116057189).fromNow());

dllPlugin 动态连接库

动态链接库好处:减小入口文件大小,比如减小 index.js 文件大小,避免首屏加载过慢。单独打包了第三方库文件,加快了打包编译速度。但动态链接库的使用不一定会整体减少构建包的体积。

分别以 react 和 vue 来举例

  1. react 举例
  • 安装 react 环境

三个核心包: react , react-dom , @babel/preset-react

/* 主要在babel presets添加对@babel/preset-react 解析react语法*/
/* .babelrc */
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": "defaults"
            }
        ],
        [
            "@babel/preset-react",
            {
                "targets": {
                    "node": "current"
                }
            }
        ]
    ]
}
  • 动态链接库基本配置
1: /* 新建打包第三方的webpack配置文件 */
    /* webpack.config.react.js 生产json清单路径*/
    module.exports = {
        plugins: [
            new webpack.DllPlugin({
                name: '_dll_[name]',
                path: path.resolve(__dirname, "dist", "manifest.json"),
            })
        ]
    }

2: /* 主配置文件 */
    /* webpack.config.js 该去那里查找清单路径*/
    new webpack.DllReferencePlugin({
        manifest: path.resolve(__dirname, "dist", "manifest.json"),
    })
/* CleanWebpackPlugin设置cleanOnceBeforeBuildPatterns属性,每次打包不会清空dll文件夹下文件,避免每次都打包第三方库 */
new CleanWebpackPlugin({
    cleanOnceBeforeBuildPatterns: ["**/*", "!dll/**"],
}),
3: /* index.html 引入打包后的第三方js */
<script src="./_dll_react.js"></script>
  • react 打包文件对比(基于生产模式 production)
构建包体积 入口文件大小 第三方打包文件大小
126kb 125kb /
129kb 小于 1KB 128kb
  • vue 打包文件对比(基于生产模式 production, 采用 vue 运行时的版本)
构建包体积 入口文件大小 第三方打包文件大小
64.1kb 63.7kb /
65.0kb 小于 1KB 64.1kb

happypack 多线程打包

开启多线程打包,加快打包构建速度。

/* webpack.config.js */
module.exports = {
        rules: [
            rules: [{
                test: /\.m?js$/,
                exclude: /node_modules/,
                use: "happypack/loader",
            }]
            plugins: [
                new HappyPack({
                    threads: 4,
                    loaders: ["babel-loader"],
                }),
            ]
        }

webpack 中自带优化(仅限于生产模式 production)

  1. tree-shaking

把没用的代码自动删除

/* unit.js */
const sum = (a, b) => {
    return a + b;
};
const minus = (a, b) => {
    return a - b;
};
export default {
    sum,
    minus,
};
/* index.js */
import calc from "./utils.js";
console.log(calc.sum(1, 2));

打包后 webpack 会自动去掉 minus 函数,因为它没有被调用过

  1. scope hosting 作用域提升

在 webpack 中自动省略部分代码,计算数值,简化代码。

let a = 1;
let b = 2;
let c = 3;
let d = a + b + c;
console.log(d + "------");

经过 webpack 打包后,会自动计算出结果,打包文件会直接输出 console.log(6+'------')


webpack 抽离公共代码 剥离代码块

从 webpack v4 开始,移除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks

新建三个文件, app1.js , app2.js , common.js 。app1 和 app2 都导入了 common, 如果不采用抽离公共代码,打包后,app1 和 app2 都会包含 common 的代码。 其实此时,我们即可将 common 抽离为公共代码块,进行单独打包为一个文件,app1 和 app2 只需引入公共代码块,增加代码的可复用性。

RUNOOB 图标

具体操作如下:

  1. 剥离公共代码块
/* 具体配置参数查看webpack官网 */
module.exports = {
    optimization: {
        splitChunks: {
            cacheGroups: {
                common: {
                    // filename: "common.js",
                    name: "commons",
                    chunks: "initial",
                    minChunks: 2,
                    minSize: 0,
                },
            },
        },
    },
};

提示:在代码复用性不高,公共代码不多时使用抽离公共代码,反而会增加构建包的体积。例如本例中,

公共代码块很简单,体积不大,不需要剥离代码块,剥离后反而增加了构建包的体积。

  1. 剥离第三方依赖库,第三方依赖库单独打包文件
/* 具体配置参数查看webpack官网 */
module.export = {
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    name: "chunk-common",
                    chunks: "initial",
                    priority: -20,
                    minChunks: 2,
                    minSize: 0,
                },
                vendors: {
                    name: `chunk-vendors`,
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10,
                    chunks: "initial",
                },
            },
        },
    },
};
  1. 以 vuecli4 为例

下图是 vuecli4 脚手架的 SplitChunksPlugin 配置。

RUNOOB 图标

我们可以修改该配置,将 chunk-vendors 进一步剥离,以优化我们的首频加载速度。例如,我们可以将第三方组件库单独剥离出来,具体配置如下:

/* vue.config.js  vuecli4.0 */
module.exports = {
    configureWebpack: (config) => {
        config.optimization = {
            splitChunks: {
                cacheGroups: {
                    /* 将node_modules下依赖包单独打包 */
                    vendors: {
                        name: "chunk-vendors",
                        test: /[\\/]node_modules[\\/]/,
                        priority: -10,
                        chunks: "initial",
                    },
                    common: {
                    /* 将复用两次以上的方法单独打包 */
                        name: "chunk-common",
                        minChunks: 2,
                        priority: -20,
                        chunks: "initial",
                        reuseExistingChunk: true,
                    },
                    /* 将vant 单独打包 */
                    vant: {
                        chunks: "all",
                        name: `vant`,
                        test: /[\\/]vant[\\/]/,
                        priority: 0,
                    },
                },
            },
        };
    },
};

使用 SplitChunks 插件来剥离公共代码块单独打包有利有弊,好处在于,防止模块被重复打包,拆分过大的 js 文件,合并零散的 js 文件。缺点即为剥离越彻底,打包后的文件越多,增加浏览器的请求次数,故要以项目实际的情况去使用 SplitChunks 插件,需切记中庸之道。

参考文献:webpack 之 SplitChunks 插件用法详解


懒加载

es6 草案中的语法,jsonp 实现动态加载文件。如 vue 路由懒加载,react 懒加载都是采用的这种方式。

/* 主要代码 */
/* source.js */
export default "我是资源文件";

/* index.js */
import("./source.js").then((data) => {
    console.log(data.default);
});

热更新 HRM

webpack5 默认支持 HRM

在开发环境,可以将 HMR 作为 LiveReload 的替代。webpack-dev-server 支持 hot 模式,在试图重新加载整个页面之前,hot 模式会尝试使用 HMR 来更新。

MIT License Copyright (c) 2021 pipe Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

webpack 优化项 展开 收起
JavaScript 等 3 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/pipepandafeng/webpack_opt.git
git@gitee.com:pipepandafeng/webpack_opt.git
pipepandafeng
webpack_opt
webpack_opt
master

搜索帮助