Webapck系列-初识Webpack

当前端项目从编写几个简单的HTMLCSSJS文件,过渡到开发需要成千上百个模块、依赖各种第三方库、甚至需要处理lessTypeScript图片等资源的项目时,随之而来的问题和麻烦接踵而至:如何组织文件浏览器不识别的语法如何处理以及如何高效加载文件等等。

Webpack正是在这样的背景下诞生的。它不仅前端开发的基础工具,更是打通开发便捷性生产性能的关键桥梁。无论你是前端的小白,还是想夯实工程化基础的进阶者,理解Webpack的工作逻辑和使用方法,都让你在项目少走弯路,更好的应对其复杂场景。

接下来,让我们从Webpack是什么开始,一步一步揭开其神秘面纱,从原理到基础实战,彻底搞懂这个前端工程化工具。

Webpack是什么

Webpack是一个静态模块打包工具 。它视所有文件为模块(JS、sass/less、图片、字体、TS),通过分析它们之间的依赖关系,最终打包成浏览器能直接识别的静态资源(JS或CSS等文件)。

可以将Webpack理解成为工厂:原料是项目中各种文件(js、css、less、ts等),按照依赖关系和特定规则处理它们,最后生成浏览器可以识别的产品(bundle文件)。

Webpack底层原理

Webpack的核心工作简单地说:从入口文件,递归解析所有依赖,处理后打包成输出文件。一步一步了解它的构建过程。

1. 确定规则

Webpack运行构建时,会默认读取项目根目录下webpack.config.js文件或读取命令行--config后的参数的配置文件。有如下核心配置:

  • 入口(entry):定义从哪个文件开始解析依赖
  • 出口(output):确定打包后文件名称和放入位置
  • 解释器(loader) :由于Webpack只能识别JS和JSON文件,webpack通过配置loader,将非JS文件转化为JS模块
  • 插件(plugin):在Webpack的构建的生命周期中额外处理。如自动生成HTML,压缩代码等等。

2, 编译阶段

这是Webpack最为核心的阶段。分为构建依赖图模块转换

  • 构建依赖图 Webpack会从webpack.config.js配置文件中的entry定义的入口文件地址开始,一层层地解析文件。
    • 先读取入口文件的内容,分析出依赖了哪些文件。
    • 递归解析被依赖的文件,直到所有关联的文件都被找到
    • 最后形成一张Graph,记录了所有文件的路径、内容以及它们之间的依赖关系

举个例子 :如果 index.js 依赖 a.jsa.js 依赖 b.cssc.png,依赖图就会清晰记录这层关系。

js 复制代码
// 构建类似如下伪代码
{
    "./src/index.js": () => {
     // 加载a.js    
    },
    "./src/a.js": () => {
     // 加载b.css和c.png   
    },
    "./src/b.css": () => { // 读取文件},
    "./src/c.png": () => { // 读取图片}
}
  • 模块转换

Wepack本身只能识别JS和JSON文件,如遇到其他文件就需要Loader进行翻译

  • loader的作用是转换:将非JS文件转换为JS模块
  • 处理顺序是从右到左从下往上
js 复制代码
{
    test: /.css$/,
    // 从右到左 依次执行
    use: ['style-loader', 'css-loader'],
    // use: [
    // 'style-loader',
    // 'css-loader'
    //]
},
  • 插件介入

    在编译的各个环节,插件都可以介入进行处理。

  • 插件是 "扩展器":可以做 loader 做不到的事情,比如自动生成 HTML 文件(HtmlWebpackPlugin)、压缩代码(TerserPlugin)、清除旧文件(CleanWebpackPlugin)等。

  • 插件基于 "事件钩子" 工作:Webpack 在打包过程中会触发很多事件(比如 beforeCompileafterCompile),插件可以监听这些事件,在特定时机执行逻辑。

Webpack基础使用

在使用Webpack之前,确保项目安装Webpack

bash 复制代码
npm init -y // 初始化项目
npm i webpack webpack-cli -D // 开发依赖下安装webapck

指定入口

入口用于告诉Webpack从哪个文件开始解析依赖。

js 复制代码
module.exports = {
  entry: "./src/index.js" // 单入口文件
  /* 适合多页面应用
  entry: {
    index: "./src/index.js",
    print: "./src/print.js"
  }
  */
}

指定出口

js 复制代码
const path = require("path");
module.exports = {
 entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    // 多入口时: filename: '[name].bundle.js'
    path: path.resolve(__dirname, "dist"),
    clean: true, // 清理dist目录
  },
}

加载资源

Webpack处理非JS文件需要在module.rules配置,通过test匹配文件类型,用use指定对应的loader

1. 处理CSS文件

需要借助css-loader转换CSS文件变为JS模块;style-loader将CSS插入到页面的style标签

  1. 安装loader
bash 复制代码
npm i css-loader style-loader -D # 开发依赖
  1. 配置
js 复制代码
module.exports = {
  module: {
   rules: [
     {
       test: /\.css$/,
       // loader 执行顺序:从右到左(先 css-loader 再 style-loader)
       use:["style-loader", 'css-loader']
     }
   ]
  }
}

如果使用sass还需要sass-loadersass

bash 复制代码
npm i sass sass-loader -D
js 复制代码
{
  test: "/\.scss$/",
  use: ["style-loader", "css-loader", "scss-loader"]
}

如果使用less还需要less-loaderless

bash 复制代码
npm i less less-loader -D
js 复制代码
{
  test: "/\.less$/",
  use: ["style-loader", "css-loader", "less-loader"]
}

2. 处理图片/字体

Webpack5内置通过Rule.type处理字体和图片,无需额外配置loader。Rule.type的值如下:

  • asset/resource 将资源作为单独文件输出,并返回URL
  • asset/inline 将文件作为Data URL内联到bundle中
  • asset/source 将文件作为原始源码导入
  • asset 根据配置决定是inline还是resource
js 复制代码
module.exports = {
  module: {
    rules: [
      test: /\.(png|jpg|gif|svg)$/,
      type: 'asset',
      parser: {
        dataUrlCondition: {
          maxSize: 8 * 1024 // 8kb
        }
      }
    ]
  }
}

开发模式

开发时需要方便调试和自动刷新,以便提高开发效率。

1. 基础开发配置

js 复制代码
module.exports = {
  mode: 'development', // 定义为开发模式
  devtool: 'inline-source-map' // 生成source-map 方便调试
}

2. 开发服务器

webpack-dev-server提供热更新(修改代码后自动刷新页面),无需手动重新打包:

bash 复制代码
npm i webpack-dev-server -D

配置

js 复制代码
module.exports = {
  devServer: {
    static: './dist', // 服务器根目录
    port:  3000, // 服务器端口号
    open: true, // 启动服务后自动打开浏览器
    hot: true // 开启热模块替换 修改代码后自动刷新页面
  }
}

package.jsonscripts字段中配置运行指令

json 复制代码
{
  "scripts": {
    "dev": "webpack serve" // 启动开发服务器
  }
}

🎯 本文小结

💡 核心要点回顾

Webpack 的本质:静态模块打包工具,将各种资源转化为浏览器可识别的静态文件

四大核心概念

  • 入口(Entry) :构建起点
  • 出口(Output) :打包结果位置
  • 加载器(Loader) :非JS文件转换器
  • 插件(Plugin) :构建过程扩展器

构建两大阶段

  1. 依赖图构建:从入口开始,递归分析模块依赖关系
  2. 模块转换:通过Loader将各类资源转为JS模块

开发效率提升

  • webpack-dev-server提供热更新
  • mode: 'development'优化开发体验
相关推荐
慧一居士3 小时前
HTML5 功能介绍,使用场景,对应功能点完整使用示例
前端
海在掘金611273 小时前
告别“undefined is not a function”:TS如何让你的函数调用更安心
前端
云中雾丽3 小时前
Flutter中Stream的各种使用场景和实现方式
前端
CptW3 小时前
第1篇(Ref):搞定 Vue3 Reactivity 响应式源码
前端·面试
葡萄城技术团队3 小时前
基于 SpreadJS 的百万级数据在线数据透视表解决方案:技术解析与实践
前端
爱隐身的官人3 小时前
XSS平台xssplatform搭建
前端·xss
jiangzhihao05153 小时前
升级到webpack5
前端·javascript·vue.js
哆啦A梦15883 小时前
36 注册
前端·javascript·html
华仔啊3 小时前
面试官:说说async/await?我差点翻车!原来还可以这么用
前端