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

CommonJS import from a Module package too inflexible #39052

Closed
k2snowman69 opened this issue Jun 16, 2021 · 3 comments
Closed

CommonJS import from a Module package too inflexible #39052

k2snowman69 opened this issue Jun 16, 2021 · 3 comments

Comments

@k2snowman69
Copy link

  • Version: v14.17.1
  • Platform: Microsoft Windows NT 10.0.19042.0 x64
  • Subsystem:

What steps will reproduce the bug?

Whenever a consuming npm package is type: module it seems to be much picker about importing packages of which distribute cjs style code via import { bar } from "../lib/factory.js";. This limitation prevents consuming libraries from using type: module until all the dependent libraries are fixed and corrected which slows adoption.

To give an example I've created a repository https://github.com/k2snowman69/bug-nodejs-import-cjs which has two folders

  • lib - Contains trimmed down versions of three different styles of cjs outputs I've found (glob, dropbox and tslib). I stopped at three because it got the point across
  • use-lib - an ESM package that consume the three different styles of CJS outputs

How often does it reproduce? Is there a required condition?

Every time across multiple versions of node

What is the expected behavior?

When running any of the following:

  • node .\use-lib\use-define-property.js
  • node .\use-lib\use-factory.js
  • node .\use-lib\use-function.js

All three succeed in executing. This would mean that even though a dependency of my project might not be written in ESM or be rewritten using the Object.defineProperty style of CJS, that I'm able to use ESM style for my particular project though lose on some of the major benefits if that dependency were written in ESM.

What do you see instead?

If the commonjs library dist output uses the Object.defineProperty to build it's output, it works successfully, however the other two solutions seem to break.

PS D:\Projects\bug-nodejs-import-cjs> node .\use-lib\use-define-property.js
bar

PS D:\Projects\bug-nodejs-import-cjs> node .\use-lib\use-factory.js
file:///D:/Projects/bug-nodejs-import-cjs/use-lib/use-factory.js:1
import { bar } from "../lib/factory.js";
         ^^^
SyntaxError: Named export 'bar' not found. The requested module '../lib/factory.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '../lib/factory.js';
const { bar } = pkg;

←[90m    at ModuleJob._instantiate (internal/modules/esm/module_job.js:120:21)←[39m
←[90m    at async ModuleJob.run (internal/modules/esm/module_job.js:165:5)←[39m
←[90m    at async Loader.import (internal/modules/esm/loader.js:177:24)←[39m
←[90m    at async Object.loadESM (internal/process/esm_loader.js:68:5)←[39m

PS D:\Projects\bug-nodejs-import-cjs> node .\use-lib\use-function.js
file:///D:/Projects/bug-nodejs-import-cjs/use-lib/use-function.js:1
import { bar } from "../lib/function.js";
         ^^^
SyntaxError: Named export 'bar' not found. The requested module '../lib/function.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '../lib/function.js';
const { bar } = pkg;

←[90m    at ModuleJob._instantiate (internal/modules/esm/module_job.js:120:21)←[39m
←[90m    at async ModuleJob.run (internal/modules/esm/module_job.js:165:5)←[39m
←[90m    at async Loader.import (internal/modules/esm/loader.js:177:24)←[39m
←[90m    at async Object.loadESM (internal/process/esm_loader.js:68:5)←[39m

Additional information

This is my first bug in such a public space and I'm a bit nervous, feel free to ask me to reorganize or cleanup the original description to make it easier to understand. Any suggestions would be great, I'm trying to get better at writing issues!

@aduh95
Copy link
Contributor

aduh95 commented Jun 16, 2021

This should be reported to https://github.com/guybedford/cjs-module-lexer – Node.js uses the module lexer to parse CJS modules to try to "guess" which exports it may have. It won't ever have a 100% success rate because CJS allows to define exports is very abstruse ways (module[Array.from("stropxe").reverse().join()] = "I'm a CJS export!"), which is why the error message suggest to use the default export instead. That being said, Object.defineProperty is listed in the supported grammar so it looks like it is a bug indeed.

@k2snowman69
Copy link
Author

Gotcha, I'll copy and paste the contents of my message into an issue in that repository

@k2snowman69
Copy link
Author

Closing now that the issue has been created on the partner repo

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

2 participants