Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-app-rewire-less not working #67

Closed
afc163 opened this issue Aug 21, 2017 · 11 comments · Fixed by #68
Closed

react-app-rewire-less not working #67

afc163 opened this issue Aug 21, 2017 · 11 comments · Fixed by #68

Comments

@afc163
Copy link
Contributor

afc163 commented Aug 21, 2017

/Users/afc163/Projects/antd-demo-new/node_modules/_react-app-rewire-less@2.0.4@react-app-rewire-less/index.js:8
  fileLoader.exclude.push(lessExtension);
            ^

TypeError: Cannot read property 'exclude' of undefined
    at rewireLess (/Users/afc163/Projects/antd-demo-new/node_modules/_react-app-rewire-less@2.0.4@react-app-rewire-less/index.js:8:13)
    at override (/Users/afc163/Projects/antd-demo-new/config-overrides.js:6:12)
    at Object.<anonymous> (/Users/afc163/Projects/antd-demo-new/node_modules/_react-app-rewired@1.2.0@react-app-rewired/scripts/start.js:18:3)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:504:3
@timarney
Copy link
Owner

react-app-rewire-less@2.0.5

@sunnyYanan
Copy link

I still have the problem with "react-app-rewire-less": "^2.1.0",

@dawnmist
Copy link
Collaborator

@sunnyYanan Could you please post the output from adding the console.log line below to your config-overrides.js file just before the call to react-app-rewire-less:

// Turns the regex tests defined in the rules into a human readable string instead of an empty object,
// so we can actually see the rule tests defined when we output it to the console.
function stringifyConfig(name, value) {
  if  (value && value.constructor === RegExp) {
    return value.toString();
  }
  return value;
}

// Assuming you're using the single function type of config-overrides.js. If not, this should be the 
// "webpack" function in the combined export.
module.exports = function(config, env) {
  // Output the actual configuration rules as generated on your machine
  console.log(`${JSON.stringify(config.module.rules, stringifyConfig, 2)}`);
  // Just to exit out without going any further, so the log messages do not get wiped away.
  throw new Error('stop here');

  config = react-app-rewire-less(config, env);
  ...the rest of your changes here...
  return config;
}

Once you have the console output from above, you can undo these changes - they're just to put together what the actual rules are that are being passed to the rewire so that we can debug why the file-loader is not being found properly on your machine.

And a quick question just to confirm - are you using the normal/default react-scripts package, or are you using a custom scripts package (the --scripts-version option to react-app-rewired)?

@sunnyYanan
Copy link

sunnyYanan commented Jan 30, 2018

[
  {
    "test": "/\\.(js|jsx|mjs)$/",
    "enforce": "pre",
    "use": [
      {
        "options": {
          "eslintPath": "/Users/zhangyanan/Documents/self-template/node_modules/_eslint@4.10.0@eslint/lib/api.js",
          "baseConfig": {
            "extends": [
              "/Users/zhangyanan/Documents/self-template/node_modules/_eslint-config-react-app@2.1.0@eslint-config-react-app/index.js"
            ]
          },
          "ignore": false,
          "useEslintrc": false
        },
        "loader": "/Users/zhangyanan/Documents/self-template/node_modules/_eslint-loader@1.9.0@eslint-loader/index.js"
      }
    ],
    "include": "/Users/zhangyanan/Documents/self-template/src"
  },
  {
    "oneOf": [
      {
        "test": [
          "/\\.bmp$/",
          "/\\.gif$/",
          "/\\.jpe?g$/",
          "/\\.png$/"
        ],
        "loader": "/Users/zhangyanan/Documents/self-template/node_modules/_url-loader@0.6.2@url-loader/index.js",
        "options": {
          "limit": 10000,
          "name": "static/media/[name].[hash:8].[ext]"
        }
      },
      {
        "test": "/\\.(js|jsx|mjs)$/",
        "include": "/Users/zhangyanan/Documents/self-template/src",
        "loader": "/Users/zhangyanan/Documents/self-template/node_modules/_babel-loader@7.1.2@babel-loader/lib/index.js",
        "options": {
          "babelrc": false,
          "presets": [
            "/Users/zhangyanan/Documents/self-template/node_modules/_babel-preset-react-app@3.1.1@babel-preset-react-app/index.js"
          ],
          "cacheDirectory": true
        }
      },
      {
        "test": "/\\.css$/",
        "use": [
          "/Users/zhangyanan/Documents/self-template/node_modules/_style-loader@0.19.0@style-loader/index.js",
          {
            "loader": "/Users/zhangyanan/Documents/self-template/node_modules/_css-loader@0.28.7@css-loader/index.js",
            "options": {
              "importLoaders": 1
            }
          },
          {
            "loader": "/Users/zhangyanan/Documents/self-template/node_modules/_postcss-loader@2.0.8@postcss-loader/lib/index.js",
            "options": {
              "ident": "postcss"
            }
          }
        ]
      },
      {
        "exclude": [
          "/\\.js$/",
          "/\\.html$/",
          "/\\.json$/"
        ],
        "loader": "/Users/zhangyanan/Documents/self-template/node_modules/_file-loader@1.1.5@file-loader/dist/cjs.js",
        "options": {
          "name": "static/media/[name].[hash:8].[ext]"
        }
      }
    ]
  }
]

here is my output, and I use the default react-scripts package

@dawnmist
Copy link
Collaborator

dawnmist commented Jan 31, 2018

@sunnyYanan Looking at the above, the file-loader really should have been able to be found - we search for it as both /file-loader/ and @file-loader/ (actually use path.sep instead of the '/' character directly, so that it adjusts to different path separators in different OS's), and the second of those two possibilities should have been triggered in the config you've posted. The match is checked for by calling loaderNameMatches(rule, 'file-loader') as follows:

const fileLoader = getLoader(
config.module.rules,
rule => loaderNameMatches(rule, 'file-loader')
);

const getLoader = function(rules, matcher) {
var loader;
rules.some(rule => {
return (loader = matcher(rule)
? rule
: getLoader(rule.use || rule.oneOf || [], matcher));
});
return loader;
};

const loaderNameMatches = function(rule, loader_name) {
return rule && rule.loader && typeof rule.loader === 'string' &&
(rule.loader.indexOf(`${path.sep}${loader_name}${path.sep}`) !== -1 ||
rule.loader.indexOf(`@${loader_name}${path.sep}`) !== -1);
}

It should have gone past the first rule in the config.modules.rules, found the "oneOf" clause in the second rule, then iterated through each of the subrules in the oneOf clause until it found a match with the last subrule according to the config that you have posted.

@pauliusuza
Copy link

pauliusuza commented Feb 2, 2018

Having the same issue as @sunnyYanan. This is an active bug, please re-open.

@dawnmist
Copy link
Collaborator

dawnmist commented Feb 3, 2018

@pauliusuza @sunnyYanan Can either of you put together a sample repository that shows this happening? What OS are you seeing it on? At this stage, I cannot reproduce the issue, and the output that @sunnyYanan provided shows that it should not have been happening, so without a way to reproduce and with output that I can see no reason for the code to be failing I am at a loss to be able to help any further.

The original reason for this to have been occurring was that we were looking for ${path.sep}file-loader${path.sep} and on some operating systems the version number is added to the path as well, so we needed to look for @file-loader${path.sep} on those operating systems. The config output that @sunnyYanan provided showed that the @file-loader${path.sep} path should have matched his config.

@sam019
Copy link

sam019 commented Feb 5, 2018

I meet this bug yet. react-app-rewire-less@2.1.0

this is my output:
[ { "test": "/\\.(js|jsx|mjs)$/", "enforce": "pre", "use": [ { "options": { "eslintPath": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_eslint@4.10.0@eslint/lib/api.js", "baseConfig": { "extends": [ "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_eslint-config-react-app@2.1.0@eslint-config-react-app/index.js" ] }, "ignore": false, "useEslintrc": false }, "loader": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_eslint-loader@1.9.0@eslint-loader/index.js" } ], "include": "/Users/liangsen/Desktop/eleme/tms_ops_web/src" }, { "oneOf": [ { "test": [ "/\\.bmp$/", "/\\.gif$/", "/\\.jpe?g$/", "/\\.png$/" ], "loader": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_url-loader@0.6.2@url-loader/index.js", "options": { "limit": 10000, "name": "static/media/[name].[hash:8].[ext]" } }, { "test": "/\\.(js|jsx|mjs)$/", "include": "/Users/liangsen/Desktop/eleme/tms_ops_web/src", "loader": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_babel-loader@7.1.2@babel-loader/lib/index.js", "options": { "babelrc": false, "presets": [ "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_babel-preset-react-app@3.1.1@babel-preset-react-app/index.js" ], "cacheDirectory": true, "plugins": [ "transform-decorators-legacy", [ "import", { "libraryName": "antd", "style": true } ] ] } }, { "test": "/\\.css$/", "use": [ "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_style-loader@0.19.0@style-loader/index.js", { "loader": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_css-loader@0.28.7@css-loader/index.js", "options": { "importLoaders": 1 } }, { "loader": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_postcss-loader@2.0.8@postcss-loader/lib/index.js", "options": { "ident": "postcss" } } ] }, { "exclude": [ "/\\.(js|jsx|mjs)$/", "/\\.html$/", "/\\.json$/" ], "loader": "/Users/liangsen/Desktop/eleme/tms_ops_web/node_modules/_file-loader@1.1.5@file-loader/dist/cjs.js", "options": { "name": "static/media/[name].[hash:8].[ext]" } } ] } ]

@sam019
Copy link

sam019 commented Feb 5, 2018

I find the problem...
This is not the problem of this package self. It is happened when use third npm source, and I fix it with fetching package via offcial npm source.

@andreigec
Copy link

my quick fix

const path = require('path');
const { compose } = require('react-app-rewired');

function excludeExtension(config, extension) {
const index1 = config.module.rules.findIndex((rule) => typeof (rule.oneOf) !== 'undefined');
config.module.rules[index1].oneOf = config.module.rules[index1].oneOf.filter((rule) => !rule.test || rule.test.toString().indexOf(extension) === -1);

const index2 = config.module.rules[index1].oneOf.findIndex((rule) => rule.loader && typeof rule.loader === 'string' && rule.loader.indexOf(`${path.sep}file-loader${path.sep}`) !== -1);
config.module.rules[index1].oneOf[index2].exclude.push(extension);

return config;

}

function rewireLess(config, env) {
const extension = /.less$/;
config = excludeExtension(config, extension);

config.module.rules.push({
    test: extension,
    use: ['style-loader?sourceMap',
        'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
        'less-loader'],
});

return config;

}

function rewriteSVG(config, env) {
const extension = /.svg$/;
config = excludeExtension(config, extension);

config.module.rules.push({
    test: extension,
    use: [
        { loader: 'svg-react-loader' },
    ],
});

return config;

}

module.exports = compose(rewireLess, rewriteSVG);

@Calerme
Copy link

Calerme commented Aug 23, 2018

Reloading version 1.1.0 can solve this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants