资讯专栏INFORMATION COLUMN

Loader 入门【Webpack Book 翻译】

yeyan1996 / 678人阅读

摘要:把他设置为以在其他之前或之后进行处理。基于布尔值的字段可用于进一步进行约束不匹配给定条件参见表示接受的值。同时匹配一系列条件。将此添加到你的配置即可检查其中的数据流,而不必在中插入。

原文链接:https://survivejs.com/webpack...
翻译计划:https://segmentfault.com/a/11...

附言:因为发现书中一些内容多带带放出来会比较尴尬,所以会跳过部分章节,当然完整版会全部翻译,已经正在研究原版的网站搭建工程了

Webpack 提供了多种配置模块 loader 的方法。 Webpack 2 开始通过引入 use 字段,简化了 loader 使用。在这里使用绝对路径是一个好主意,因为它们允许你在不影响构建的情况下移动配置。

另一种方法是设置 context 字段,因为这会产生类似的效果并影响 entry 和 loader 的路径解析。但是它对输出没有影响,你仍然需要使用绝对路径或 /

即使你设置了 includeexclude 规则,从 node_modules 加载的包仍然可以正常工作,因为它们已经被编译为开箱即用的代码。如果它们没这么做,那么你必须应用 Consuming Packages 章节中涵盖的技术。

T> include/exclude 在处理 node_modules 问题时非常方便,因为当你将 JavaScript 文件导入项目时,webpack 会默认处理并遍历已安装的包。为了让 webpack 不处理 node_modules,你需要使用 exclude。其他文件类型不会遇到此问题。

剖析 Loader

Webpack 通过 loader 支持多种格式的文件。此外,它支持一些开箱即用的 JavaScript 模块规范。文件格式不同,但思路都是一致的,你必须设置一个或多个 loader,并将它们与你的目录结构连接起来。

{pagebreak}

下例中 webpack 通过 Babel 处理 JavaScript:

webpack.config.js

module.exports = {
  ...
  module: {
    rules: [
      {
        // **Conditions** to match files using RegExp, function.
        test: /.js$/,

        // **Restrictions**
        // Restrict matching to a directory. This
        // also accepts an array of paths or a function.
        // The same applies to `exclude`.
        include: path.join(__dirname, "app"),
        exclude(path) {
          // You can perform more complicated checks  as well.
          return path.match(/node_modules/);
        },

        // **Actions** to apply loaders to the matched files.
        use: "babel-loader",
      },
    ],
  },
};

T> 如果你对 RegExp 的匹配不熟悉,可以使用在线工具,例如 regex101,RegExr 或 Regexper。

Loader 的运算顺序

一定要记住 loader 总是从右到左,从下到上(拆开写的时候)进行运算的。把它看成函数比较容易理解所谓“从右到左运行”。你可以把 use: ["style-loader", "css-loader"] 看作 style(css(input))

要查看规则,请看以下示例:

{
  test: /.css$/,
  use: ["style-loader", "css-loader"],
},

根据从右到左的规则,可以等效拆分为:

{
  test: /.css$/,
  use: "style-loader",
},
{
  test: /.css$/,
  use: "css-loader",
},
强制执行顺序

尽管可以使用上述规则配置,但是也可以强制在常规规则之前之后应用特定规则。enforce 字段在这里可以派上用场。把他设置为 pre or post 以在其他 loader 之前或之后进行处理。

Lint 是一个很好的例子,因为 Lint 必须先于任何其他行为。enforce: "post" 倒是很少用到,这多是你想对构建结果进行检查时使用的。

{pagebreak}

基本语法如下:

{
  // Conditions
  test: /.js$/,
  enforce: "pre", // "post" too

  // Actions
  use: "eslint-loader",
},

如果你可以保证 test 中的 loader 顺序无误,那么可以不使用 enforce。不过使用 enforce 方便你把不同步骤的 loader 分离开来,更容易组织。

Loader 的传参

可通过 query 把参数传到 loader:

{
  // Conditions
  test: /.js$/,
  include: PATHS.app,

  // Actions
  use: "babel-loader?presets[]=env",
},

这种配置风格也适用于 entry 和 import,webpack 会处理他们。在某些个别情况下,这个写法能派上用场,但通常情况下最好使用以下更具可读性的方案。

{pagebreak}

传入对象到 use

{
  // Conditions
  test: /.js$/,
  include: PATHS.app,

  // Actions
  use: {
    loader: "babel-loader",
    options: {
      presets: ["env"],
    },
  },
},

如果你想使用多个 loader,你可以将一个对象数组传递给 use

{
  test: /.js$/,
  include: PATHS.app,

  use: [
    {
      loader: "babel-loader",
      options: {
        presets: ["env"],
      },
    },
    // Add more loaders here
  ],
},

{pagebreak}

使用函数在 use 字段添加分支

本书中,你在更高级别上进行环境配置。实现类似结果的另一个选择是在 use 处使用分支,因为 webpack 的 loader 定义接受函数作为参数,你可以通过此函数区分环境:

{
  test: /.css$/,

  // `resource` refers to the resource path matched.
  // `resourceQuery` contains possible query passed to it
  // `issuer` tells about match context path
  use: ({ resource, resourceQuery, issuer }) => {
    // You have to return something falsy, object, or a
    // string (i.e., "style-loader") from here.
    //
    // Returning an array fails! Nest rules instead.
    if (env === "development") {
      return {
        use: {
          loader: "css-loader", // css-loader first
          rules: [
            "style-loader", // style-loader after
          ],
        },
      };
    }
  },
},

用心感受,这是组合配置的另一种手段。

内联式定义

尽管配置级 loader 定义更可取,但可以内联编写 loader 定义:

// Process foo.png through url-loader and other
// possible matches.
import "url-loader!./foo.png";

// Override possible higher level match completely
import "!!url-loader!./bar.png";

这种方法的问题在你的源代码会与 webpack 耦合。相同的机制还适用于 entry:

{
  entry: {
    app: "babel-loader!./app",
  },
},
匹配文件的备选方法

test 结合 includeexclude 是匹配文件的最常用方法。这些字段接受以下数据类型:

test——匹配 RegExp,字符串,函数,对象或数组。

include——同上。

exclude——同上,输出与 include 相反。

resource: /inline/——匹配包含查询内容的资源路径。示例:/path/foo.inline.js, /path/bar.png?inline

issuer: /bar.js/——匹配从某处请求的资源。示例:如果 /path/foo.png/path/bar.js 请求,那么 /path/foo.png 将匹配。

resourcePath: /inline/——匹配包含查询内容的资源路径(不包括 query)。示例:/path/foo.inline.png

resourceQuery: /inline/——匹配包含查询内容的 query(不包括 query)。示例:/path/foo.png?inline

基于布尔值的字段可用于进一步进行约束:
Boolean based fields can be used to constrain these matchers further:

not——匹配给定条件(参见test表示接受的值)。

and——同时匹配一系列条件。

or——与数组中其中一个条件匹配。

基于 resourceQuery 加载

oneOf 字段可以根据资源相关匹配将 webpack 路由到特定的 loader:

{
  test: /.png$/,
  oneOf: [
    {
      resourceQuery: /inline/,
      use: "url-loader",
    },
    {
      resourceQuery: /external/,
      use: "file-loader",
    },
  ],
},

如果你需要在文件名中查询,应该使用 resourcePath 而不是 resourceQuery

{pagebreak}

基于 issuer 加载

issuer 基于资源的导入位置进行操作。以下示例改编自 css-loader issue 287,style-loader 将应用于 JavaScript 导入的 CSS 文件:

{
  test: /.css$/,

  rules: [
    {
      issuer: /.js$/,
      use: "style-loader",
    },
    {
      use: "css-loader",
    },
  ],
},

另一种方法结合了 issuernot

{
  test: /.css$/,

  rules: [
    // CSS imported from other modules is added to the DOM
    {
      issuer: { not: /.css$/ },
      use: "style-loader",
    },
    // Apply css-loader against CSS imports to return CSS
    {
      use: "css-loader",
    },
  ],
}
了解 loader 行为

通过观察 loader 行为可以更深入地理解它们。 loader-runner 允许你在没有 webpack 的情况下多带带运行它们。Webpack 在底层也是使用此软件包,Extending with Loaders 章节将会详细介绍它。

inspect-loader 可以监视 loader 之间传递的内容。将此 loader 添加到你的配置即可检查其中的数据流,而不必在 node_modules 中插入 console.log

总结

Webpack 提供了多种设置 loader 的方法,但在 webpack 4 中用好 use 就足够了。注意 loader 的处理顺序,这是很多常见的问题来源。

回顾一下:

Loaders 决定了 webpack 的模块解析机制匹配到文件时应该作何处理。

loader 定义包括用于匹配的条件(conditions),以及匹配成功需要进行的动作(actions)

Webpack 2 引入了use字段。它将以前的 loaderloaders 字段结合到了一起。

Webpack 4 提供了多种匹配和改变 loader 行为的方法。例如,你可以在匹配 loader 后进行 resource query 匹配,指引 loader 进行特定操作。

在下一章中,你将学习使用 webpack 加载图片。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108420.html

相关文章

  • 什么是 Webpack?【Webpack Book 翻译

    摘要:资源哈希编码使用可以为每个包的名称注入一个哈希值例如,,以便在版本更新后使客户端上旧版本的包无效重新下载。如此受人喜爱的原因之一是热模块更换。可以为文件名生成哈希值,在内容更改时,可以作废浏览器缓存中上个版本的包。 原文链接:https://survivejs.com/webpack...翻译计划:https://segmentfault.com/a/11... 涉及到的未翻译单词 ...

    tainzhi 评论0 收藏0
  • Webpack2 升级指南和特性摘要

    摘要:名称后自动自动补全的功能将被移除在配置时,官方不再允许省略扩展名,的配置写法上将逐步趋于严谨。使用自定义参数作为配置项传入方式将做调整如果你随意将自定义参数通过传入到配置项中,如你会发现这将不会被允许,的执行将会遵循更为严格的标准。 历时多日,webpack2.2正式版终于赶在年前发布了,此次更新相对于1.X版本有了诸多的升级优化改进,笔者也在第一时间查阅了官方的文档,整理和翻译了由w...

    Forelax 评论0 收藏0
  • webpack入门学习手记(一)

    摘要:争取早日能完全抛弃掉中文文档,最终可以翻译英文文档,输出英文文档。待续相关文章入门学习手记一入门学习手记二入门学习手记三入门学习手记四 本人微信公众号:前端修炼之路,欢迎关注。 showImg(https://segmentfault.com/img/bVbk0kO?w=1150&h=599); 之前用过gulp、grunt,但是一直没有学习过webpack。这两天刚好有时间,学习了下...

    mengera88 评论0 收藏0
  • Webpack 4.X 从入门到精通 - module(四)

    摘要:这就需要把文件单独拎出来,那需要一个插件来配合才能完成版本需要以上,低版本请使用使用步骤安装在里引入模块写入陈学辉文件目录会放入里写入代替执行命令后可以看到目录里已经多了一个文件夹,这个文件夹里放了一个文件。 概念 在webpack中任何一个东西都称为模块,js就不用说了。一个css文件,一张图片、一个less文件都是一个模块,都能用导入模块的语法(commonjs的require,E...

    harryhappy 评论0 收藏0
  • webpack入门及踩坑应对指南

    摘要:的使用为什么使用前端需要工程化工程化的概念小作坊流水线流水线的特点自动化,模块化性能优化自动化就是命令行操作,一行命令实现多个功能,例如自动监听变化,自动翻译源代码到打包代码库里面文件复杂多样文件多变化快将各种文件集 webpack的使用 为什么使用webpack 1.前端需要工程化 工程化的概念: 小作坊 -> 流水线流水线的特点:自动化,模块化、性能优化 自动化就是命令行操作,一行...

    ky0ncheng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<