Skip to content

Commit

Permalink
Add workaround for loading ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
JulioC committed Sep 2, 2023
1 parent b6bc035 commit 4ea4c11
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 0 deletions.
5 changes: 5 additions & 0 deletions bench/esm/import-chalk.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(async () => {
// Evaluating the dynamic import is a workaround for loading ESM in CJS files
const { default: chalk } = await (Function(`return import("chalk")`)());
console.log(chalk.blue("Hello World"));
})();
5 changes: 5 additions & 0 deletions bench/esm/import-local-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(async () => {
// Evaluating the dynamic import is a workaround for loading ESM in CJS files
const {default: log} = await (Function(`return import("./local-file.mjs")`)());
log();
})();
3 changes: 3 additions & 0 deletions bench/esm/local-file.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function () {
console.log('Hello World')
}
15 changes: 15 additions & 0 deletions bench/require-import-chalk.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env node
'use strict';

const WITH_CACHE = true;

require('./_measure.js')('require-chalk', WITH_CACHE, () => {
// Node introduced support for dynamics import in v12
const NODE_MAJOR_VERSION = process.versions.node.split('.')[0];
if (NODE_MAJOR_VERSION < 12) {
return;
}

process.argv.push('config', 'get', 'init.author.name');
require('./esm/import-chalk.js');
});
15 changes: 15 additions & 0 deletions bench/require-import-local-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env node
'use strict';

const WITH_CACHE = true;

require('./_measure.js')('require-local-file', WITH_CACHE, () => {
// Node introduced support for dynamics import in v12
const NODE_MAJOR_VERSION = process.versions.node.split('.')[0];
if (NODE_MAJOR_VERSION < 12) {
return;
}

process.argv.push('config', 'get', 'init.author.name');
require('./esm/import-local-file.js');
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"dependencies": {},
"devDependencies": {
"babel-core": "6.26.3",
"chalk": "^5.3.0",
"eslint": "^7.12.1",
"flow-parser": "0.136.0",
"rimraf": "^2.5.4",
Expand Down
5 changes: 5 additions & 0 deletions sandbox-esm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(async () => {
require("../v8-compile-cache.js");
require('../bench/esm/import-chalk.js');
require('./requires-local-file/requires-local-file.js');
})();
23 changes: 23 additions & 0 deletions v8-compile-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,35 @@ class NativeCompileCache {

var buffer = this._cacheStore.get(filename, invalidationKey);

var _this = this;

var script = new vm.Script(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true,
cachedData: buffer,
produceCachedData: true,
// Allow importing ESM with import() (otherwise throws "A dynamic import callback was not specified.")
// See https://nodejs.org/dist/latest-v20.x/docs/api/vm.html#new-vmscriptcode-options
// See https://github.com/nodejs/node/blob/3a6a80a4e1ad3fc3f1b181e1c94ecfd0b17e6dd1/test/parallel/test-vm-module-dynamic-import.js#L10
importModuleDynamically: function(specifier) {
// Disable cache if script uses dynamic imports (otherwise throws "Invalid host defined options")
_this._cacheStore.delete(filename);

// Resolve specifier in filename directory to allow importing local files
// There might be other paths to be included here
var paths = [
path.dirname(filename)
].concat(require.resolve.paths(filename))
var resolved = require.resolve(specifier, { paths });

// This will only work on Node >=10.12.0
var url = require('url');
var importSpecifier = url.pathToFileURL(resolved)

// Dynamic import, should be supported by Node if importModuleDynamically is called
return import(importSpecifier);
},
});

if (script.cachedDataProduced) {
Expand Down

0 comments on commit 4ea4c11

Please sign in to comment.