abraham / reflection

Lightweight (3K) ES Module implementation of reflect-metadata
https://www.npmjs.com/package/@abraham/reflection
MIT License
265 stars 14 forks source link

fix dual module types exporting #728

Closed forehalo closed 1 year ago

forehalo commented 2 years ago

the commonjs usage was broken in v0.11.0 release

> node -e "require('@abraham/reflection')" --input-type=commonjs
node:internal/modules/cjs/loader:1177
      throw err;
      ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /workspace/reflection/dist/index.umd.js from /workspace/reflection/[eval] not supported.
index.umd.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead rename index.umd.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /workspace/reflection/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

    at [eval]:1:1
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:313:38)
    at [eval]-wrapper:6:22 {
  code: 'ERR_REQUIRE_ESM'
}

nodejs doc reference:

Node.js will treat as CommonJS all other forms of input, such as .js files where the nearest parent package.json file contains no top-level "type" field, or string input without the flag --input-type. This behavior is to preserve backward compatibility. However, now that Node.js supports both CommonJS and ES modules, it is best to be explicit whenever possible. Node.js will treat the following as CommonJS when passed to node as the initial input, or when referenced by import statements, import() expressions, or require() expressions:

  • Files with a .cjs extension.

  • Files with a .js extension when the nearest parent package.json file contains a top-level field "type" with a value of "commonjs".

  • Strings passed in as an argument to --eval or --print, or piped to node via STDIN, with the flag --input-type=commonjs.

this fix is about the the second scenario, .js will be treated as ESModule if the type field in package.json is given module, and only the files with .cjs extension can be correctly required in a commonjs context.

two eval tests are added in gh actions as well, and they can simply tell whether the module system is broken in the incoming changes.

sublimator commented 1 year ago

@abraham

Bump :)

sublimator commented 1 year ago

Awesome :)