Webpack构建工具

发布于:2025-07-05 ⋅ 阅读:(19) ⋅ 点赞:(0)

构建工具系列

跟着B站视频30 分钟掌握 Webpack写的
代码:项目地址

前言

Webpack 是一个现代 JavaScript 应用的静态模块打包工具。它将项目中的各类资源(如 JavaScript、CSS、图片等)视为模块,通过依赖关系分析生成优化后的静态资源。

一、安装

  1. 通过 npm 安装相关插件:
    mkdir pkdemo
    cd pkdemo
    npm init -y
    npm i webpack webpack-cli -D
    npm i html-webpack-plugin -D
    npm i babel-loader @babel/core @babel/preset-env -D
    npm i terser-webpack-plugin -D
    npm i webpack-dev-server -D
    npm i webpack-bundle-analyzer -D
    code .
    
  1. npm init -y 是一个快速初始化 Node.js 项目的命令,它跳过交互式问答环节,直接生成默认的 package.json 文件。 -y 或 --yes 参数表示使用默认配置,无需手动输入信息。默认值包括项目名(基于当前目录)、版本号(1.0.0)、描述等字段。
  2. webpack 是模块打包工具,用于处理 JavaScript 和其他静态资源
  3. webpack-cli 是 Webpack 的命令行工具,提供命令行交互和配置支持。
  4. –save-dev(或 -D 简写)表示将安装的包记录在 devDependencies 中,即这些包仅在开发阶段需要,不会包含在生产环境中。
  5. html-webpack-plugin一个常用的插件,用于简化 HTML 文件的创建和管理。它能够自动生成 HTML 文件,并自动注入打包后的 JavaScript 和 CSS 资源。
  6. babel-loader将现代 JavaScript 代码(如 ES6+、TypeScript 或 JSX)转换为向后兼容的版本,确保代码能在旧版浏览器或环境中运行。babel-loader 依赖于 Babel 核心工具链(@babel/core)和配置的预设(presets)或插件(plugins)来完成转译任务。
  7. @babel/core负责解析源代码、应用插件或预设的转换规则,并生成目标代码,是整个 Babel 生态系统的引擎
  8. @babel/preset-env 是一个智能预设,根据目标浏览器或环境自动确定需要的 Babel 插件和 polyfill。它通过分析项目的 browserslist 配置或手动指定的目标环境,仅转换必要的语法特性,避免不必要的代码转换。例如:
    - 如果目标环境支持箭头函数,@babel/preset-env 会跳过箭头函数的转换。
    - 如果目标环境缺乏 Promise,它会自动引入相关 polyfill(需配合 core-js 使用)。
  9. terser-webpack-plugin用于通过 Terser 工具压缩 JavaScript 代码
  10. webpack-dev-server一个基于 Express 的本地开发服务器,专为 webpack 项目提供实时重新加载(Live Reloading)和模块热替换(HMR)功能。它通过内存编译文件,避免写入磁盘,从而提升开发效率。配置完成,初次打包后将自动打开浏览器并加载页面,且更改代码后将自动更新页面
  11. webpack-bundle-analyzer 是一个可视化工具,用于分析 Webpack 构建生成的 bundle 文件。它帮助开发者理解打包后的文件结构、大小及其依赖关系,从而优化性能。配置后打包得时候会自动显示一个可视化页面,从里面可以看到各文件大小
    可视化分析 bundle 组成
    通过交互式树状图或矩形图展示 bundle 中每个模块的大小及其占比,直观呈现哪些模块占用了最多空间。开发者可以快速定位体积过大的模块。
    识别冗余或重复依赖
    工具会高亮显示重复或未被使用的依赖项,帮助开发者发现代码分割或 Tree Shaking 未优化的部分,减少不必要的代码打包。
    优化代码分割策略
    分析结果可用于调整 Webpack 的 SplitChunks 配置,合理拆分公共代码或第三方库,避免单个 bundle 过大影响加载速度。
    对比不同构建版本
    支持与历史构建结果对比,观察优化前后的 bundle 变化,验证配置调整是否有效。例如检查是否成功压缩了特定依赖的体积。
    辅助长期性能监控
    整合到持续集成流程中,定期生成分析报告,监控项目体积的增长趋势,防止因新增依赖导致性能退化。
  12. code . 打开VScodde

在这里插入图片描述

打包

在项目根目录新建一个index.html文件。输入英文状态下的!或者输入html:5并回车即可自动创建一个HTML模板。
新建src\index.js
在插件市场安装Live Server,可帮我们运行html页面,在html页面右键选择open in the Liver Server即可(安装目的:查看html页面编写是否有问题)。

在这里插入图片描述
运行打包指令:

npx webpack

在根目录出现一个dist文件夹即打包成功。
在这里插入图片描述

配置webpack

在项目根目录新建webpack.config.js文件,并在其中进行信息配置。

// 导入path插件
const path = require('path');
//导入静态页面生成插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
//导入压缩插件
const TerserPlugin = require('terser-webpack-plugin');
//导入打包分析插件
const BundleWebpackPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;    
/* 
* model.exports:nodejs模块导出对象 
* mode 开发模式或生产模式 
* entry 用于指定打包的入口文件。webpack会从这些入口文件开始,构建内部依赖图,并打包所有依赖模块
* output 用于指定打包后的文件输出位置、文件名格式以及其他相关设置  
* module指的是项目中可被分割的最小功能单位。每个文件(如JavaScript、CSS、图片等)都被视为一个module.
* webpack通过分析这些module之间的依赖关系,构建依赖图(Dependency Graph),最终打包成浏览器可识别的静态资源
*/
module.exports = {
    mode: 'development', // 模式, development或production
    //设置此属性是为了方便查看打包后得源代码
    devtool: 'inline-source-map', // 开发环境下使用source-map,生产环境下使用hidden-source-map,eval-source-map
    entry: "./src/index.js",//入口文件
    output: {//输出文件
        path: path.resolve(__dirname ,'dist'), // 指定输出文件的目录,必须为绝对路径
        // filename: "bundle.js"// 定义输出文件的名称。可以使用[name]、[hash]等占位符动态生成文件名
        filename: "[name].[contenthash].js"// [name]会被替换为入口文件的名称,[contenthash]会根据内容生成一个唯一的哈希值,确保文件名在内容变化时也会变化,从而实现缓存优化
    },
    optimization: {
        minimize:true,//是否压缩
        minimizer:[new TerserPlugin()]//使用TerserPlugin压缩
    },
    /* 插件 
    * plugins:[new HtmlWebpackPlugin() ]可自动生成html,可不传参
    */
    plugins:[
        // 自动生成html文件
        new HtmlWebpackPlugin(
            {
                title: 'webpack打包测试',// 定义生成的html文件的标题
                filename: 'testIndex.html',// 定义生成的html文件的名称
                // template: 'src/index.html'// 定义html模板文件路径
            }
        ),
        // 打包分析插件
        new BundleWebpackPlugin({})
    ],
    module:{        
        rules: [
        //匹配css的规则
        {
            //用于匹配以 .css 结尾的字符串,且匹配时不区分大小写
            test: /\.css$/i,//\.转义'.' ,$匹配字符串的结尾,i 修饰符表示不区分大小写的匹配
            /*
            *用于指定处理特定文件类型时使用的 loader。
            *它是一个数组,可以包含多个 loader,webpack 会从右到左(或从下到上)依次应用这些 loader。
            */
            use: ['style-loader', 'css-loader']// 使用的loader,Loader 从右向左执行,例如 use: ['style-loader', 'css-loader'] 中先执行 css-loader。
        },
        //匹配图片的规则
        {
            test:/\.(png|jpg|jpeg|png|gif|svg)$/i,
            type: 'asset/resource', // 使用资源模块处理图片文件,将文件直接输出到输出目录并返回最终的 URL
        },
        //匹配js的规则
        { 
            test: /\.js$/, // 匹配所有以 .js 结尾的文件
            exclude: /node_modules/, // 排除 node_modules 目录下的文件
            use: {
                loader: 'babel-loader', // 使用 babel-loader 处理 JavaScript 文件
                options: {
                    presets: ['@babel/preset-env'] // 使用 @babel/preset-env 预设
                }
            }
        }
    ]},
    // 开发环境下使用 webpack-dev-server 开启热更新,还需要再去package.json中配置相关命令:scripts中添加“"start": "webpack serve --open"”
    devServer:{
        // 静态资源目录
        static: "./dist"
    },
    resolve:{
        alias: {
            // 设置别名,方便在代码中引用
            '@': path.resolve(__dirname, 'src'),
            '@utils': path.resolve(__dirname, 'src/utils'),
            '@assets': path.resolve(__dirname, 'src/assets')
        },
    }
    // EntryOptionPlugin
}

安装样式加载器

在Webpack或Vite等构建工具中配置样式加载器后方可编译样式文件。

npm i style-loader css-loader -D

devtool

devtool 是 webpack 配置中用于控制生成 source map 方式的选项,主要用于调试代码。source map 可以映射编译后的代码回源文件,方便定位问题。

webpack devtool 配置详解

devtool 是 webpack 配置中用于控制生成 source map 方式的选项,主要用于调试代码。source map 可以映射编译后的代码回源文件,方便定位问题。

常见 devtool 值及适用场景

eval

  • 使用 eval 包裹模块代码,生成速度最快
  • 只能映射到转换后的代码,无法映射到源文件
  • 适用于开发环境快速构建
module.exports = {
  devtool: 'eval'
}

eval-source-map

  • 每个模块使用 eval 执行
  • 生成完整的 source map 并作为 DataUrl 嵌入
  • 构建速度较慢但质量高
  • 适用于开发环境需要精确源映射

cheap-eval-source-map

  • 类似 eval-source-map 但只映射行号
  • 不映射列信息,构建速度更快
  • 适用于开发环境折中方案

cheap-module-eval-source-map

  • 类似 cheap-eval-source-map
  • 但会映射 loader 转换前的源代码
  • 推荐用于开发环境

source-map

  • 生成完整独立的 source map 文件
  • 质量最高但构建速度最慢
  • 适用于生产环境调试
module.exports = {
  devtool: 'source-map'
}

hidden-source-map

  • 生成 source map 但不添加引用注释
  • 需要手动处理 source map 文件
  • 适用于生产环境但不想暴露源文件

nosources-source-map

  • 生成 source map 但不包含源代码
  • 只能看到错误堆栈但无法查看代码
  • 适用于生产环境部分保护源代码

选择建议

开发环境推荐:

  • eval-source-mapcheap-module-eval-source-map

生产环境推荐:

  • source-maphidden-source-map

性能考虑:

  • eval 的选项构建更快
  • module 的选项能映射 loader 前代码
  • cheap 的选项忽略列映射

性能影响

不同 devtool 设置对构建和重建速度有显著影响。质量越高的 source map 生成时间越长。开发环境下需要在质量和速度间取得平衡。

// 开发环境推荐配置
module.exports = {
  devtool: 'cheap-module-eval-source-map',
  // 其他配置...
}

// 生产环境推荐配置
module.exports = {
  devtool: 'source-map',
  // 其他配置...
}

注意事项

  • 生产环境如需 source map 应考虑安全性
  • 某些设置可能导致源文件暴露
  • 大型项目应测试不同设置的构建速度
  • 现代浏览器开发工具已很好支持各种 source map

module

在webpack中,module指的是项目中可被分割的最小功能单位。每个文件(如JavaScript、CSS、图片等)都被视为一个module,webpack通过分析这些module之间的依赖关系,构建依赖图(Dependency Graph),最终打包成浏览器可识别的静态资源。

module的类型
webpack支持多种类型的module,常见的有:

  • JavaScript模块:通过import或require导入的JS文件。
  • CSS模块:通过css-loader处理的样式文件。
  • 图片/字体资源:通过file-loader或url-loader处理的静态资源。
  • 第三方库:如lodash、jQuery等通过npm安装的依赖。

处理流程

module的处理流程

  • 解析路径:webpack根据配置的resolve规则解析模块路径。
  • 匹配规则:通过test正则匹配文件类型,调用对应的loader处理。
  • 依赖分析:处理过程中发现新的依赖(如import语句),递归处理。
  • 打包输出:最终将所有module合并为bundle文件。

module.rules

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
};

module.use

用于指定处理特定文件类型时使用的 loader。它是一个数组,可以包含多个 loader,webpack 会从右到左(或从下到上)依次应用这些 loader。
常见loader的作用

  • babel-loader:将ES6+代码转换为ES5。
  • css-loader:解析CSS文件中的@import和url()。
  • style-loader:将CSS注入到DOM中。
  • file-loader:将文件输出到指定目录并返回URL。

注意事项

  1. loader 的执行顺序是从右到左(或从下到上),第一个 loader 会将结果传递给下一个 loader
  2. 对于需要选项的 loader,建议使用对象形式配置
  3. 复杂的 loader 链可以拆分成多个规则
  4. 在生产环境中,可能需要使用 MiniCssExtractPlugin.loader 替代 style-loader

module.type

module.type 用于定义模块的处理方式。

  • asset/resource:专门用于处理文件资源(如图片、字体等),它会将文件直接输出到输出目录并返回最终的 URL。适用于需要直接引用文件路径而非文件内容的场景,例如:
    • 图片文件(.png, .jpg, .svg)
    • 字体文件(.woff, .ttf)
    • 其他静态资源
  • asset/inline:将文件内容作为 Data URL 嵌入(适用于小文件)。
  • asset/source:将文件内容作为字符串返回(适用于文本文件)。
  • asset:自动选择 resource 或 inline(默认阈值 8KB)。