loader配置

本节进一步讲解Webpack的loader配置与使用,学习本节前确保已学习https://www.jiangruitao.com/webpack/loader/一节。

一、Loader的关键配置

我们先看一下之前使用过的Webpack配置,我们使用style-loader和css-loader这两个loader来处理CSS。

webpack.config.js里配置上这两个loader

  const path = require('path');

  module.exports = {
    entry: './a.js',  // a.js里引入了CSS文件
    output: {
      path: path.resolve(__dirname, ''),
      filename: 'bundle.js'
    },
    module: {
      rules: [{
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }]
    },
    mode: 'none'
  };

配置loader是在Webpack配置项module里进行的,这个配置项名为何叫module?Module是模块的意思,因此用这个名字可以表示这个配置项是用来解析与处理模块的。

Module配置项里最重要的一个配置子项就是rules了,它定义了loader的处理法则。

Rules是一个数组,数组每一项是一个JS对象,该对象有两个关键属性test和use。

Test是一个正则表达式或正则表达式数组,模块文件名与正则匹配的会被use里的loader处理。

Use可以是字符串,对象或数组,表示要使用的loader。

如果使用单一loader,那么可以取字符串,例如 use: 'babel-loader'。

如果该loader额外配置参数,那么可以取对象,额外参数放在options里(有部分loader放query里),例如 use: {loader: 'babel-loader', options: {…}}。

如果使用多个loader进行链式处理,那么可以取数组,数组每一项可以是字符串或对象,字符串或对象的使用同上。

二、rules其它参数

除了test和use这两个关键配置参数,rules还有exclude、include、resource、issure和enforce等参数。

1.exclude与include

如果我们有一些文件不想被正则匹配到的loader处理,那么我们可以配置exclude项,exclude的中文意思是排除。

Exclude的值是字符串或正则表达式,字符串需要是绝对路径。

我们来看一个例子

  rules: [{
    test: /\.js$/,
    use: ['babel-loader'],
    exclude: /node_modules/,
  }]

上面的配置表示,除了node_modules文件夹,对所有的以js为后缀名的文件模块使用babel-loader处理。

Include表示的意思正好与exclude相反,它表示只对匹配到的文件处理。

  rules: [{
    test: /\.js$/,
    use: ['babel-loader'],
    include: /src/,
  }]

上面的配置表示,只对src目录下以js为后缀名的文件模块使用babel-loader处理。

2.Enforce

对同一类后缀名类型的文件,我们可以使用多个loader处理,例如处理CSS时使用['style-loader', 'css-loader'],loader的处理顺序是数组项从后向前。

如果我们想强制某个loader最先处理或最后处理,可以使用enforce项。

Webpack推荐使用的enforce项有两个,'pre'和'post'。

Pre表示这个loader在所有的loader之前执行,post表示这个loader在所有的loader执行后再执行。

我们来看一个例子

  rules: [{
    test: /\.js$/,
    use: ['eslint-loader'],
    enforce: 'pre',
    exclude: /node_modules/,
  }]

这个配置表示在所有处理js文件模块loader之前执行eslint-loader,这样我们可以在js代码未被处理的时候就进行eslint代码规范校验。

3.resource与issuer

Resource的中文意思是资源,issuer中文意思是发行人。在Webpack中被加载的模块我们称之为resource,而实施加载的模块我们称之为issuer。

例如,我们在一个JS模块里引入了CSS模块,那么JS模块就是issuer,CSS模块就是resource。

  // app.js
  import './src/reset.css'

我们在app.js里引入了reset.css,这里app.js是issuer,reset.css是resource。

在我们之前使用过的loader配置里,其实已经使用了resource,那些test和exclude等配置是使用了默认resource。下面的配置是等效的

  rules: [{
    test: /\.css$/,
    use: ['style-loader', 'css-loader'],
    exclude: /node_modules/
  }]
  rules: [{
    use: ['style-loader', 'css-loader'],
    resource: {
      test: /\.css$/,
      exclude: /node_modules/
    }
  }]

我们来看一个例子,配套github仓库 https://github.com/jruit/webpack-tutorial 的webpack3-1

这个例子和Webpack入门一章Webpack loader的webpack1-3例子相似,都是简单的在一个JS文件里引入一个CSS文件。我们把rules换成了其用resource项的等价写法。执行npx webpack后,在浏览器打开引用了打包后JS文件的HTML,文字颜色显示正常。

  module.exports = {
    entry: './a.js',  // a.js引入了CSS文件,该CSS将文字颜色改为蓝色
    output: {
      path: path.resolve(__dirname, ''),
      filename: 'bundle.js'
    },
    module: {
      // rules: [{
      //   test: /\.css$/,
      //   use: ['style-loader', 'css-loader']
      // }]
      rules: [{
        use: ['style-loader', 'css-loader'],
        resource: {
          test: /\.css$/
        }
      }]
    },
    mode: 'none'
  };
loader配置resource Webpack教程 姜瑞涛的官方网站

下面说一下issuer的使用。

如果想指定只有src目录下的JS引用的CSS可以被相应的loader处理,那么可以配置issuer,下面的配置是等效的。

  rules: [{
    test: /\.css$/,
    use: ['style-loader', 'css-loader'],
    exclude: /node_modules/,
    issuer: {
      test: /\.js$/,
      include: /src/
    }
  }]
  rules: [{
    use: ['style-loader', 'css-loader'],
    resource: {
      test: /\.css$/,
      exclude: /node_modules/
    },
    issuer: {
      test: /\.js$/,
      include: /src/
    }
  }]

三、其它loader写法

在Webpack版本更新的过程中,出现过不同的loader写法。

下面是一个例子,是vue-cli里的配置,这里没有使用use项而是直接使用了loader项指定loader。

  rules: [
    {
      test: /\.(js|vue)$/,
      loader: 'eslint-loader',
      enforce: 'pre',
      include: [resolve('src'), resolve('test')],
      options: {
        formatter: require('eslint-friendly-formatter')
      }
    },
   ]

在Webpack1.x的时候,还有使用loaders项的方式,现在已经被rules取代了。

  module: {
    loaders: [
      {
        test: /\.json$/,
        loader: "json"
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      }
    ]
  }

一些其它的loader写法这里就不列举了,本节内容关键是掌握loader的使用本质,见到其它写法的时候知道查一下资料就可以了。

小结

本节进一步讲解Webpack的loader配置与使用,把一些常用配置都进行了讲解。

笔记与思考

  1. // body.css
    .yellow {
    color: yellow;
    }

    // index.css
    @import './body.css';
    .blue {
    color: blue;
    }

    import style from '../assets/style/index.css'
    const element = `

    CSS Modules

    CSS Modules

    `
    document.getElementById('app').innerHTML = element

    我这里能取到 .blue,但是为什么这里 .yellow 是 undefined?
    一个 css Module 【A】 导入另一个 css Module【B】,A 里面已经有了 B 中的样式,但是经过 loader 加载后,类名发生了改变,导致 html 只能取到直接引入的 【A】 中的类,【B】中的取不到,这个怎么解决呢

  2. import style from '../assets/style/index.css'

    const element = `

    CSS Modules

    CSS Modules

    `
    document.getElementById('app').innerHTML = element

发表评论

邮箱地址不会被公开。 必填项已用*标注