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

[Babel7] Does not resolve module for monorepo with babel-node #338

Open
jibees opened this issue Dec 11, 2018 · 16 comments
Open

[Babel7] Does not resolve module for monorepo with babel-node #338

jibees opened this issue Dec 11, 2018 · 16 comments

Comments

@jibees
Copy link

jibees commented Dec 11, 2018

Hi there,

I have a monorepo designed like this:

- packages
-- package-1
-- package-2
babel.config.js

In packages/package-2 I have a script defined in package.json like this:

"dev": "babel-node --config-file ../../babel.config.js ./index.js",

The babel config for module-resolver is :

 const plugins = [
    [
      "module-resolver",
      {
        cwd: "packagejson",
        root: "./",
        alias: {
          "@package1": "./packages/package-1"
        }
      }
    ]
  ];

The babel config is loaded, but can't resolve the module './packages/package-1' :

Error: Cannot find module './packages/package-1'
    at Function.Module._resolveFilename (module.js:548:15)
    at Function.Module._load (module.js:475:25)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> ([...]/packages/package-2/index.js:1:1)
    at Module._compile (module.js:653:30)
    at Module._compile ([...]/node_modules/pirates/lib/index.js:83:24)
    at Module._extensions..js (module.js:664:10)
    at Object.newLoader [as .js] ([...]/node_modules/pirates/lib/index.js:88:7)
    at Module.load (module.js:566:32)

Thanks a lot !

EDIT: workaround for me : using yarn workspaces https://yarnpkg.com/lang/en/docs/workspaces/#toc-how-to-use-it

@Izhaki
Copy link

Izhaki commented Dec 21, 2018

There could be a few issues here.

First, it appears you run the command from the sub-package folder, so babel may see ./ (root) as the folder you are running the command from. Instead of providing a relative path to babel.config.js, have a look at providing babel-node with rootMode: 'upward'.

Then, try "@package1": "packages/package-1", although I'll be surprised if this is the issue.

Finally, could you show the line you use to import the package in index.js?

@jibees
Copy link
Author

jibees commented Dec 21, 2018

I've made a repo with the error I can reproduce:
https://github.com/jibees/babel7-node-test/tree/original-error

Thanks a lot ;)

@Izhaki
Copy link

Izhaki commented Dec 21, 2018

Well if you do this:

    [
      "module-resolver",
      {
        root: 'xxxxxxxxxxxxxxxxxxxx',
        alias: {
          "@package1": "../package-1"
        }
      }
    ]

It does pickup package-1, which suggests that the root property is ignored and it uses cwd to resolve the alias path.

@Izhaki
Copy link

Izhaki commented Dec 21, 2018

Note that this works:

      "module-resolver",
      {
        resolvePath(sourcePath) {
          switch (sourcePath) {
            case "@package1":
              return path.resolve(__dirname, "packages/package-1");
            default:
              console.log(sourcePath);
          }
        }
      }

@Izhaki
Copy link

Izhaki commented Dec 21, 2018

@tleunen I think there's an issue with the plugin: It doesn't resolve the root correctly when using babel.config.js which is central to mono-repos with babel 7 (docs).

@jibees
Copy link
Author

jibees commented Dec 21, 2018

Note that this works:

      "module-resolver",
      {
        resolvePath(sourcePath) {
          switch (sourcePath) {
            case "@package1":
              return path.resolve(__dirname, "packages/package-1");
            default:
              console.log(sourcePath);
          }
        }
      }

I got the error : path is not defined
And if I replace by sourcePath, I got sourcePath.resolve is not a function

@Izhaki
Copy link

Izhaki commented Dec 21, 2018

Add at the top:

const path = require('path')

It's a core module.

jibees pushed a commit to jibees/babel7-node-test that referenced this issue Dec 21, 2018
@jibees
Copy link
Author

jibees commented Dec 21, 2018

Ooops, sorry.

Done this, by got a new error:

(function (exports, require, module, __filename, __dirname) { import _foo from "@jibees/package1/src/foo";
                                                              ^^^^^^

SyntaxError: Unexpected token import

Strange...

@Izhaki
Copy link

Izhaki commented Dec 21, 2018

That's because babel does not build anything outside the current cwd. You'd need to override the ignore option to only include node_modules. This is how I do this, albeit with babel/register:

require('@babel/register')({
  // Find babel.config.js up the folder structure.
  rootMode: 'upward',

  // Since babel ignores all files outside the cwd, it does not compile sibling packages
  // So rewrite the ignore list to only include node_modules
  ignore: ['node_modules'],
});

@jibees
Copy link
Author

jibees commented Dec 21, 2018

It works ;) Thanks a lot !

@Izhaki
Copy link

Izhaki commented Sep 11, 2019

Can this issue be closed?

@snaerth
Copy link

snaerth commented May 6, 2020

This is still an issue for me. When using monorepo

@avallonazevedo
Copy link

avallonazevedo commented May 11, 2020

@snaerth

I had the same problem as you. I solved it by creating a specific babel.config.js for each package and extending it to the root babel.config.js.

packages
- package-1
-- utils
-- components
-- babel.config.js
- package-2
-- src
-- babel.config.js
babel.config.js

For each babel.config, I have this configuration:

module.exports = {
  extends: './../../babel.config.js',
  plugins: [
    [
      'module-resolver',
      {
        alias: {
          '@utils': './utils',
          '@components': './components',
        },
      },
    ],
  ],
};

@snaerth
Copy link

snaerth commented May 11, 2020

@snaerth

I had the same problem as you. I solved it by creating a specific babel.config.js for each package and extending it to the root babel.config.js.

packages
- package-1
-- utils
-- components
-- babel.config.js
- package-2
-- src
-- babel.config.js
babel.config.js

For each babel.config, I have this configuration:

module.exports = {
  extends: './../../babel.config.js',
  plugins: [
    [
      'module-resolver',
      {
        alias: {
          '@utils': './utils',
          '@components': './components',
        },
      },
    ],
  ],
};

@avallonazevedo fantastic thank you

@snaerth
Copy link

snaerth commented May 12, 2020

@avallonazevedo this does not work when you have babelrcRoots configured.
This is my base config

module.exports = api => {
  api.cache(true);

  const presets = [
    [
      '@babel/env',
      {
        targets: {
          browsers: ['last 2 versions', 'safari >= 10', 'ie 11'],
        },
        // Exclude transforms that make all code slower
        exclude: ['transform-typeof-symbol'],
      },
    ],
    '@babel/react',
    '@babel/flow',
  ];

  const plugins = [
    '@babel/plugin-transform-modules-commonjs',
    '@babel/plugin-proposal-object-rest-spread',
    '@babel/plugin-transform-regenerator',
    '@babel/plugin-transform-runtime',
    // insert before @babel/plugin-proposal-class-properties
    '@babel/plugin-transform-flow-strip-types',
    [
      '@babel/plugin-proposal-class-properties',
      {
        loose: true,
      },
    ],
  ];

  const env = {
    development: {
      plugins: ['react-hot-loader/babel'],
    },
    production: {
      plugins: [
        '@babel/plugin-transform-react-constant-elements',
        '@babel/plugin-transform-react-inline-elements',
      ],
    },
  };

  const babelrcRoots = [
    // Keep the root as a root
    '.',
    // Also consider monorepo packages "root" and load their .babelrc.json.
    './packages/*',
  ];

  return {
    presets,
    plugins,
    env,
    babelrcRoots,
    ignore: ['node_modules'],
  };
};

and this is the package config

module.exports = api => {
  api.cache(true);

  const plugins = [
    [
      'module-resolver',
      {
        alias: {
          '@static': './static',
        },
      },
    ],
  ];

  return {
    extends: "../../babel.config.js",
    plugins,
  };
};

And the error is classic
Error: .babelrcRoots is not allowed in .babelrc or "extends"ed files, only in root programmatic options, or babel.config.js/config file options

@avallonazevedo
Copy link

@snaerth

Did you try to remove babelrcRoots? I believe that by placing the babel.config.js configuration in each package, babelrcRoots becomes unnecessary, correct?

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

No branches or pull requests

4 participants