-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[JS]: Add support for node ESModules with --experimental-modules flag #4504
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
Conversation
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
|
I signed the CLA with the email [email protected]. |
|
CLAs look good, thanks! |
|
Not being a JS expect, it is not obvious to me that this supports all JS versions on all platforms, in/outside browser, TypeScript, Windows etc. This makes use of some scripting to generate @krojew for TS. Any other JS users want to chime in? |
Absolutely! You can preview changes to the npm package proposed in this PR at trxcllnt/flatbuffers-esm. The Arrow project is presently depending on this instead of the mainline Excepting those pulling the file from source-control, this PR won't affect anyone currently relying on the existing This PR adds support for importing I'm not necessarily a fan of the scripts that create the The JS lib seems mature enough that it doesn't require frequent updates or complex build tools. It's reasonable to revisit this assumption if the project does one day resume extensive active development. Building on Windows:It's my understanding the A bit about me:I'm @ReactiveX core team member and Apache contributor on Arrow. I coauthored A bit about Arrow:The Arrow project is written in TypeScript. We compile the TS source to a 3x3 matrix of supported JS versions and module formats, as well as ES6 + ESModule ".mjs" files for use in node with the At the moment we have a battery of 117,420 unit and integration tests that are executed against each of compilation targets to ensure compatibility and correctness across the entire matrix. |
|
From the TS point of view, I don't see any problems. TS code only assumes flatbuffers are available (via typings) and the resulting JS code will have it available using the user-chosen import method, whatever that will be. |
…les support Updates the `text-encoding-utf-8` dependency to version 1.0.2, [which now supports](arv/text-encoding-utf-8#2) ESModules in node >= v8.6.0 via the `--experimental-modules` flag. We currently support ESModules in node in the main `apache-arrow` package, but need our dependencies to also expose ESModule forms as well. I have also issued a [PR to flatbuffers](google/flatbuffers#4504) to add ESModules support, and are using a temporary [fork of flatbuffers](https://github.com/trxcllnt/flatbuffers-esm) in my github until that PR is merged. This PR enables the following workflow: ```js // file - index.mjs // run via `node --experimental-modules index.mjs` import util from 'util'; import * as fs from 'fs'; import { Table } from 'apache-arrow'; (async () => { const buffer = await util.promisify(fs.readFile)('simple.arrow'); console.log(Table.from([buffer]).toString()); /* foo, bar, baz 1, 1, aa null, null, null 3, null, null 4, 4, bbb 5, 5, cccc */ })(); ``` Author: Paul Taylor <[email protected]> Closes #1338 from trxcllnt/update-text-encoding-utf8 and squashes the following commits: fbecde5 [Paul Taylor] synthesize an mjs file for tslib on postinstall 4b050c9 [Paul Taylor] update text-encoding-utf-8 dependency with node ESModules support
|
I'd prefer it if this keeps working for people who work directly with our repo, I am sure there are some :) If the We've tried to make changes to importing before, and it broke people using the Closure compiler. Is this likely to affect it? (again, not a JS expert :) |
|
@aardappel I don't expect it to break anybody using Closure compiler. The full diff of changes to the - // Exports for Node.js and RequireJS
- this.flatbuffers = flatbuffers;
/// @endcond
/// @}
+
+ // Exports for Node.js and RequireJS
+ this.flatbuffers = flatbuffers;To any JS interpreter, we just moved the I can't say conclusively whether this would matter to older versions of the Closure compiler, but since I can't find any references to We compile ES6 to ES5 in the Arrow build via Closure compiler with advanced optimizations. This is a relatively new feature in Closure compiler, and they don't allow you to mix JS module systems, so adding the |
Ah, then feel free to commit the |
|
I'm confused, are you going to make changes such that |
|
@aardappel oh, yeah! sorry, I wasn't sure if you wanted to defer that decision until after this PR is merged or not. Will commit that here in a bit. |
ac9ad52 to
f7f8450
Compare
|
@aardappel added the files and rebased from master 👍 |
|
Ok, so now I wonder, given that |
|
@aardappel after this PR, flatbuffers.src.js is the source of truth, and
Node needs the
Yes that would be my preference (and why I'd gitignore'd the generated files initially), but you raised concerns people may be linking to the files directly via git instead of using the published packages, and I'm happy to defer to you here. |
|
Well, I'd prefer it if |
|
@aardappel we can do that, but removing the legacy commonJS export from If you're fine with that, then we'd need to rename the derived files to something like Do you want to schedule a quick hangout or slack call to discuss options? You can reach me at the email in my github profile, or via [email protected] |
|
@aardappel alternatively I could use |
|
@trxcllnt I've sent you a hangouts invite. Apologies if this is drawn-out, my understanding of the JS eco-system is minimal, and I am wary of breaking existing users (and copies of in repos :) Is there no way to if-then around the offending statement? |
|
@aardappel awesome, thanks! I'm available now in hangouts |
f7f8450 to
47b38d5
Compare
|
@aardappel alright, good to go! I'd mixed up sed and awk, meant to say sed before. So now the |
|
LGTM! |
|
@aardappel shouldn't be. If you're using |
|
I'm on 3.10.10 for some reason. Noted :) Thanks for your persistence :) |
…les support Updates the `text-encoding-utf-8` dependency to version 1.0.2, [which now supports](arv/text-encoding-utf-8#2) ESModules in node >= v8.6.0 via the `--experimental-modules` flag. We currently support ESModules in node in the main `apache-arrow` package, but need our dependencies to also expose ESModule forms as well. I have also issued a [PR to flatbuffers](google/flatbuffers#4504) to add ESModules support, and are using a temporary [fork of flatbuffers](https://github.com/trxcllnt/flatbuffers-esm) in my github until that PR is merged. This PR enables the following workflow: ```js // file - index.mjs // run via `node --experimental-modules index.mjs` import util from 'util'; import * as fs from 'fs'; import { Table } from 'apache-arrow'; (async () => { const buffer = await util.promisify(fs.readFile)('simple.arrow'); console.log(Table.from([buffer]).toString()); /* foo, bar, baz 1, 1, aa null, null, null 3, null, null 4, 4, bbb 5, 5, cccc */ })(); ``` Author: Paul Taylor <[email protected]> Closes #1338 from trxcllnt/update-text-encoding-utf8 and squashes the following commits: fbecde59 [Paul Taylor] synthesize an mjs file for tslib on postinstall 4b050c95 [Paul Taylor] update text-encoding-utf-8 dependency with node ESModules support
This PR adds support for using
flatbufferswith node's new--experimental-modulesflag which natively supports ESModules:this.flatbuffers = flatbuffers;line from the end of the source filejs/flatbuffers.jstojs/flatbuffers.src.js, in order to maintain backwards-compatabilitya.
js/flatbuffers.jswiththis.flatbuffers = flatbuffers;appended to the end for CommonJS/RequireJS backwards-compatb.
js/flatbuffers.mjswithexport { flatbuffers };appended to the end for ESModules"main": "js/flatbuffers.js"entry in package.json (so it is now just"main": "js/flatbuffers")"module": "js/flatbuffers.mjs"definition in the package.json, for compatibility with Closure Compiler"files"entry in package.json to publish["js/flatbuffers.js", "js/flatbuffers.mjs"]Items 2-4 are necessary because node will automatically select either the "js" or "mjs" file depending on whether it was run with the
--experimental-modulesflag, but only if the "main" entry doesn't explicitly specify a file extension.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:
Item 5 is necessary support newer builds of Closure Compiler that support compiling ESModules with the
module_resolution: "NODE"compiler flag:closure-compiler --module_resolution=NODE \ # select dep package.json "module" entries before "main" --package_json_entry_names=module,main \ --js=node_modules/flatbuffers/package.json \ --js=node_modules/flatbuffers/js/flatbuffers.mjs \ --entry_point=index.jsFor context: the Apache Arrow project is based on flatbuffers, and we compile ES6 -> ES5 JS bundles with closure-compiler + advanced optimizations.
Recently closure-compiler's ESModules support has improved to the point where we can use it directly, instead of duplicating and maintaining dependency sources in our project. We also support importing Arrow as ESModules in node directly with the
--experimental-modulesflag.The last step in this process is helping ensure our dependencies expose closure-compiler and 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!