-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Expose entry points exports #453
Conversation
@davidnagli Does it align with Parcel being just a simple bundler? I've tried hard to make sure there is 0 side-effect on any environment (browser, node.js, electron, etc). It would make server-rendering much easier. The only missing piece after this would be supporting code-splitting. I'm not sure how this will be possible but we'll see. |
Hi @eXon, Interesting PR. I'm trying to run it using these test files: 900e034 Do those files look correct? When I run If you have Slack, hop on and shoot me a message, or join the #contributors channel. https://slack.parceljs.org/ |
Hey @shawwn I've updated the PR with a more appropriate integration test. The goal is not to bundle the whole thing for Node.js but rather make the exports on the entry point available when you require the bundle from Node.js. If you run within the |
@shawwn After testing exactly your code, I can see the Here is the code with minification enabled: const e={send(){}},s=require("./test");s(e); However, in my test the |
Anything else I can do to make this PR merged? |
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.
The code meets standards. This change doesn't harm existing functionality. It adds functionality to enable SSR capabilities in parcel.
@shawwn anything preventing this PR from getting merged? I know everyone is probably busy but I think this would improve parcel and shouldn't cause any problem. Thanks! |
src/builtins/prelude.js
Outdated
|
||
// Expose the exports if we are on the entry point by using the | ||
// previous defined module. | ||
if (previousModule && name === 1) { |
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.
Checking name === 1
would break if we ever change the way IDs are generated (such as #780). Not sure how else this can be checked, though. @devongovett ?
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.
Yeah. Also in split bundles, the entry module does not have id === 1
. You can look in the entry
argument passed to this function above to get the entry module for the bundle. It is an array, but the last element will be the id of entry module. See here:
parcel/src/packagers/JSPackager.js
Lines 197 to 199 in 595252c
if (this.bundle.entryAsset && this.externalModules.size === 0) { | |
entry.push(this.bundle.entryAsset.id); | |
} |
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.
Thanks for your work on this. Sorry for the delay getting this reviewed.
src/builtins/prelude.js
Outdated
|
||
// Expose the exports if we are on the entry point by using the | ||
// previous defined module. | ||
if (previousModule && name === 1) { |
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.
Yeah. Also in split bundles, the entry module does not have id === 1
. You can look in the entry
argument passed to this function above to get the entry module for the bundle. It is an array, but the last element will be the id of entry module. See here:
parcel/src/packagers/JSPackager.js
Lines 197 to 199 in 595252c
if (this.bundle.entryAsset && this.externalModules.size === 0) { | |
entry.push(this.bundle.entryAsset.id); | |
} |
req.send('Test!'); | ||
} | ||
|
||
module.exports = middleware; |
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.
Thanks for adding these fixtures! Can you also add a test that uses them in test/javascript.js
?
Perhaps we should just support generating a UMD bundle instead of something specific for node? That would make it compatible with CommonJS, AMD, globals, etc. https://github.com/umdjs/umd Here's a template: https://github.com/ForbesLindesay/umd/blob/master/template.js |
Codecov Report
@@ Coverage Diff @@
## master #453 +/- ##
==========================================
+ Coverage 86.61% 87.86% +1.25%
==========================================
Files 77 77
Lines 4033 4385 +352
==========================================
+ Hits 3493 3853 +360
+ Misses 540 532 -8
Continue to review full report at Codecov.
|
@devongovett After reading your comments I've added the missing test and ajusted the entry point to use the correct value. I've also managed to support RequireJS. While I was reading about UMD examples, I also saw that in order to be UMD, we also need the global export. However, that exporrt needs a name. Just like jquery is on Maybe this should be only enabled if a library name is specified. Or maybe this can be the package.json file. Should we have this only if we target I feel like this is an impossible task with the current information the file has. @devongovett Do you have an insight about this? Thanks! |
While I was playing with UMD, I think I found the most elegant solution. CommonJS and RequireJS would have the entry point exposed out of the box. Then, the only missing part to be 100% UMD is the browser globals. By adding a new option @devongovett @shawwn @ntomsic @danawoodman |
Any traction on this? This is a much needed feature. |
The way the code is bundled is perfect for the browser. It is also perfect for Node.js if you want to do server-side rendering. However, it was impossible to expose functions that you could import from Node.js by requiring the bundle. The expected behaviour would be to access the entry point exports. Here is an example of what I was trying to accomplish:
test.js
index.js
parcel build test.js
node index
The expected behaviour would be to have printed on the console
MEOW!
. Right now, it would throwtest is undefined
.There is many benefits of working this way when you do server-rendering. You still have zero-configuration. The hashed asset names are already converted within the bundle. And many more.
I am not sure if there is only 1 entry point and it is always the first. Maybe someone that knows the code better would be able to confirm if this approach is correct.