webpack loader全解析,从入门到精通(10)

webpack 的核心功能是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。更多复杂的功能需要借助 webpack loaders 和 plugins 来完成。

1. 什么是 Loader

Loader 本质上是一个函数,它的作用是将某个源码字符串转换成另一个源码字符串返回。Loader 在模块解析的过程中被调用,以得到最终的源码。

2. Loader 的工作流程

全流程

  1. 初始化:webpack 读取配置文件,解析入口模块。
  2. 编译
    • 创建 chunk:根据入口模块创建 chunk。
    • 解析模块:解析每个模块的依赖关系。
    • 应用 loader:根据配置的 loader 对模块进行转换。
  3. 输出 :将编译后的资源输出到指定的文件中。

Chunk 中解析模块的流程

  1. 读取模块内容:读取模块的源代码。
  2. 解析依赖:解析模块中的依赖关系。
  3. 生成 AST:生成抽象语法树(AST)。
  4. 生成模块代码:根据 AST 生成最终的模块代码。
更详细的流程
  1. 读取模块内容:读取模块的源代码。
  2. 解析依赖:解析模块中的依赖关系。
  3. 应用 loader
    • 从右到左:多个 loader 会从右到左依次执行。
    • 链式调用:每个 loader 的输出作为下一个 loader 的输入。
  4. 生成 AST:生成抽象语法树(AST)。
  5. 生成模块代码:根据 AST 生成最终的模块代码。

处理 loaders 的流程

  1. 当前模块是否满足某个规则?

    • 如果当前模块满足某个规则,则继续下一步。
    • 如果不满足,则跳过所有 loader,直接进入下一个模块。
  2. 读取规则中对应的 loaders

    • 根据当前模块所满足的规则,找到相应的 loader 列表。
  3. 加载 loaders 数组

    • 将找到的所有 loader 放入一个数组中。
  4. 处理 loader 流程

    • 从右到左依次执行每个 loader。
      • 第一个 loader 接收原始代码作为输入。
      • 每个 loader 执行完后,将其结果作为下一个 loader 的输入。
      • 最终的结果就是经过所有 loader 处理后的源码。

    总的来说,当一个模块满足特定规则时,webpack 会按照配置好的顺序,从右到左依次应用每个 loader,直到获得最终的源码。如果模块不满足任何规则,则不会应用任何 loader。这种机制允许开发者灵活地定义不同类型的文件应该如何被处理。

3. Loader 配置

完整配置

javascript 复制代码
module.exports = {
  module: { // 针对模块的配置,目前版本只有两个配置,rules、noParse
    rules: [ // 模块匹配规则,可以存在多个规则
      { // 每个规则是一个对象
        test: /\.js$/, // 匹配的模块正则
        use: [ // 匹配到后应用的规则模块
          {  // 其中一个规则
            loader: "模块路径", // loader 模块的路径,该字符串会被放置到 require 中
            options: { // 向对应 loader 传递的额外参数
              // 配置选项
            }
          }
        ]
      }
    ]
  }
};

简化配置

javascript 复制代码
module.exports = {
  module: { // 针对模块的配置,目前版本只有两个配置,rules、noParse
    rules: [ // 模块匹配规则,可以存在多个规则
      { // 每个规则是一个对象
        test: /\.js$/, // 匹配的模块正则
        use: ["模块路径1", "模块路径2"] // loader 模块的路径,该字符串会被放置到 require 中
      }
    ]
  }
};

4. 常见的 Loader

  • babel-loader:将 ES6+ 代码转换为 ES5 代码。
  • css-loader :解析 CSS 文件中的 @importurl() 语句。
  • style-loader:将 CSS 插入到 DOM 中。
  • file-loader:将文件输出到指定目录,并返回文件的 URL。
  • url-loader :类似于 file-loader,但可以将小文件转为 Data URL。
  • less-loader:将 Less 文件编译为 CSS。
  • sass-loader:将 Sass/SCSS 文件编译为 CSS。
  • ts-loader:将 TypeScript 文件编译为 JavaScript。

5. 示例

假设我们有一个项目,需要使用 babel-loader 来转换 ES6 代码,使用 css-loaderstyle-loader 来处理 CSS 文件。

项目结构
复制代码
my-project/
├── src/
│   ├── index.js
│   ├── styles.css
├── dist/
├── package.json
└── webpack.config.js
webpack.config.js
javascript 复制代码
const path = require('path');

module.exports = {
  mode: 'development', // 或 'production'
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
};
安装依赖
bash 复制代码
npm install --save-dev webpack webpack-cli babel-loader @babel/core @babel/preset-env css-loader style-loader
运行构建

package.json 中添加一个 build 脚本:

json 复制代码
{
  "scripts": {
    "build": "webpack"
  }
}

然后运行:

bash 复制代码
npm run build

构建完成后,dist 目录下会生成 bundle.js 文件,你可以在 HTML 文件中引入这个文件:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Webpack Project</title>
</head>
<body>
  <script src="dist/bundle.js"></script>
</body>
</html>

总结

通过本课程,你已经了解了 webpack 中 loader 的概念、工作流程以及如何配置 loader。合理使用 loader 可以帮助你处理各种类型的文件,提高项目的可维护性和灵活性。

相关推荐
Ticnix23 分钟前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人26 分钟前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl30 分钟前
OpenClaw 深度技术解析
前端
崔庆才丨静觅33 分钟前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人41 分钟前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼44 分钟前
shadcn/ui,给你一个真正可控的UI组件库
前端
布列瑟农的星空1 小时前
前端都能看懂的Rust入门教程(三)——控制流语句
前端·后端·rust
Mr Xu_1 小时前
Vue 3 中计算属性的最佳实践:提升可读性、可维护性与性能
前端·javascript
jerrywus1 小时前
我写了个 Claude Code Skill,再也不用手动切图传 COS 了
前端·agent·claude
玖月晴空1 小时前
探索关于Spec 和Skills 的一些实战运用-Kiro篇
前端·aigc·代码规范