-
Notifications
You must be signed in to change notification settings - Fork 11
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
Refactor codebase from CommonJS to ESM #177
Conversation
Find/replace: ``` const (.*?) = require\((.*?)\); import $1 from $2; ```
Find replace: ``` module\.exports = \{ export { ``` ``` module\.exports = (.*?); export default $1; ```
53991be
to
bcb02f8
Compare
const hydrogenRenderModule = new vm.SourceTextModule(hydrogenRenderScriptCode, { | ||
identifier: path.basename(vmRenderScriptFilePath), | ||
context: vmContext, | ||
}); | ||
// TODO: This is crazy compared to the normal `vm.Script(...)` API and this doesn't | ||
// work at the moment because it only handles ESM imports or exports, idk. Too much BS | ||
// if I just want the behavior that Node.js already provides by default. | ||
// | ||
// And the only reason we need to use `vm.SourceTextModule` is because we need see | ||
// `SyntaxError: Cannot use import statement outside a module` in the script we try to | ||
// run with `vm.Script(...)` and `vm.runInContext(vmContext);`. | ||
// | ||
// XXX: This is crazy to handle on our own! | ||
// https://github.com/nodejs/node/issues/31234 Also see | ||
// https://github.com/nodejs/node/issues/35848 | ||
await hydrogenRenderModule.link((specifier, referencingModule) => { | ||
return new Promise(async function (resolve, reject) { | ||
const mod = await import(specifier); | ||
resolve( | ||
new vm.SyntheticModule(['default'], function () { | ||
this.setExport('default', mod.default); | ||
}) | ||
); | ||
}); | ||
}); | ||
// Note: The VM does not exit after the result is returned here and is why | ||
// this should be run in a `child_process` that we can exit. | ||
const vmResult = hydrogenRenderScript.runInContext(vmContext); | ||
// Wait for everything to render | ||
// (waiting on the promise returned from the VM render script) | ||
await vmResult; | ||
await hydrogenRenderModule.evaluate(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This area will be the downfall of this migration 😢
With the previous new vm.Script(code).runInContext(vmContext)
, we see SyntaxError: Cannot use import statement outside a module
after the ESM refactor
Which prompted an update to new vm.SourceTextModule(...) ...
but this API surface is crazy and expects to implement our own linker
when I just want default Node.js behavior.
- Simplify vm.Module nodejs/node#43899
- Provide built-in implementations of module linker, initializeImportMeta, importModuleDynamically nodejs/node#31234
- Link modules with paths in module.link(linker) nodejs/node#35848
- Linking cycle with
vm.SourceTextModule
nodejs/help#3535
The linker I tried to copy from the above issues isn't sufficient because it doesn't handle the menagerie of Node.js specific behavior or event CommonJS modules. We would have to do something much more robust like these (crazy):
- https://github.com/jestjs/jest/blob/6e95bdcbf9e5c2e354f277d0db6e4dff1ad2c43f/packages/jest-runtime/src/index.ts#L474-L513
- https://github.com/cloudflare/miniflare/blob/2d0fbc624bfa46a31f6c47f342a96ce7fdddebd2/packages/runner-vm/src/linker.ts#L57-L167
The new vm.Script(...)
API (or some API) should handle all of the complexity of whether I used import
or require
syntax and just load dependencies (sane defaults please).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(giving up for now ⏩)
Refactor codebase from CommonJS to ESM
Spawning from the
gulp-rev
dependency in #175 being ESM which kinda necessitates that we also switch over.Dev notes
See https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c