-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Improve CJS and ESM module support #1037
Conversation
First of all thank you very much for looking into this. I'm using node 12 and did this:
I had to update the Gruntfile to make it run. Did I do something wrong or did this run through on your end? diff --git a/Gruntfile.js b/Gruntfile.js
index 8814780e..443bf901 100755
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -369,8 +369,8 @@ module.exports = function (grunt) {
command: chainCommands([
"echo '\n--- Regenerating config files. ---'",
"echo [] > src/core/config/OperationConfig.json",
- "node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
- "node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
+ "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
+ "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
"echo '--- Config scripts finished. ---\n'"
]),
sync: true
I'll look into the actual performance stuff now. I don't think console.time works in this case, I assume the |
Same when running diff --git a/Gruntfile.js b/Gruntfile.js
index 8814780e..853e30fc 100755
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -369,8 +369,8 @@ module.exports = function (grunt) {
command: chainCommands([
"echo '\n--- Regenerating config files. ---'",
"echo [] > src/core/config/OperationConfig.json",
- "node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
- "node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
+ "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
+ "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
"echo '--- Config scripts finished. ---\n'"
]),
sync: true
@@ -378,7 +378,7 @@ module.exports = function (grunt) {
generateNodeIndex: {
command: chainCommands([
"echo '\n--- Regenerating node index ---'",
- "node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
+ "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
"echo '--- Node index generated. ---\n'"
]),
sync: true
|
So this definitely helped a lot, here's a more realistic test that shows a rough 50% improvement. require.js const chef = require('./CyberChef/src/node/wrapper.js');
console.log(chef.fromBase64("U28gbG9uZyBhbmQgdGhhbmtzIGZvciBhbGwgdGhlIGZpc2gu")); import.mjs import chef from './CyberChef/src/node/index.mjs';
console.log(chef.fromBase64("U28gbG9uZyBhbmQgdGhhbmtzIGZvciBhbGwgdGhlIGZpc2gu"));
Now let's see if I can compile CyberChef down to a single file using ncc, that would be amazing. Because it's still a lot of files that need to be loaded. I'll report back. |
For ncc (and node in general?) these Webpack specific parts are still a problem CyberChef/src/core/operations/AddTextToImage.mjs Lines 139 to 144 in 4c3324a
|
35b6049
to
01fafaf
Compare
@Prinzhorn I also ran into those issues (and so did our CI) so I've put those fixes onto this branch 👍 I have never tried to use ncc, please let us know if you find a solution. Some UI-specific operations are bound to fail in the NodeJS API. I think we haven't come across them all yet because, like the example you've shown above, they'll only try and import those files when the function is run. Feel free to raise a separate issue for that. Node does support dynamic import. As I said, if you do look into that issue, let us know what you find |
The changes in this branch have been merged in v9.33.0 #1326 |
Functional changes:
exports
inpackage.json
to explicitly define entrypoints forimport
andrequire
routesload via
require
Loading via require will take you to the esm wrapped module which exports the top-level ESModule as a CJS module. This provides full compatibility with ESM modules, but loading takes a performance hit, as shown in this PR
Performance profile
load via
import
Node.js as increasing support for ESM / CJS interoperability. We can use this with a couple of extra flags. A consumer will need to use
--experimental-json-modules
to load JSON files as modules, and--experimental-specifier-resolution
to resolve non-explicit imports in our dependencies.Performance profile
Later Node.js versions
I've tested this with latest stable (14.3.0) - you don't need the
--experimental-modules
flag but you do need the other two when usingimport
.