-
Notifications
You must be signed in to change notification settings - Fork 296
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
Node.js Compat: Implement the nodejs_compat_v2 compat flag #2147
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
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.
I can't judge the implementation soundness, but I was able to play with this and can confirm that with the nodejs_compat_v2
flag Buffer
and process
are now exposed, however global
is not. Could you please add that?
I was also able to do some basic experiments with process.getBuiltinModule
which also seems to work as expected. I did not test if overwriting a built-in using a user-provided module results in no change for the getBuiltinModule - this would be a good thing to add to an automated test.
Can you please add a test or sample for this functionality?
Otherwise this change looks good to me and will unblock our work on hybrid polyfills (unjs/unenv#181). Thank you for a speedy turnaround.
To recap the todos:
- expose
global
- add tests
FYI here is my test code:
import path from 'path';
import npath from 'node:path';
export default {
async fetch(req, env) {
return new Response("Hello World\n" +
(('Buffer' in globalThis) ? Buffer : "xBufferx") + '\n' +
(('process' in globalThis) ? JSON.stringify(Object.keys(process)) : 'xprocessx') + '\n' +
(JSON.stringify(Object.keys(process.getBuiltinModule('path')))) + '\n' +
(JSON.stringify(Object.keys(path))) + '\n' +
(JSON.stringify(Object.keys(npath))) + '\n'+
(('global' in globalThis) ? global : "xglobalx") + '\n'
);
}
};
e8de45c
to
da49fdb
Compare
This comment was marked as resolved.
This comment was marked as resolved.
da49fdb
to
e8a1f7f
Compare
@fhanau @harrishancock @dom96 ... this change is needed by the frameworks/wrangler folks to move forward on evolving the node.js compat story. @irvinebroque @mikenomitch ... heads up from the product perspective this changes the way node.js compat is enabled. There's the existing |
Is the plan to make |
Unfortunately I don't think so. Given the way compat dates work and the guarantees they carry, we can't really combine these at any point and we had made the decision long ago that Node.js compat would not be on-by-default ever. If we move forward with adding this, it'll mean a second node.js compat mode going forward indefinitely. This is something we should discuss tho to see if there's a reasonable path forward. |
@jasnell sorry if I was not clear, I'm not suggesting that |
Even then, I'm not sure we can combine |
yes, let's evaluate and be careful, but I'd personally rather take the risk of breaking things and having to pivot, than taking the easy route and having to live with two confusing flags forever. |
Just catching up now, but I generally agree with @IgorMinar's intuition on this. node_compat vs nodejs_compat is confusing enough already, so adding a new permanent flag worries me a lot - Do global compatability dates not give us a way to break the functionality of nodejs_compat in a safe way? And given that "node:" will still work, is the main breaking change the new globals that are added? |
I'll say "potentially" breaking change are the new globals and the fact that statements like |
LGTM otherwise |
e8a1f7f
to
b3d5b98
Compare
The `nodejs_compat_v2` flag supersedes the 'nodejs_compat' flag. When enabled... 1. Node.js built-ins are available for import/require 2. Unlike the original `nodejs_compat` flag, Node.js imports do not require the 'node:' specifier prefix. Internally, the implementation will detect a Node.js raw specifier and convert it into the appropriate prefixed specifier, e.g. 'fs' becomes 'node:fs' 3. The `Buffer` and `process` global objects are exposed on the global 4. A user worker bundle can still provide it's own implementations of all `node:` modules which will take precendence over the built-ins 5. The new `process.getBuiltinModule(...)` API is implemented. See nodejs/node#52762 A worker can replace the implementation of `node:process` if they choose, which may mean that `getBuiltinModule(...)` is not available.
b3d5b98
to
6fd7fd0
Compare
The
nodejs_compat_v2
flag supersedes the 'nodejs_compat' flag. When enabled...nodejs_compat
flag, Node.js imports do not require the 'node:' specifier prefix. Internally, the implementation will detect a Node.js raw specifier and convert it into the appropriate prefixed specifier, e.g. 'fs' becomes 'node:fs'Buffer
,process
, andglobal
are exposed on the globalnode:
modules which will take precedence over the built-insprocess.getBuiltinModule(...)
API is implemented. See process: add process.getBuiltinModule(id) nodejs/node#52762A worker can replace the implementation of
node:process
if they choose, which may mean thatgetBuiltinModule(...)
is not available.Refs: #2133