Closed garrydzeng closed 4 years ago
Can you elaborate on the behavior you'd like to see here? I'm not sure how the option as documented by rollup is useful. Why not just use the global variable? Why is it an import at all?
@devongovett
Let me take React as an example.
I can use React as global variable in my project, but many third-party library imported React in their code and I can't control that, so, if I include React through a CDN, like <script src="//cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
and the bundle in my index.html, then browser has to download React twice.
In order to avoid this problem, I have to import React in my project. If Parcel can replace React as global variable when it handling third-party library, then it can reduce bundle size & I can use CDN to speed up my website. React can be any library also.
I made an example: parcel-example.zip. Hope this help!
I see. This seems somewhat related to aliasing actually. See #25.
Another vote for this issue... I really like what you've done here with Parcel. It was super-easy to get my project 95% set up. This issue, (external resources), along with dev-server proxying are the two things holding me back.
Motivation for both is that I'm developing components that will be used within a larger application. There are external dependencies (that I don't want packaged up in the component build), and there are external APIs I want to hit while developing. In both cases, these are things that will be there when the project is deployed, but which are not a part of this component.
garrydzeng mention Rollup's "globals" option. Webpack similarly has "externals" (https://webpack.js.org/configuration/externals/).
You mentioned babel aliasing. That, I think, is a separate issue, because it's after the packager has decided to include a file, you can tell babel an alternate path to get it. There doesn't appear to be a way to tell babel that it should be ignored entirely. (At least not in a way that will keep other things happy). The "external" concept would really need to be configured at the packager.
I'd be happy to help out and contribute code to solving these issues, but given the 'zero-configuration' mantra, it's not clear to me where or how either could/should be done in Parcel. If you have ideas along those lines, please let me know. --Thanks
+1 on this issue. The aliases implemented in https://github.com/parcel-bundler/parcel/pull/850 can not solve this issue. Just like globals
in Rollup and externals
in webpack, Parcel also need an option to map modules to a global value.
I'd like to help with this issue if needed : )
I have a patched version that allows external scripts. The idea is to mark scripts as โcopyโ and provide a mapping of globale to modules that. But that still is kind of configuration...
@starkwang Cool! Iโd be great if you can take this issue ๐
@derolf @davidnagli Perhaps change the aliasing a slight bit and add something like this:
aliases {
"react": false // This will ignore the package
}
This would cause it to skip without adding extra complex configurations. (Of course we still have to implement it and i'm not sure if it's sorta allowed by the standards) This behaviour would be kinda similar to how browser.fs === false works for fs resolves
I have a proposal to extend the "alias" syntax to support externals:
"<module>": "<file>!<evaluated export term>"
Example (for cesiumjs):
"cesium": "./node_modules/cesium/Build/Cesium/Cesium.js!Cesium"
Semantics:
Usage:
HTML inline load: <script src="cesium"></script>
@derolf isn't this different than the described issue? The issue is about using external packages from cdn's wouldn't this just be lazyloading everything from the local server or cdn?
@DeMoorJasper
For CDN:
"cesium": "http://cdn.xyz.com/foo/bar/Cesium.js!Cesium"
could work the same way. But instead of copying into dest folder it's is directly linked.
I think the main idea is to somehow refer to "prebuilt" folders -- disable parcel parsing -- and link them to a fake module.
So the exclamation mark disables parcel parsing of the content and the term afterwards creates the export directive for the fake module.
@derolf I think the !
syntax is fairly non-obvious, at least I haven't seen it used before. Is this 'standard' across similar implementations? Why not just use the key?
@woubuc So, if you look at webpack's external, you need a key plus which global symbol to bind to that key. So, we need to tell parcel which symbol to bind to the fake module.
Example: three-js exports a global symbol called THREE, so the syntax would be:
"three": "https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js!THREE"
This follows the same approach in webpack.
@DeMoorJasper 's <PackageName>: false
makes sense to me (but misses renaming... which may be important in certain cases).
I don't see the advantage of @derolf's <PackageName>: <CDN path>:!<import name>
, unless it's solving a different problem than what I was talking about.
Could the webpack externals
concept be followed directly, except inside package.json. Then it's a 1-to-1 with a well-known feature, and keeps the ability to rename the import.
package.json:
"dependencies": { },
"parcel": { /* Or should externals be at the top level? */
"externals": {
"MyProjectConfig": "config",
"react": "react"
}
}
}
Unlike the aliases: {packageName: false}
, this allows for renaming. You can import
from the proper name of the package (as if you were really packaging it up), but still have the code get linked into whatever the actual named variable is in the CDN/inline script.
My deployed index.html/jsp that pulls in the parceled project...
<script>
config = {
someValue: 123
}
</script>
<script src="://some-cdn/react.min.js"></script>
<script src="./build/parceled-up-project.js></script>
And finally... some random source file in my project:
import MyProjectConfig from 'MyProjectConfig'
import React, { Component } from 'react'
For both those imports, the packager can find the 'from' in the externals list, and know that it doesn't need to actually fetch/import anything. And the actual variable names can get assigned with the desired renaming.
Something like this makes the most sense to me... but it's obviously getting away from 'zero-config', so I assume it would need some consensus before building it in. What do you think?
Package.json is not available to the parser. Because resolution is done afterwards.
So, you need two things:
@MalcomDwyer okay, I can implement your โexternalsโ in package.json proposal and create module stubs the same way that Webpack does.
But, what is a good syntax to tell parcel to NOT bundle a script that is already in the public folder?
Like:
But, what is a good syntax to tell parcel to NOT bundle a script
In my example, that "deployed index.html/jsp" would not even be something that parcel ever sees...
I have my frontend project codebase that I use to develop, and test the javascript project. Then in a separate downstream project, I just pick up the bundle.js (src="./build/parceled-up-project.js in my example above) as a pre-built entity. It is in that downstream file that those external imports actually get resolved. (So they are external to parcel, but are part of the downstream project).
So I would probably have parcel building the real bundle.js (which ignores those externals), but also for development, I'd have parcel build a demo/index.html which would have the same imports and should include those files. I can't think of a time I'd be pointing parcel at an html with <script src="x">
and not want it to import "x".
I start bundling from a central HTML file and need to pull in stuff to parcel and stuff that is prebuilt (three js and cesium js).
Package.json is not available to the parser. Because resolution is done afterwards.
You shouldn't wait this long right? You just append the externals to the resolver, this way u can detect it before it even gets to the parser
Githubissues.Githubissues is a development platform for aggregating issues.
Choose one: is this a ๐ bug report or ๐ feature request?
๐ feature request
๐ค Expected Behavior
Don't include external module in bundled file everywhere. Like rollup
globals
option. https://rollupjs.org/#big-list-of-options๐ Your Environment