FlorianRappl / parcel-plugin-externals

Parcel plugin for declaring externals. These externals will not be bundled. :package:
https://piral.io
MIT License
47 stars 3 forks source link

Help how to 'externalize' all of WordPress' globals #18

Closed cliffordp closed 2 years ago

cliffordp commented 4 years ago

2 questions for a situation where my app loads within WordPress and therefore globals like jQuery, Moment, Lodash, React, and ReactDOM are already...

References:

  1. What does "*" actually do?
  2. Why doesn't lodash.isequal get excluded from my own build?

Any and all suggestions for my "externals" are welcome! :D

===

Here's a Parcel build report:

image

Here's an example npm ls ...:

image

Here's my externals:

{
...
"externals": {
    "@babel/runtime/regenerator": "regeneratorRuntime",
    "@wordpress/element": "wp.element",
    "jquery": "jQuery",
    "lodash": "lodash",
    "lodash-es": "lodash",
    "moment": "*",
    "react": "React",
    "react-dom": "ReactDOM"
}
...
}
FlorianRappl commented 4 years ago

Obviously we have here multiple installations of lodash.isequal. Presumably, there is a conflict. Unfortunately, locally (i.e., from some installed package) a different version is therefore resolved then globally (i.e., from the source code).

I am not sure if we can / should also counter-act this situation. Because a situation where we have two deps A and B and B should be excluded, but is available in v2, however, A depends on v1 of B. Now if we would treat v1 of B as v2 of B then this would break at runtime.

Is it possible to resolve this conflict? Note: Besides having the same version(s) (the sub packages seem to be all on 4.5).

Regarding "" -> are you referring to NPM versions? This matches any* version. I think by default it goes to latest, but as far as I know it would pick the first one it encounters. What version of lodash.isequal is installed in node_modules?

cliffordp commented 4 years ago

Appreciate the help!

I meant "moment": "*",

cliffordp commented 4 years ago

If I external Lodash (like I tried), does it not external all the dots after it (modules?)

In other words, if Lodash is externalized, why does lodash.transform specifically get built? https://lodash.com/docs/4.17.15#transform

FlorianRappl commented 4 years ago

If I external Lodash (like I tried), does it not external all the dots after it (modules?)

No.

So what we do (or what a bundler does): If you import something like package-a we find the module that it resolves to (e.g., node_modules/package-a/index.js) and replace this with an "externalized" call.

Consequently, all other packages, e.g., package-b that are called by package-a are also not part of the final bundle, however, if you call package-b then this is part of the final bundle (unless, of course, package-b should also be externalized).

Now, if at some code you import package-a/foo then this is different to package-a. While the latter resolved to node_modules/package-a/index.js, the former is maybe something like node_modules/package-a/foo.js.

Hope that helps!

cliffordp commented 4 years ago

thanks for taking the time... so WordPress' build has lodash and lodash-es as externals because they're already loaded globally by WordPress Core... so I thought lodash.___ would as well... but I didn't realize Lodash exports each method, such as https://www.npmjs.com/package/lodash.isempty

So because isempty is required by little-state-machine, but it's also already included in the full lodash/lodash-es, then I have to add every lodash method export as an external or write Parcel Externals JS to do so...

What do you think about adding wildcard like "lodash.*": "lodash" instead of having to write JS? (I couldn't get it working in a short time)

FlorianRappl commented 4 years ago

Sorry I totally forgot about that issue here.

Yeah we discussed these wildcard options quite a bit. In the end we want for the more explicit version, but maybe we find a way to introduce a reduced version.

The original issue with wildcards was that we go explicitly for the stated externals, we don't traversed all deps. The traversal would be implicit with the factory that you can write (that also does not traverse, but rather just looks at Parcel's current suggestion and then changes that).

Maybe the asterisk could work on Parcel's suggestion (i.e., a star triggers the creation of a special kind of function - as if you would have written it ...).

cliffordp commented 4 years ago

Might be above my understanding there, but I appreciate your effort and thought on this topic 👍