JetBrains / svg-sprite-loader

Webpack loader for creating SVG sprites.
MIT License
2.01k stars 272 forks source link

rawRule.use is not iterable #464

Open rrooding opened 3 years ago

rrooding commented 3 years ago

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
mdudek commented 3 years ago

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

kovart commented 3 years ago

The issue occurs from 6.0.7

Eli-Black-Work commented 3 years ago

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

domq commented 3 years ago

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;
MelonCode commented 2 years ago

Are there any news about this one?

iuscare commented 2 years ago

same for me above 6.0.7

nueq22 commented 2 years ago

same issue 😔 6.0.9

dFelinger commented 2 years ago

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: ...
    }
  ]
}
roamn commented 2 years ago

@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