了解webpack的打包流程、步骤和生命周期,加深对项目打包的理解,便于性能优化

        webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。

        通俗的讲:相当于将你写的代码编译成浏览器所能解析的代码,处理资源之间的关系,再将代码压缩打包减小体积再运行)

一、webpack.config.js 文件基本配置

webpack 默认只会处理和压缩 js 文件,需解析其他文件的话就要在module配置项里配置loader

注意:文件中所用到的依赖包: webpack 和 webpack-cli 是基础的,其他依赖根据文件中所用自行下载

npm i -D webpack webpack-cli
const path = require('path')
// 语法检查插件
const ESLintPlugin = require('eslint-webpack-plugin')
// 打包输出html文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 将css代码提取成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css文件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
// 压缩静态图片
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin")


module.exports = {
    // 入口文件配置项
    entry: "./src/main.js",
    // 打包输出配置项
    output: {
        path: path.resolve(__dirname,"../dist"),
        filename: "static/js/[name].js",
        // 给打包输出的其他文件命名(动态引入文件等),加 .chunk 以区别主文件
        chunkFilename: "static/js/[name].chunk.[contenthash:10].js",
        // 图片、字体等资源打包后,统一通过type:asset 处理资源命名方式命名
        assetModuleFilename: "static/media/[hash:10][ext][query]",
        // 清除输出目录中上一次打包的资源
        clean: true,
    },
    // 解析各模块的loader配置项
    module: {
        rules: [
            // 解析css类文件 
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"]
            },
            // 解析图片类文件
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: "asset"
            },
            // 解析字体图标或音视频类文件
            {
                test: /\.(ttf|woff2?|map3|map4|avi)$/,
                type: "asset/resource"  
            },
            // 解析js文件的 es6+ 的语法,需另外配置一个 babel.config.js 文件
            {
                test: /\.js$/,
                // 排除哪些文件不编译
                exclude: /node_modules/,
                use: ["babel-loader"],
            }
        ],
    },
    // 插件配置项
    plugins: [
        // 对文件代码进行语法检查,需另外配置一个 eslint.config.js 文件
        new ESLintPlugin({
            // 检查些文件
            context: path.resolve(__dirname,"../src"),
            // 用exclude排除不需要处理的文件,默认开启
            exclude: "node_modules",
        }),
        // 将html文件一起打包到输出目录,并自动引入所需资源
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "../public/index.html")
        }),
        // 提取css代码提取为单独文件
        new MiniCssExtractPlugin({
            // 文件名
            filename: "static/css/[name].css",
            // 动态引入时的文件名
            chunkFilename: "static/css/[name].chunk.css"
        }),
    ],

    // 优化操作配置项
    optimization: {
        // 用于存放用于压缩的插件
        minimizer: [
            // 压缩css文件
            new CssMinimizerPlugin(),
            // 压缩静态图片
            new ImageMinimizerPlugin({
                // 压缩配置,复制即可无需记
                minimizer: {
                    implementation: ImageMinimizerPlugin.imageminGenerate,
                    // 这里采用无损压缩
                    options: {
                        plugins: [
                            ["gifsicle",{interlaced: true}],
                            ["jpegtran",{progressive:true}],
                            ["optipng",{optimizationLevel: 5}],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    }
                }
            }),
        ],
        // 分割代码配置
        splitChunks: {
            // 对所有资源,符合条件的将会被分割为独立文件
            chunks: "all",
        },
    },
    // 打包模式配置项,这里是生产模式
    mode: "production"
}

二、核心生命周期阶段

Webpack 的构建流程可划分为以下主要阶段:

1. 初始化阶段

  1. 读取配置文件:执行打包命令后(例如:npm run build),首先加载你项目根目录中的 webpack.config.js 文件 或 命令行参数(例如:npx webpack --config ./config/webpack.prod.js),解析文件里的配置象

  2. 创建 Compiler 实例:初始化核心对象,管理整个构建过程(后续的打包流程都是再compiler对象中实现)

  3. 加载插件:先执行所有插件的 constructor(option) 方法,再依次执行所有插件的 apply(compiler) 方法,注册生命周期钩子

  4. 注册 ModuleFactory 和 Resolver:准备模块解析和构建的基础设施(准备打包所需要的依赖)

2. 编译阶段

  1. 触发 Compile 钩子:标识编译开始(所有文件的编译打包都在compiler对象中完成)

  2. 创建 Compilation 对象:负责单次构建的上下文,存储模块和资源信息(负责一种资源单次的编译和打包过程)

  3. 解析入口文件:通过 entry 配置找到入口模块(意思是从哪个文件开始编译)

  4. 构建模块依赖图递归分析所有依赖关系(根据入口文件内对其他文件和资源的引用的关系形成树图)

3. 模块构建阶段(在compilation对象中进行)

  1. 加载模块内容:通过 resolve 找到文件路径

  2. 执行 Loader 链:按 从后往前 顺序应用 Loaders(例如 ['sass-loader', 'css-loader', 'style-loader']

  3. 收集依赖:识别 require/import 语句,递归处理子模块

4. 优化阶段(在compilation对象中进行)

  1. 触发 make 钩子:完成所有模块构建后

  2. 执行 SplitChunks 优化:代码分割(若配置)

  3. Tree Shaking:移除未使用代码(用 es 语法引入的模块才会移除,例如一个模块中定义了多个方法默认暴露了出去,但是父模块只导入其中一个方法,那其他方法的代码不会被打包)

  4. 应用插件优化:如 TerserPlugin 压缩代码,MiniCssExtractPlugin 提取 CSS(若配置)

5. 生成资源阶段(所有资源文件编译、解析完后)

  1. 触发 emit 钩子:生成最终资源前最后修改机会

  2. 创建 Chunk:根据入口和动态导入生成输出块 对应 初始化的chunk延迟加载的chunk

  3. 生成最终文件:根据 output 配置生成 bundle.js 等文件(根据 output配置项 中定义的文件名,给打包后的资源命名)

  4. 写入文件系统:将资源输出到 dist 目录(打包到 output配置项 指定的目录)

6. 收尾阶段

  1. 触发 done 钩子:构建完成

  2. 统计信息输出:显示构建时间和资源大小

  3. 监听模式(Watch Mode):持续监听文件变化,准备重新构建(开发模式下)

三、compiler和compilation中的关键钩子(hook)

compiler对象相当于编译器,webpack会将所有资源文件和环境都放入compiler对象中,而compilation对象就相当于编译器中负责编译资源文件的工具

以下黄色部分compilation对象中的关键钩子其他为compiler对象的关键钩子,他们的钩子都存在各自对象的hooks属性中,例如:compiler.hooks.run ;compilatioin.hooks.buildModule 。

钩子名称触发时机典型用途
initializecompiler对象初始化后检查运行环境
beforeRun构建开始前清理旧构建结果
run构建开始记录构建启动时间
compileCompilation对象创建前初始化编译环境(loader等)
compilationCompilation对象创建后注册编译器的插件
make开始分析入口文件自定义模块处理
buildModule单个模块构建前修改模块源码
succeedModule单个模块构建完成模块级缓存处理
finishModules所有模块构建完成提交优化任务
optimize开始优化阶段代码压缩、Tree Shaking
afterCompileCompilation对象编译资源全部结束后分析模块大小、数量,设置缓存
emit打包资源到输出目录前添加自定义文件
afterEmit打包资源到输出目录后清理临时文件
done构建完成输出统计信息
failed构建失败错误处理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值