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

@babel-register is not configurable when used with ES Modules (--experimental-modules) #6737

Open
feross opened this Issue Nov 3, 2017 · 8 comments

Comments

Projects
None yet
7 participants
@feross

feross commented Nov 3, 2017

Choose one: is this a bug report or feature request? Bug report

Input Code

import babelRegister from '@babel/register'
babelRegister({ extensions: '.xxx' })

Babel/Babylon Configuration (.babelrc, package.json, cli command)

The specific config I'm using should not be relevant, but I'm providing it just in case.

{
    "plugins": [
      "transform-class-properties",
      [
        "transform-react-jsx",
        {
          "pragma": "h",
          "useBuiltIns": true
        }
      ],
      "transform-object-rest-spread"
    ]
  }

Expected Behavior

Invoking Node.js 8 LTS or Node.js 9 with the --experimental-modules command line flag enables built-in support for ES Modules. When this option is passed, the entry-point file must be an ES Module, which requires the use of import statements; require is not available. Using import on CommonJS modules is supported.

I expect that invoking the following code will change the babel-register configuration:

node --experimental-modules index.mjs
// index.mjs
import babelRegister from '@babel/register'
babelRegister({ extensions: '.xxx' })

// babel-register should *not* transpile foo.mjs (because it has a .mjs extension)
import foo from './foo'
// foo.mjs
console.log('blah')

Current Behavior

The configuration stays unchanged even when following how the documentation says to configure babel-register.

Possible Solution

I think the reason might be that module loading with ES Modules is async, while CommonJS is sync. Does babel-register assume that the function to configure will be called in the first tick?

Context

Trying to using babel-register for server-side JSX support, while also using node's built-in ES Module support with the --experimental-modules flag.

Your Environment

software version(s)
Babel @babel/core 7.0.0-beta.4; @babel-register 7.0.0-beta.5
Babylon
node 8.9.0
npm 5.5.1
Operating System macOS 10.13.1
@babel-bot

This comment has been minimized.

Show comment
Hide comment
@babel-bot

babel-bot Nov 3, 2017

Collaborator

Hey @feross! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

Collaborator

babel-bot commented Nov 3, 2017

Hey @feross! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@hzoo hzoo added the area: modules label Nov 3, 2017

@loganfsmyth

This comment has been minimized.

Show comment
Hide comment
@loganfsmyth

loganfsmyth Nov 3, 2017

Member

I don't believe Node's ES6 import statements will run require hooks, so I don't think there is any way for babel to hook into those, at least currently.

Member

loganfsmyth commented Nov 3, 2017

I don't believe Node's ES6 import statements will run require hooks, so I don't think there is any way for babel to hook into those, at least currently.

@feross

This comment has been minimized.

Show comment
Hide comment
@feross

feross Nov 4, 2017

@loganfsmyth Require hooks are getting run when using import on a CommonJS module (a file with a .js extension).

babel-register does run on this import:

import app from './app' // this references a commonjs file called app.js

But it does seem like when loading an ES Module, the hook isn't run.

feross commented Nov 4, 2017

@loganfsmyth Require hooks are getting run when using import on a CommonJS module (a file with a .js extension).

babel-register does run on this import:

import app from './app' // this references a commonjs file called app.js

But it does seem like when loading an ES Module, the hook isn't run.

@Kovensky

This comment has been minimized.

Show comment
Hide comment
@Kovensky

Kovensky Nov 4, 2017

Member

It's not possible to configure babelRegister because all import calls are finished by the time your babelRegister call happens.

You either have to import a module that will then call babelRegister for you, or you have to use dynamic import()s for loading anything you need to be processed by the configured babelRegister.

Now, I believe that babelRegister working at all was probably not intentional; or at least I'm not sure if node still wants to keep require.extensions working even after deprecating it for years.


@loganfsmyth

NOTE: there is no guarantee that this is how it is intended to work. It is possible that @babel/register works on import-ed commonjs by accident instead of by design.

When something is imported (statically or dynamically), it goes through the ModuleRequest loader. The loader responsible for loading .js files, aka the cjs loader, just delegates it directly to the current commonjs loader, which happens to invoke handlers in require.extensions (how @babel/register installs itself).

However, there is a probably incomplete API for hooking into ESM imports as well, which may be usable in the future; but probably not via @babel/register.

Member

Kovensky commented Nov 4, 2017

It's not possible to configure babelRegister because all import calls are finished by the time your babelRegister call happens.

You either have to import a module that will then call babelRegister for you, or you have to use dynamic import()s for loading anything you need to be processed by the configured babelRegister.

Now, I believe that babelRegister working at all was probably not intentional; or at least I'm not sure if node still wants to keep require.extensions working even after deprecating it for years.


@loganfsmyth

NOTE: there is no guarantee that this is how it is intended to work. It is possible that @babel/register works on import-ed commonjs by accident instead of by design.

When something is imported (statically or dynamically), it goes through the ModuleRequest loader. The loader responsible for loading .js files, aka the cjs loader, just delegates it directly to the current commonjs loader, which happens to invoke handlers in require.extensions (how @babel/register installs itself).

However, there is a probably incomplete API for hooking into ESM imports as well, which may be usable in the future; but probably not via @babel/register.

@graingert

This comment has been minimized.

Show comment
Hide comment
@graingert

graingert Feb 19, 2018

Contributor

The --loader hook has now been documented: https://nodejs.org/api/esm.html#esm_loader_hooks

You can set it via --loader eg @babel/register could provide a @babel/register/index.mjs for using the node loader hooks.

Contributor

graingert commented Feb 19, 2018

The --loader hook has now been documented: https://nodejs.org/api/esm.html#esm_loader_hooks

You can set it via --loader eg @babel/register could provide a @babel/register/index.mjs for using the node loader hooks.

@pruett

This comment has been minimized.

Show comment
Hide comment
@pruett

pruett Jul 25, 2018

Could someone provide the full answer to this issue? Running into something similar. --loader doesn't seem to help

pruett commented Jul 25, 2018

Could someone provide the full answer to this issue? Running into something similar. --loader doesn't seem to help

@graingert

This comment has been minimized.

Show comment
Hide comment
@graingert

graingert Jul 25, 2018

Contributor

@pruett it's not implemented yet

Contributor

graingert commented Jul 25, 2018

@pruett it's not implemented yet

@pruett

This comment has been minimized.

Show comment
Hide comment
@pruett

pruett commented Jul 25, 2018

ah, thanks @graingert !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment