microsoft / tslib

Runtime library for TypeScript helpers.
BSD Zero Clause License
1.26k stars 128 forks source link

support node ESModules via --experimental-modules flag #44

Closed trxcllnt closed 4 years ago

trxcllnt commented 6 years ago

This PR adds support for importing tslib in node running with the --experimental-modules flag:

  1. Adds a "prepublishOnly" script to copy tslib.es6.js to tslib.mjs just before publishing to npm (not windows compatible afaik -- wanted to avoid adding an shx devDependency)
  2. Removes the file extension from the "main": "tslib.js" package.json entry
  3. Adds a "files" entry in package.json
  4. Add "tslib.mjs" entry to .gitignore

Steps 1-2 are necessary because node will automatically select either the "js" or "mjs" file depending on whether it was run with the --experimental-modules flag, but only if the "main" entry doesn't explicitly specify a file extension.

Step 3 ensures the gitignore'd tslib.mjs file is included in the assets published to npm. Step 4 ensures the mjs file is always in line with the tslib.es6.js file, and avoids source code duplication.

ESModules in node >= 8.6.0

If you attempt to import a CommonJS module as an ESModule (either by explicitly importing the "js" version, or if there's no explicit extension and no "mjs" file available), node will synthesize a default export from the "module.exports" object, leading to the following error condition:

// $ node index.js
const tslib = require('tslib');
// works like normal
tslib_1.__awaiter(/* some code generated by TypeScript */);
// $ node --experimental-modules index.mjs
import * as tslib from 'tslib';
// throws "TypeError: tslib_1.__awaiter is not a function"
tslib_1.__awaiter(/* some code generated by TypeScript */);
screen shot 2017-11-20 at 1 06 41 pm

I believe this PR is the less invasive of two possible approaches, as it shouldn't break anyone who has hard-coded references to tslib.es6.js in their builds (e.g. for closure compiler). Alternatively, we could rename tslib.es6.js -> tslib.mjs (branch).

For context: the Apache Arrow JS project is written in TypeScript, and we're targeting full compatibility with node's new --experimental-modules flag.

The last step in our upgrade process is helping ensure our dependencies expose node v8.6.0+ compatible ESModules. Please let me know if there's anything else I can do to help get this PR accepted, and a new version published soon. Thanks!

msftclas commented 6 years ago

CLA assistant check
All CLA requirements met.

dasa commented 5 years ago

Hopefully this PR or one like it can be merged soon 🙏

sla100 commented 4 years ago

The title can be cleaned from "--experimental-modules". Since version 13 Node supports them directly

ExE-Boss commented 4 years ago

This has the issue that existing imports of tslib/tslib.es6.js will remain broken.

I’ve opened https://github.com/microsoft/tslib/pull/87 to do this using conditional exports.