svg-sprite-loader icon indicating copy to clipboard operation
svg-sprite-loader copied to clipboard

rawRule.use is not iterable

Open rrooding opened this issue 3 years ago • 9 comments

Trying to use webpack 5 with Next.js & svg-sprite-loader with extract, I receive the following error:

rawRule.use is not iterable

It's this code here that is causing the issue: https://github.com/JetBrains/svg-sprite-loader/blob/839f8786e94e3afc3edbb6533ec8f7e3c25c969e/lib/utils/get-matched-rule-5.js

It is triggered by this automatically added webpack configuration from Nx.dev/Next:

Screenshot 2021-06-23 at 18 48 31

rrooding avatar Jun 23 '21 16:06 rrooding

I'm facing same issue, please fix it. Does not work from version 6.0.8.

mdudek avatar Jun 24 '21 06:06 mdudek

The issue occurs from 6.0.7

kovart avatar Jun 27 '21 08:06 kovart

@kovart Works fine for me on 6.06 (but not 6.09) 🙂

Eli-Black-Work avatar Jul 02 '21 09:07 Eli-Black-Work

Confirm that I can reproduce the issue in 6.08 and 6.09, but not 6.07

The following patch works for me. (If you are watching this bug, consider applying it in your own project with patch-package)

diff --git a/node_modules/svg-sprite-loader/lib/utils/get-matched-rule-5.js b/node_modules/svg-sprite-loader/lib/utils/get-matched-rule-5.js
index a5c1854..59af04f 100644
--- a/node_modules/svg-sprite-loader/lib/utils/get-matched-rule-5.js
+++ b/node_modules/svg-sprite-loader/lib/utils/get-matched-rule-5.js
@@ -8,13 +8,18 @@ const isSpriteLoader = (rule) => {
   return /svg-sprite-loader/.test(rule.loader);
 };
 
+const hasIterableProperty = (obj, name) => 
+  Object.prototype.hasOwnProperty.call(obj, name) &&
+      typeof obj[name][Symbol.iterator] === 'function'
+
+
 module.exports = (compiler) => {
   const rawRules = compiler.options.module.rules;
   let spriteLoader = null;
   for (const rawRule of rawRules) {
     if (isSpriteLoader(rawRule)) {
       spriteLoader = rawRule;
-    } else if (Object.prototype.hasOwnProperty.call(rawRule, 'use')) {
+    } else if (hasIterableProperty(rawRule, 'use')) {
       for (const subLoader of rawRule.use) {
         if (isSpriteLoader(subLoader)) {
           spriteLoader = subLoader;

domq avatar Jul 08 '21 06:07 domq

Are there any news about this one?

MelonCode avatar Jul 21 '21 10:07 MelonCode

same for me above 6.0.7

iuscare avatar Jul 21 '21 14:07 iuscare

same issue 😔 6.0.9

nueq22 avatar Jul 21 '21 14:07 nueq22

The question is the answer :) "rawRule.use is not iterable"

For every rule: Wrap "use" object with an array or Extract "use" object to root of the rule and remove "use"

module: {
  rules: [
    ...
    {
        ...
        use: [ { loader: 'next-babel-loader', options: ... } ]
    }
  ]
}
module: {
  rules: [
    ...
    {
        ...
        loader: 'next-babel-loader',
        options: ...
    }
  ]
}

dFelinger avatar Aug 04 '21 05:08 dFelinger

@rrooding As workaround you can modify nextJs default webpack rules like this

module.exports = {
  webpack: (config, options) => {
    config.module.rules = config.module.rules.map((rule) => {
      const ruleUse = rule?.use;
      const isRuleUseIterable = Array.isArray(ruleUse);
      if (ruleUse && !isRuleUseIterable) {
        rule.use = [ruleUse];
      }

      return rule;
    });

    return config
  },
}

More about it you can find here

roamn avatar Sep 10 '21 00:09 roamn