三石的webpack.config.js(module篇)

912 阅读5分钟

模块,webpack 默认只支持 .js, .json 文件,像其他的 .vue.png.scss.css.ts等都是不支持的。

所以如果想要 webpack 支持其他类型的文件,就需要不同类型的 loader 进行解析。

Loader

处理各模块的,简单来说处理符合条件的模块,并按照一定格式输出符合webpack要求的模块。然后webpack将这些模块打包起来生成对应的js文件

具体请看 三石的webpack(Loader篇)

Rule

作用

当匹配成功时,应用相应规则处理模块。 规则有两种输入值:

  1. 应用 loader:应用在 resource 上的 loader 数组。
  2. 应用 Parser:用于为模块创建解析器的选项对象 其中,影响 loader 的属性有 loader、options、use等;影响 parser 的属性有 parser 选项

匹配

匹配输入

有两种输入值:

  1. resource:资源文件的绝对路径。它已经根据 resolve 规则解析。
  2. issuer: 请求者的文件绝对路径。是导入时的位置。

例如:  从 app.js 导入 './style.css',resource 是 /path/to/style.css. issuer 是 /path/to/app.js

在规则中,属性 test, include, exclude 和 resource 对 resource 匹配,属性 issuer 对 issuer 匹配。 当使用多个条件时,所有条件都匹配

resource 是文件的 解析 路径,这意味着符号链接的资源是真正的路径,而不是 符号链接位置

test

test就是用来筛选资源的,有以下匹配规则

  • 字符串 值为字符串时,可以为资源、其目录的绝对路径
  • 函数 值为函数时,入参是资源的绝对路径,返回boolean
module.exports = {
  //...
  module: {
    rules: [
      {
        test: (path) => {
          return path.indexOf('.css') > -1
        }
        use: [ 'css-loader']
      },
    ],
  },
};
  • 正则 值为正则时,匹配正则
  • 条件数组 值为条件数组时,里面每一项都可以是字符串、正则、函数,只要符合其中一项就能交给loader处理
  • 对象 值为对象时,匹配所有属性

exclude/include

用法和test相同(也就是都支持那几种筛选方式),都是用来筛选资源的

  • exclude:排除符合条件的模块
  • include:引入符合条件的模块

issuer

用法和test相同,但是要注意匹配的是引入资源的文件路径!

// index.js
import A from './a.js';

像上面的例子,issuer就会匹配到 index.js 文件的路径

layer

匹配模块所在的文件夹

issuerLayer

可以匹配文件夹的issuer

resource

此选项也可筛选资源,符合条件的资源让loader处理
它有以下选项:

  • test:同rules.test
  • exlude:同rules.exclude
  • include:同rules.include
  • not:值为数组,数组每一项可以是字符串、正则、函数;如果其中一项满足,那就不能交给loader处理
  • and:值为数组,同上,但是每一项都符合才能交给loader处理
  • or:值为数组,同上,符合一项就能交给loader处理

resourceQuery

和resource一样,但是匹配的不是路径,而是query参数

oneOf

其用法和 rules 一样。可以使用 oneOf 判断多个规则,当规则匹配时,使用第一个匹配到的

下面这个例子,处理.css资源,但是one.css要用url-loader处理,two.css要用file-loader处理

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/
        oneOf: [
          {
            resourceQuery: /one/,
            use: 'url-loader'
          },
          {
            resourceQuery: /two/,
            use: 'file-loader'
          },
        ]
      },
    ],
  },
};

Notice

  • issuer exclude test include resourceQuery同时使用时,是“与”的关系
  • resource resourceQuery同时使用时,也是“与”
  • 配置了resourceexclude test include不能使用;issuer不生效

use

  1. 可以是一个应用于模块的 useEntry 数组。每个入口指定使用一个 loader
module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: 'less-loader',
            options: {
              noIeCompat: true,
            },
          },
        ],
      },
    ],
  },
};

useEntry 有以下属性:

  • loader是必须的,用来处理模块
  • options为字符串或对象,可以理解为loader的选项,可以传递到loader中
  • 其他的诸如 cacheDirectory cacheCompression等特殊的
  1. 也可以是函数,接受入参info,返回应用于模块的 useEntry 数组
module.exports = {
  //...
  module: {
    rules: [
      {
        use: (info) => [
          {
            loader: 'custom-svg-loader',
          },
          {
            loader: 'svgo-loader',
            options: {
              plugins: [
                {
                  cleanupIDs: {
                    prefix: basename(info.resource),
                  },
                },
              ],
            },
          },
        ],
      },
    ],
  },
};

info 有以下属性:

  • compiler: 当前 webpack 的编译器(可以是 undefined 值)
  • issuer: 引入被处理资源的所在文件的绝对路径
  • realResource: 被处理资源的绝对路径
  • resource: 被处理资源的绝对路径,它常常与 realResource 相等,只有当资源名称被 request 字符串中的 !=! 覆盖时才不相等
  • resourceQuery: 被处理资源的query部分

Other

enforce

我们知道,loader的处理顺序和书写顺序一致,但是如果已经写好了loader,但是又需要调整顺序,这时候就可以用到 rule.enforce 属性

1. pre 优先处理
2. normal 正常处理(默认)
3. inline 其次处理
4. post 最后处理

parser

解析器的配置,通常是把所有解析器配置都收敛到 rule.parser 这个对象里

resolve

也可以使用 rule.resolve 配置该模块层级的解析,而不采用全局 resolve解析

module.exports = {
  resolve: {
    alias: {
      footer: './footer/default.js',
    },
  },
  module: {
    rules: [
      {
        resourceQuery: /one/,
        resolve: {
          alias: {
            footer: './footer/overridden.js',
          },
        },
      },
    ],
  },
};

在非?one文件下使用 footer,会定位到 './footer/default.js';在?one文件下定位到'./footer/overridden.js'

noParse

如果一些第三方模块没有AMD/CommonJS规范版本,可以使用 noParse 来标识这个模块,这样 Webpack 会引入这些模块,但是不进行转化和解析,从而提升 Webpack 的构建性能 ,例如:jquery 、lodash

module.exports = {
    //...
    module: {
        noParse: /jquery|lodash/
    }
}

Other

  1. generator 可以使用 module.generator 在一个地方配置所有生成器的选项

  2. parser 可以用 module.parser 在一个地方配置所有解析器的选项

  3. unsafeCache 缓存模块请求的解析

  • 如果 cache 未被启用,则默认值为 false
  • 如果 cache 被启用,并且此模块的来自 node_modules,则值为 true,否则为 false