Skip to content
This repository was archived by the owner on Sep 29, 2020. It is now read-only.
This repository was archived by the owner on Sep 29, 2020. It is now read-only.

Support Node 10 ECMAScript Modules #151

@dantman

Description

@dantman

Node has implemented native support for ES2015 modules with an .mjs extension. True modules that function according to the spec.

One limitation of the spec differences between real ES modules and CommonJS modules is that imports from CommonJS modules cannot use named imports, the entire exports/module.exports object is just exposed as the default export.

For core-decorators this results in the following:
https://github.com/dantman/core-decorators-esm-test

core-decorators-modules daniel$ npm start

> core-decorators-modules@1.0.0 start /private/tmp/core-decorators-modules
> npm run run:babel && npm run run:esm


> core-decorators-modules@1.0.0 run:babel /private/tmp/core-decorators-modules
> babel test.js > babel-test.js && node babel-test.js

{ override: [Getter],
  deprecate: [Getter],
  deprecated: [Getter],
  suppressWarnings: [Getter],
  memoize: [Getter],
  autobind: [Getter],
  readonly: [Getter],
  enumerable: [Getter],
  nonenumerable: [Getter],
  nonconfigurable: [Getter],
  debounce: [Getter],
  throttle: [Getter],
  decorate: [Getter],
  mixin: [Getter],
  mixins: [Getter],
  lazyInitialize: [Getter],
  time: [Getter],
  extendDescriptor: [Getter],
  profile: [Getter],
  applyDecorators: [Getter] }

> core-decorators-modules@1.0.0 run:esm /private/tmp/core-decorators-modules
> node --experimental-modules test.mjs

(node:22402) ExperimentalWarning: The ESM module loader is experimental.
{ default:
   { override: [Getter],
     deprecate: [Getter],
     deprecated: [Getter],
     suppressWarnings: [Getter],
     memoize: [Getter],
     autobind: [Getter],
     readonly: [Getter],
     enumerable: [Getter],
     nonenumerable: [Getter],
     nonconfigurable: [Getter],
     debounce: [Getter],
     throttle: [Getter],
     decorate: [Getter],
     mixin: [Getter],
     mixins: [Getter],
     lazyInitialize: [Getter],
     time: [Getter],
     extendDescriptor: [Getter],
     profile: [Getter],
     applyDecorators: [Getter] } }

You cannot import {autobind} from 'core-decorators'; inside of ESM code. Your only option is to import CD from 'core-decorators'; const {autobind} = CD;.

To make it possible to use named imports from core-decorators I think it would be a good idea to support Node 10's ES modules.

Doing this should be pretty simple for core-decorators, as core-decorators is a leaf package (a package with no dependencies).
We just need to export another build in the package that uses ES modules like es/ does but uses the .mjs file extension.
Also ESM modules use the same main as normal Node modules, you just specify main without an extension and Node 9- will get your CommonJS .js and Node 10/--experimental-modules will get the ESM .mjs. So either the .mjs build will need to be in lib/ or you'll need an index.js and index.mjs in the package root to switch between module.exports = require('./lib'); and export * from './esm';.

Given how ESM works, I think the ecosystem would adapt to ESM easiest if leaf packages like core-decorators are the first to support ESM. (Then packages with dependencies on leaf packages don't need to worry about importing CommonJS versions of leaf packages)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions