Skip to content
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

Workaround for loading ESM #47

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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