-
-
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
node bundling #192
Comments
That’s an interesting point. I don’t think we deal with target environments like Node yet. It would just bundle everything just like it would for the browser. I think it’s something we should look into though. Out of curiousity... why would you ever want to bundle your Node scripts? |
Well, the most obvious reason is performance. One file instead of thousands mean MUCH faster install times, and slightly faster runtime. It also cricumvents tough versioning situations: end users can install-uninstall whatever they like, but my bundled package will always behave exactly the same way. Not meant for every library on NPM, but useful in some cases. Could be especially priceless for corporate environments in fact (human effort to check, mandate, verify 3rd party external components is proportional to package count). |
You cannot bundle dependencies, because some of them may change things like environment or OS configuration, and all of those tasks are usually executed in the installation phase. And about the bundling, zero performance will be achieved in runtime because when you launch your program, all the code gets into memory. The bundling is effective in the browser because you can fetch all your code faster, but you are not accelerating your processing speed in any way. For example, there are already a lot of NodeJS compilers (for example http://enclosejs.com/). But all of them will especify that you will not win any perforn |
This can be extremely useful when compiling a React app to Node.js for service side rendering (with css modules), where we would |
To be clear on performance: in certain cases there's runtime win in bundling. Resolving a module requires several full-blown OS calls through kernel, FS drivers and back. Modules living in Having huge dependency tree with hundreds of tiny modules magnify FS-specific costs, that's where bundling would help runtime performance. Of course the installation wins are more pronounced than runtime in any case: latency and costs of accessing FS are miniscule comparing to latencies and costs of accessing NPM registry. Resolving version between hundreds of packages, downloading all of them, decompressing and creating all those files locally takes time. Dealing with a single package eliminates majority of this work. |
Other obvious benefit of bundling, babel in dependencies, your package is running on AWS, with node 4 or 6, using babel to replace async / await by Bluebird generators give a huge boost performance |
There are other ways to do server-rendering with parcel. You don't actually needs to bundle it, just run it through babel. Here is a great example supporting import ignore on css/anything you need: https://github.com/reactivestack/parcel-react-ssr |
Oh and also parcel bundle are actually running on node.js easily. The only thing you can't is export a function in the bundle and require it from node. |
@davidnagli I started experimenting here.. Which is essentially the start of yet another bundler. Mostly just need correct dynamic module resolution and good extension points for a virtual file system. There are also a lot of edge cases for native modules (.node files) |
@eXon Isn't it the whole point of ParcelJS to have zero configuration and Automatically transforms modules system?
ParcelJS already supports TypeScript and lots of other features – it would be really cool if it could support Universal Web Apps the same out of the box way. (Without a separate configuration for the server) |
+1 for this. |
webpack does this with a single parameter. all thats needed, is NOT to process files that matches /node_modules/ |
Just made a pull request that introduces a node mode. Please give it a try and see if it works for you. |
I think the new In webpack, this is achievable as follows: const builtins = require('builtin-modules')
const DEPS = Object.keys(require('./package').dependencies || {})
module.exports = {
// ...
externals: (context, request, callback) => {
[request] = request.split('/') // this doesn not take into account package names like "@scope/pkg"
if (DEPS.includes(request) || builtins.includes(request))
return callback(null, 'commonjs ' + request) // exclude from bundle
callback() // include in bundle
},
// ...
} This way, I get the following gains:
|
@jrop this sounds like a pretty bad idea as devDependencies doesn't seem to be meant for this purpose? |
devDependencies should not be required by the project at all, thus shouldn't be bundled.
About native modules, I have the code for bundling them working already. After this is reviewed and merged, I'll open a new pull request with it.
Eventually, everything should be bundled. If you somehow can't bundle a part of the things, then what is the advantage of bundling the other part?
|
See my use-case below.
This is a good point, and is one I have considered. Supposing I am writing a library, and I want to produce a UMD bundle to publish as a package, purely for the startup benefits of not having to require 1k's of files from the file-system. In this way I can bundle "as much as possible", and list a native lib as a dependency so that somebody can "npm install" my package. @DeMoorJasper However, by definition, they are dependencies required only for development. Here is a use-case (albeit a corner-case):
To accomplish this, my project would in fact list "inquirer" and "node-fetch" as devDependencies, as they are only required for development. |
Also, there was some previous discussion on this already (for the record) in some PR file comments: https://github.com/parcel-bundler/parcel/pull/652/files#r164348823 |
If this is a library, then bundling its dependencies on the package is a bad practice for node. Some libraries bundle their own code in a single file, but they still require their node_modules dependencies, so that they can be updated or shared between multiple libraries. Bundling everything is bad here. But if you still want to do that, that's ok... Just bundle everything. Native modules will be supported in a following pull request.
Again, this is solved by just bundling everything. Parcel will only bundle what is in fact required by the source, so you shouldn't have to do anything special to separate some packages. As parcel is today, it will not read your "dependencies" for anything. A believe both your usecases are covered by See #796 |
FWIW, when targeting Node, instead of using |
Hi @lbguilherme, I don't seem to find your merge request about native modules. Is the current state of parcel 2 beta 2 can bundle node native addons ? If not, can anyone give me guidance on how to use |
I added to my package.json something like "targets": {
"main": {
"context": "node",
"isLibrary": true,
"sourceMap": false,
"outputFormat": "commonjs",
"includeNodeModules": {
"typescript": false,
"vscode": false
}
}
}, |
🙋 feature request
Other bundlers (like webpack) can target node environment instead of browser. That largely involves leaving things like
require('fs')
andprocess
intact in the code.Is there a way to do the same in parcel?
If no, is it on the roadmap?
Ideally I'd want to test it by parcelling the parcel itself, and getting a bundled single JS file.
The text was updated successfully, but these errors were encountered: