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

stop using esm for ES module loading #14

Merged
merged 9 commits into from
Dec 10, 2019

Conversation

dbushong
Copy link
Member

@dbushong dbushong commented Dec 6, 2019

BREAKING CHANGE: now if you want to use .mjs files, you need to run
with NODE_OPTIONS=--experimental-modules on Node 10.x+. Also, native
ES module loading is NOT compatible with coffeescript/register


This PR was started by: git wf pr

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

Additional worthy notes:

  • we've seen segfaults in the latest node 10.x during mjs loading that aren't reproducible on node 12.x.
  • std/esm allowed you to "import" foo.js with import foo from './foo'; - but node native requires import foo from './foo.js';

Copy link
Collaborator

@jkrems jkrems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@@ -1,2 +1,3 @@
/node_modules
/tmp
/lib/esm/import.js
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Would this be better as a glob-based override of the eslint settings in .eslintrc?

Copy link
Member Author

@dbushong dbushong Dec 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the next PR i'll upgrade our lint settings to ones that we can more usefully override to parse this correctly

@jkrems
Copy link
Collaborator

jkrems commented Dec 9, 2019

we've seen segfaults in the latest node 10.x during mjs loading that aren't reproducible on node 12.x.

Unfortunately there's no good way yet to tell if the current version of node has "real" ESM support. But I'm pretty sure that node 10 won't get backported, so maybe it would be best to restrict this to node 12+?

P.S.: Even for node 12 it's only "very likely" that we'll backport the final implementation over next few months.

Copy link
Member

@aotarola aotarola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💚

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

But I'm pretty sure that node 10 won't get backported, so maybe it would be best to restrict this to node 12+?

Sounds reasonable. Restrict with package.json engines.node and amending the comment to suggest Node 12+?

@jkrems
Copy link
Collaborator

jkrems commented Dec 9, 2019

I don't think I personally would bother with engines.node. It may be enough to call out in the README that ESM is only supported in version X of node but I would assume that if anybody is going out of their way to set --experimental-modules in node 10 and use this package, they "know" what they're doing.

BREAKING CHANGE: now if you want to use `.mjs` files, you should run
with `NODE_OPTIONS=--experimental-modules` on Node 12.x+.  Also, native
ES module loading is NOT compatible with coffeescript/register

Fixes: #11
@dbushong dbushong force-pushed the dbushong/feature/master/kill-esm-mod branch from 57a71df to 5608968 Compare December 9, 2019 19:20
@dbushong dbushong changed the title stop using esm for ES module loading [WIP] stop using esm for ES module loading Dec 9, 2019
@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

Turned on tests for 12.x and looks like there some bugs that need addressing if we'll be telling people to use 12. Will remove [WIP] when ready for re-review

@jkrems
Copy link
Collaborator

jkrems commented Dec 9, 2019

Can you try it with 13.x, potentially even without the experimental flag? There's quite a big delta between what's in 12/experimental and the code in 13.

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

The 12.x issue is something we've seen before that's not related (AFAWCT) directly to ES Modules - it seems to be related to a change in how paths are cached inside the under-documented Module class instances. Will update as I investigate.

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

e.g.:

$ nvm run 10 foo.js
Running node v10.17.0 (npm v6.11.3)
{ name: 'nilo-project' }
{ name: 'nilo-cli' }
$ nvm run 12 foo.js
Running node v12.13.0 (npm v6.12.0)
{ name: 'nilo-project' }
{ name: 'nilo-project' }

for foo.js:

'use strict';

const Module = require('module');

const { _nodeModulePaths: getPaths } = Module;

const m1 = new Module('<project>');
m1.filename = `${__dirname}/examples/project/app`;
m1.paths = getPaths(m1.filename);

const m2 = new Module('<cli>');
m2.filename = `${__dirname}/examples/cli/app`;
m2.paths = getPaths(m2.filename);

console.log(m1.require('./package.json'));
console.log(m2.require('./package.json'));

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

Seems like maybe we should just move to using createRequire():

'use strict';

const Module = require('module');

const { createRequire, createRequireFromPath } = Module;

const createReq = createRequire || createRequireFromPath;

const r1 = createReq(`${__dirname}/examples/project/app`);
const r2 = createReq(`${__dirname}/examples/cli/app`);

console.log(r1('./package.json'));
console.log(r2('./package.json'));
$ nvm run 12 foo.js
Running node v12.13.0 (npm v6.12.0)
{ name: 'nilo-project' }
{ name: 'nilo-cli' }
$ nvm run 10 foo.js
Running node v10.17.0 (npm v6.11.3)
{ name: 'nilo-project' }
{ name: 'nilo-cli' }

(maybe leaving the current implementation in to make 8 happy)

@jkrems
Copy link
Collaborator

jkrems commented Dec 9, 2019

Oh, yeah. createRequire is a lot more reliable. Good point!

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

Fun interesting node 10 -> 12 behavior change in Proxy:

$ nvm run 10 foo.js
Running node v10.17.0 (npm v6.11.3)
{ x: 1,
  [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]] }
$ nvm run 12 foo.js
Running node v12.13.0 (npm v6.12.0)
inspected: 2
'use strict';

const INSPECT = require('util').inspect.custom;

const a = {
  x: 1,
  [INSPECT]() {
    return `inspected: ${this.x}`;
  },
};
const b = new Proxy(a, { get: () => 2 });
console.log(b);

@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

Maybe related: nodejs/node#26241

@dbushong dbushong force-pushed the dbushong/feature/master/kill-esm-mod branch from 0cb2b14 to 9b5b703 Compare December 9, 2019 23:14
@dbushong dbushong changed the title [WIP] stop using esm for ES module loading stop using esm for ES module loading Dec 9, 2019
@dbushong
Copy link
Member Author

dbushong commented Dec 9, 2019

Ready for re-review; thanks

Copy link
Member

@aotarola aotarola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💚

@dbushong dbushong merged commit 4ab103d into master Dec 10, 2019
@dbushong dbushong deleted the dbushong/feature/master/kill-esm-mod branch December 10, 2019 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants