jeron-diovis
jeron-diovis

Reputation: 846

webpack2: configuring module rules

I'm using [email protected]

My config is pretty simple:

{
  resolve: {
    modules: [
      SRC_ROOT,
      "node_modules",
    ],
  },

  entry: "index.js",

  output: {
    path: sysPath.join(APP_ROOT, "dist"),
    filename: "index.js",
  },

  module: {
    rules: [
      {
        test: /\.js$/i,
        include: SRC_ROOT,
        use: [
          {
            loader: "eslint-loader",
            enforce: "pre",
            options: {
              failOnError: true,
              failOnWarning: true,
            },
          },

          {
            loader: "babel-loader",
          }
        ],
      }
    ]
  },
}

And when I run it, I got following:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.module.rules[0].use should be one of these:
   non-empty string | function | object { loader?, options?, query? } | function | [non-empty string | function | object { loader?, options?, query? }]
   Details:
    * configuration.module.rules[0].use should be a string.
    * configuration.module.rules[0].use should be an instance of function.
    * configuration.module.rules[0].use should be an object.
    * configuration.module.rules[0].use should be one of these:
      non-empty string | function | object { loader?, options?, query? }
    * configuration.module.rules[0].use should be an instance of function.
    * configuration.module.rules[0].use[0] should be a string.
    * configuration.module.rules[0].use[0] should be an instance of function.
    * configuration.module.rules[0].use[0] has an unknown property 'enforce'. These properties are valid:
      object { loader?, options?, query? }
    * configuration.module.rules[0].use[0] should be one of these:
      non-empty string | function | object { loader?, options?, query? }

I'm confused, because these errors are totally contradict to what I see in docs: https://webpack.js.org/configuration/#options.

Arrays in "use" are not supported? "unknown property 'enforce'"? How is it even possible, when doc shows exactly the same usage examples?

Please explain what am I doing wrong here.

Upvotes: 1

Views: 14695

Answers (2)

Michael Jungo
Michael Jungo

Reputation: 32972

The problem is that enforce is not a valid property on a loader. It must be used on a rule, hence it's Rule.enforce in the docs. The following line of the error message tells you that it's not a valid property:

* configuration.module.rules[0].use[0] has an unknown property 'enforce'. These properties are valid:
  object { loader?, options?, query? }

It doesn't show use to be a valid property, because internally use, loaders and loader are treated as aliases.

You'd have to put enforce on the entire rule.

{
  test: /\.js$/i,
  enforce: "pre",
  include: SRC_ROOT,
  use: [
    {
      loader: "eslint-loader",
      options: {
        failOnError: true,
        failOnWarning: true,
      },
    },
    {
      loader: "babel-loader",
    }
  ],
}

But you don't really want babel-loader to be a pre-loader and that means you need to create two separate rules.

rules: [
  {
    test: /\.js$/i,
    enforce: "pre",
    include: SRC_ROOT,
    use: [
      {
        loader: "eslint-loader",
        options: {
          failOnError: true,
          failOnWarning: true,
        },
      },
    ]
  },
  {
    test: /\.js$/i,
    include: SRC_ROOT,
    use: [
      {
        loader: "babel-loader"
      }
    ],
  }
]

I've purposely kept the explicit version of the rules. You can indeed use some shortcuts, one of them being that if you only use a single loader, you may specify options directly on the rule. The options will be forwarded to the loader, which is probably why you thought that enforce is valid on a loader.

Upvotes: 4

Ematipico
Ematipico

Reputation: 1244

Use two different objects inside your rules

module: {
  rules: [
    {
      test: /\.js$/i,
      include: SRC_ROOT,
      loader: "eslint-loader",
      enforce: "pre",
      options: {
        failOnError: true,
        failOnWarning: true,
      }
    },
    {
      test: /\.js$/i,
      include: SRC_ROOT,
      loader: "babel-loader",
    }    
  ]
}

It's a bit redundant but it should work

Upvotes: 0

Related Questions