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

Babel-node does not transpile files references by workers. Can/should it? #10972

Open
zachsa opened this issue Jan 9, 2020 · 7 comments
Open

Babel-node does not transpile files references by workers. Can/should it? #10972

zachsa opened this issue Jan 9, 2020 · 7 comments
Labels

Comments

@zachsa
Copy link

@zachsa zachsa commented Jan 9, 2020

I find that using new Worker(file.js) (and file.js uses import statements), that babel loads the referenced script fine but babel-node doesn't. Is this a bug or related to how babel-node works (my understanding of these things is not so good)?

I have just posted a StackOverflow question with more detail: https://stackoverflow.com/questions/59662352/how-to-get-babel-node-to-convert-files-referenced-by-workers-to-commonjs-like

@babel-bot

This comment has been minimized.

Copy link
Collaborator

@babel-bot babel-bot commented Jan 9, 2020

Hey @zachsa! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."

@JLHwung

This comment has been minimized.

Copy link
Contributor

@JLHwung JLHwung commented Jan 9, 2020

The Worker constructor does not invoke Module constructor so babel-node could not hook into the loader and apply the transformation. You can use @babel/register to hook into any files loaded inside your worker:

file-wrapper.js

require("@babel/register")
require("file.js") // your worker entry

main.js

new Worker("file-wrapper.js")
@JLHwung JLHwung removed the i: needs triage label Jan 9, 2020
@zachsa

This comment has been minimized.

Copy link
Author

@zachsa zachsa commented Jan 10, 2020

thanks - i'm quite new to this and would definitely be interested in knowing more about how the node.js module system works.

what is the Module constructor? I can see that there is no Module constructor in JavaScript (at least not in the browser or the Node.js repl)

@zachsa

This comment has been minimized.

Copy link
Author

@zachsa zachsa commented Jan 10, 2020

Another question - when using babel (not babel-node), it does actually work:

babel ./src --out-dir dist

That does convert the worker to commonjs.

@JLHwung

This comment has been minimized.

Copy link
Contributor

@JLHwung JLHwung commented Jan 12, 2020

what is the Module constructor?

The Module constructor is actually the internal implementation of CommonJS module of Node.js: https://github.com/nodejs/node/blob/f9c16b87eff60858efa0b6977fa1d253be538589/lib/internal/modules/cjs/loader.js#L154, when a module is loading, it will call the functions registered in Module._extensions: https://github.com/nodejs/node/blob/f9c16b87eff60858efa0b6977fa1d253be538589/lib/internal/modules/cjs/loader.js#L1064. We call them loader hooks.

babel-node injects babel transform into loader hooks. For example, let's say you have an index.js, in which you are doing require("lib.js"). This is what happens when you are using babel-node index.js.

require("lib.js")
==> new Module("lib.js")
==> module._load 
==> Module._extensions[".js"]("lib.js")
==> babel transform(content of "lib.js")
==> run the transformed module

So if you are doing new Worker("worker.js"), the babel-transform is not applied like above because the Worker constructor does not call new Module, so does Module._extensions["js"], so the execution code "worker.js" gets no chance to be transformed.

If you are using babel-cli to precompile the code, that means you are doing

new Worker(transformed "worker.js")

It works because the execution code has been transformed.

@ZachSAEON

This comment has been minimized.

Copy link

@ZachSAEON ZachSAEON commented Jan 14, 2020

Ah, thanks. But. the only reason that babel-cli knows to transform worker.js is that the file is referenced by the Worker constructor. Does this mean that babel-cli follows all file references whereas babel-node only follows module imports? Why is this?

Thank you very much for your answers. Out of interest, I see this line:

Module._extensions[extension](this, filename)

That looks like there is one loader per file extension. How does Node allow 3rd party code to be executed per module extension? I see the .js extension function. But I don't see where the babel transform function would be executed.

@JLHwung

This comment has been minimized.

Copy link
Contributor

@JLHwung JLHwung commented Jan 14, 2020

babel-cli transforms all the JavaScript files inside the src folder. It operates on per-file level and does not process the module references.

How does Node allow 3rd party code to be executed per module extension?

Under the hood babel-node uses pirates, which overwrites Module._extension[".js"]. So when a module is loaded, the babel transform defined here will be executed:

cached = babel.transform(code, {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.