Babel-plugin-module-resolver: ver 2.6.0 broken - aliases not recognized

Created on 29 Mar 2017  路  34Comments  路  Source: tleunen/babel-plugin-module-resolver

Hello!

After your newest release (2.6.0) my react application stopped building because of few errors.
The main problem is that aliases stopped working, for example logs from building:

    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/lib/Compilation.js:229:38
    at onDoneResolving (/Users/i319388/knowledgehub_react/app/node_modules/webpack/lib/NormalModuleFactory.js:29:20)
    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/lib/NormalModuleFactory.js:85:20
    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/node_modules/async/lib/async.js:726:13
    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/node_modules/async/lib/async.js:52:16
    at done (/Users/i319388/knowledgehub_react/app/node_modules/webpack/node_modules/async/lib/async.js:241:17)
    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/node_modules/async/lib/async.js:44:16
    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/node_modules/async/lib/async.js:723:17
    at /Users/i319388/knowledgehub_react/app/node_modules/webpack/node_modules/async/lib/async.js:167:37
    at /Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:24:19
    at onResolved (/Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/Resolver.js:38:18)
    at innerCallback (/Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/Resolver.js:94:11)
    at loggingCallbackWrapper (/Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/createInnerCallback.js:21:19)
    at /Users/i319388/knowledgehub_react/app/node_modules/tapable/lib/Tapable.js:134:6
    at /Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js:54:23
    at /Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/Resolver.js:191:15
    at /Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js:45:26
    at loggingCallbackWrapper (/Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/createInnerCallback.js:21:19)
    at /Users/i319388/knowledgehub_react/app/node_modules/tapable/lib/Tapable.js:134:6
    at Resolver.<anonymous> (/Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/ModuleAsDirectoryPlugin.js:30:12)
    at Storage.finished (/Users/i319388/knowledgehub_react/app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:38:16)
    at /Users/i319388/knowledgehub_react/app/node_modules/graceful-fs/polyfills.js:284:29
    at FSReqWrap.oncomplete (fs.js:114:15)
resolve module components/3-pages/App in /Users/i319388/knowledgehub_react/app/src/containers
  looking for modules in /Users/i319388/knowledgehub_react/app/node_modules
    /Users/i319388/knowledgehub_react/app/node_modules/components doesn't exist (module as directory)
  looking for modules in /Users/i319388/knowledgehub_react/app/bower_components
    /Users/i319388/knowledgehub_react/app/bower_components/components doesn't exist (module as directory)
  looking for modules in /node_modules
    /node_modules/components doesn't exist (module as directory)

Version 2.5.0 works as expected.

My babelrc:

{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": ["react-hot-loader/babel",
    ["module-resolver", {
        "root": ["./src"],
        "alias": {
          "basic": "components/1-basic",
          "atoms": "components/1-basic/1-atoms",
          "molecules": "components/1-basic/2-molecules",
          "organisms": "components/2-organisms",
          "pages": "components/3-pages",
          "hoc":  "components/hoc",
          "components": "components",
          "containers": "containers",
          "store": "store",
          "services": "services",
          "utils": "utils",
          "styles": "styles"
        }
      }]
    ]
}

Most helpful comment

I have just released [email protected], if you'd like to give it a try. We changed quite a few things internally so hopefully all (or most) of your issues will be resolved.

If you have issue with this beta version, please let me and @fatfisz know :)

_Note:_ If you're using it with eslint, please ugrade the import plugin to its v4.0.0-beta.0.

All 34 comments

Same here. I set back version to 2.5.0 and now everything is fine again.

Hi there, the 2.6 doesn't work for me as well:

This is my .babelrc that it works fine with 2.5.
With 2.6 Webpack says "I'm not able to resolve the path" when I trying to import a module.

Any clues?

"module-resolver", {
            "root": ["./src"],
            "alias": {
                "root_components": "components",
                "root_entities": "entities",
                "root_library": "library",
                "root_services": "services",
                "root_styles": "styles",
                "root_views": "views"
            }

I bet that our error messages are very similar, for example from mine stack trace:
looking for modules in /node_modules /node_modules/components doesn't exist (module as directory)

It just means that plugin stopped working and doesnt replace aliases thus webpack is trying to find modules called same as our aliases (in my case 'components' for example).

Would anyone of you have a public repo for this error?
I'm curious to see why it fails for so many users without failing in our test suite or in my own projects :/

Thanks.
@fatfisz if you have an idea... :)

@mjasinski5 @guirip @useless-stuff Could one of you "donate" a small POC public project? It would be extremely useful for bisection.

Unfortunately, based on the configs alone we're unable to debug - aliasing is covered by the tests and based on them the behavior didn't change between the two versions, so this is very puzzling to me 馃檨

@fatfisz @tleunen I haven't had time to minimize it, but we ran into an issue which I believe is the same/similar with the issue that GitHub linked in above ^.

The error we've seen from a user:

SyntaxError: TransformError: /Users/parm/nav-app/node_modules/expo/src/Expo.js: /Users/parm/nav-app/node_modules/expo/src/Expo.js: Cannot read property 'find' of undefined

The babel preset in question:

// index.js
module.exports = {
  presets: ['babel-preset-react-native-stage-0/decorator-support'],
  plugins: [
    [
      'babel-plugin-module-resolver',
      {
        alias: {
          'react-native-vector-icons': '@expo/vector-icons',
          '@expo/vector-icons/lib/create-icon-set': 'react-native-vector-icons/lib/create-icon-set',
          '@expo/vector-icons/lib/icon-button': 'react-native-vector-icons/lib/icon-button',
          '@expo/vector-icons/lib/create-icon-set-from-fontello': 'react-native-vector-icons/lib/create-icon-set-from-fontello',
          '@expo/vector-icons/lib/create-icon-set-from-icomoon': 'react-native-vector-icons/lib/create-icon-set-from-icomoon',
          '@expo/vector-icons/lib/icon-button': 'react-native-vector-icons/lib/icon-button',
          '@expo/vector-icons/glyphmaps': 'react-native-vector-icons/glyphmaps',
        },
      },
    ],
  ],
};

The source of the referenced Expo.js: https://github.com/expo/expo-sdk/blob/master/src/Expo.js

Let me know if this helps at all, or if I should post this in a separate issue? We've temporarily resolved the problem by pinning the preset to 2.5.0 in a newer release, but would be good to be able to stay up to date.

I'll make a quick fix for Cannot read property 'find' of undefined. See https://github.com/tleunen/babel-plugin-module-resolver/pull/145. I'll release a new fix version shortly

Will have to investigate further once I get more time.

Can someone try 2.6.1 and let me know if this resolves the initial issue?

@tleunen I tested 2.6.1 and the modules still cannot be found

I've managed to reproduce the error in Expo, will track the cause now.

For now I've tracked it down to babel-preset-expo being used twice: first in the app's own .babelrc, then in node_modules/expo/.babelrc. Removing the preset in the second place (or removing the .babelrc altogether) removes the problem.

Of course this is not the actual cause; I will see if I can find out what it is today, as my day is nearing an end ;)

Aha! That's good to know (cc @brentvatne). Regardless of the fix on this end, seems like we may want to flatten the duplicate usages.

Ok, I've pinpointed that to manipulateOptions.

Let's take a look at where it is called:

for (const ref of plugins) {
  const [plugin, pluginOpts] = ref;

  currentPluginVisitors.push(plugin.visitor);
  currentPluginPasses.push(new PluginPass(this, plugin, pluginOpts));

  if (plugin.manipulateOptions) {
    plugin.manipulateOptions(opts, this.parserOpts, this);
  }
}

Because babel-plugin-module-resolver is using manipulateOptions to modify the plugin options, and pluginOpts is not passed to manipulateOptions, this code is used instead to find the plugin options:

let findPluginOptions = babelOptions.plugins.find(plugin => plugin[0] === this)[1];

This has a flaw - if the same plugin is included twice in the plugin list, only the first one will have the options modified. And this is indeed the cause of the error in create-react-native-app.

My suggestion is to get rid of manipulateOptions completely - it is not even documented AFAIK.
Using the pre method and modifying this.opts inside it seems like a better option. I've prepared a fix here: #146.


On a side note, I don't think this bug is related to the original one - so if OP or others could please send a bigger example, I'll debug that.

@fatfisz its still needed? PoC? If yes, I can provide one in few hours :)

@mjasinski5 Please do, I'm convinced that the issue I've solved and the original issue are two different things :)

Though if my fix has somehow fixed both of them, then it's all the better. Still, I'd like to have additional tests to prevent regressions in the future.

@fatfisz https://github.com/mjasinski5/poc-module-resolver-bug
It works with 2.5.0 but it doesnt with 2.6.0 :)

Ive erased all my unnecessary code but still left package.json with all dependencies (might be helpful?). Maybe its connected with some another babel plugin. Hope it helps!

Good luck:)

NOTE: im using node 7.6.0 :)

@mjasinski5 Thanks, I'll be looking at that in 5 hours or so. Hopefully it will break on my machine too so that I can pinpoint the cause :D

@tleunen @mjasinski5 I think I've got it. The cause is very "interesting" 馃槄

There was a bug where in some cases the alias was applied twice. This was caused by:
1) an alias that had the same prefix, e.g. "path": "path/src"
2) and the usage of the babel-plugin-transform-es2015-modules-commonjs, usually through the es2015 preset.

The module-resolver plugin was applying the alias once when it has encountered an import statement and then the second time after import was transformed into require.

This bug was fixed in 097bcc838066a7f40930ca9c553a74767b56ff86, by enforcing only one pass for the imports/requires.


Here's my version of the PoC project that is minimal: https://github.com/fatfisz/poc-module-resolver-bug. To test run npm test. Expected output is true. For 2.6.x the output is false, because the path is not resolved to the expected one.

The configuration in the PoC boils down to three things:
1) there's the es2015 preset - import will be transformed into require
2) a root is configured for the module-resolver plugin: "./src"
3) an alias is configured for the module-resolver plugin: "pages": "components/3-pages"

The "culprit" file has this import: import App from 'pages/App';.

In 2.5.0 the path was transformed two times - first in the import:

  • pages/App -> components/3-pages/App (based on the alias)

and then in the require because of the es2015 preset:

  • components/3-pages/App -> ./src/components/3-pages/App (based on the root).

As you can see, this has only worked out because of the two-pass bug. The 2.6.x version does only one pass, so naturally it ends up with components/3-pages/App, which is treated as a node module.

Removing the es2015 preset results in the right path, and so does fixing the alias like so:

"pages": "./src/components/3-pages"

One solution I see is to resolve aliased paths using the root again, mimicking the second pass of the plugin. I'm however not sure how this will affect configuration not relying (unknowingly, but still) on this bug.

Just to confirm:

@useless-stuff: do you expect "root_components" to resolve to "./src/components" or to the package "components"? Are you transforming import to require?

@guirip: what's your configuration? Can you confirm whether it's the case similar to what I've described here?

@fatfisz - could you possibly pull the broken releases from npm so that people using Expo don't run into this problem? it has spawned a reddit thread :P https://www.reddit.com/r/reactnative/comments/62eth0/this_error_is_driving_me_insane_has_anyone_found/

we have fixed it for new releases but it would be too difficult to handle all cases for old releases

I'll revert all changes we made in 2.6

Lesson learned for next time. Do not publish a new version when you don't have the time for the support

Or maybe you could merge the fix #146? I have time for support now, I'm just not sure what our protocol is for merging stuff.

Could we move the discussion about the non-OP bug (Cannot read property 'find' of undefined) to the other thread (#148)? This will start getting unwieldy otherwise, as the original issue is a different one.

@fatfisz I've made a 2.6.2 with your fix.

Lets see if a full rollback is still needed.

@tleunen - trying it now

@tleunen re:

Lesson learned for next time. Do not publish a new version when you don't have the time for the support

Please don't feel discouraged! This is a very useful package for us that we're grateful to not have to maintain ourselves. EDIT: I should add that the super fast replies here have been amazing!

I'll track #148 now, sorry for hijacking this issue -- hadn't had my coffee yet and fixated on the version number rather than the actual error.

hate to be the bearer of bad news, new version still breaks :( maybe it's best to revert and publish these to a 2.0.0-rc.0 version?

The revert seems like the safest solution for now then.

also agreed with @dikaiosune - this package is incredibly useful and we really appreciate your quick responses and hard work on it

I have just released [email protected], if you'd like to give it a try. We changed quite a few things internally so hopefully all (or most) of your issues will be resolved.

If you have issue with this beta version, please let me and @fatfisz know :)

_Note:_ If you're using it with eslint, please ugrade the import plugin to its v4.0.0-beta.0.

Alias is not working in [email protected] for me =(

@wasd171 Can you create a new issue and provide more info there, like your configuration, what was printed in the console and what is the structure of your project?

@fatfisz I am sorry, found out it was my misconfiguration!

Alias path: 'path/dist' is working for me [email protected]

Was this page helpful?
0 / 5 - 0 ratings