microbundle
microbundle copied to clipboard
Officially support more elaborate externals
This is a feature request/Proposal
As a user of microbundle I want ways to configure which imports are to be considered external. In order to reduce my bundle size and also to work with non-standard imports (images, fonts, ...) that are not supported by microbundle.
Status Quo
- As described in https://github.com/developit/microbundle/issues/283#issuecomment-523879163, there is a (I guess unoffical) way to use regex in the
--exclude
flag, which can be used to have rollup treat specific import statements as external. - Presence of the
--exclude
flag triggers if pkg.dependencies are treated as external or not (see index.js#L387) I find that quite confusing and the behaviour is not documented.
Problem
Given I want to use --external .*/assets/.*
to work with non-standard imports
And I also want all my dependencies to be excluded
Then I need to add all dependencies to --external
causing code duplication and manual overhead.
Proposal
In order to fix the problem and reduce confusion I propose to have it work like this:
$ microbundle
Exclude dependencies
, peerDependencies
$ microbundle --external .*/assets/.*
Exclude dependencies
, peerDependencies
and .*/assets/.*
And explicitly support regular expressions or globs under --external
$ microbundle --external .*/assets/.*,angular --include-dependencies
Exclude peerDependencies
and .*/assets/.*
All normal dependencies ecxept angular
are included in the bundle
Non-breaking alternative
I realize that the above proposal is really tied to my personal usecase of (miss-?)using --external
for non-standard imports.
It would also introduce a potential pretty impactful breaking change (since users of microbundle might ship bundles that lack bundled dependencies).
Alternatively the current behaviour could stay as is, using regex in --external
will be considered hacky. And we introduce a new, documented way to exclude assets:
$ microbundle --external-glob **/*.(jpg|png)
Exclude dependencies
, peerDependencies
and all imports matching **/*.(jpg|png)
$ microbundle --external angular --external-glob **/*.(jpg|png)
Exclude peerDependencies
, angular
, and all imports matching **/*.(jpg|png)
Let me know what you think about this. I would be really happy to implement the changes and provide a PR.
It seems like glob pattern support would be fine to add without the addition of a second --external-glob
flag, since *
is not valid within npm package names.
There's still the issue of global without *
, so perhaps we could use wrapping slashes to debit patterns (versus specifier names) explicitly:
microbundle --external "/foo.{js,ts}/"
microbundle --external foo.js,foo.ts
Yeah! i like the approach!
I find it confusing to wrap a glob with /
since it then looks more like regex to me, I would therefore not use globs and propose the following:
micorbundle --external vue,react
: exclude peerDependencies, vue and react
microbundle --external "/\.jpg$/i"
: exclude peerDependencies, dependencies and all imports matching the regex.
microbundle --external "/\.jpg$/i,angular"
: Exclude peerDependencies, angular and all imports machting the regex
microbundle --external "/.*\/strange,commafile.js\/.*/i,angular"
: Throw Error "/.*/strange" is not a valid npm package. If you want to use regex make sure to wrap it with "/". Also commas in regex is not supported.
The docs would then read:
--external
: 'none' or a comma-seperated list of module names or regex.
I would also like to add a small section documenting when peerDependencies and dependencies are added to the exclusion list.
implementation sketch
- still split the externals by
,
- check if each external is valid regex (match against
^\/.*\/i?$
) and create regex without adding stuff - otherwise check if external is valid npm package and create regex as currently implemented
- throw if both are invalid
- add peerDependencies
- if externals did not contain a npm package add dependencies
Could also be implemented without validating the npm package in order to not add additional dependencies. In that case we would not throw errors and just blindly create the module regex no matter what. I assume that this might lead to intransparent behaviour for users of microbundle.
I'll create a PR with the proposed changes (regex within external list).
I would like that this feature would be available, so I could import non-javascript files, for example png, jpg, svg images.
Is there an update here? I'm trying to import .woff
and .woff2
files but am not able to. Unless I'm missing something?
I'll give it some 👀 in the coming days :)
Thanks @wardpeet !
I don't know when, but we landed support for regex externals in 0.13.
Would it also be possible to add an all
or dependencies
option to compliment none
which makes all non-relative import/requires external?
I have component libraries where core-js
and react
are dev dependencies, but I don't want them to be bundled, and I don't really want to add them as peer dependencies (which I find a bit problematic). Also, I don't really want to accidentally bundle libraries. I'd really prefer that bundling was always explicit.
The work around I have now is using --external "^[@a-zA-Z0-9-].*$"
, so anything that has a valid module ID first character should be considered external, and everything else (eg. core-js
, react
) is internal/bundled.
Hi @Shakeskeyboarde
I make all external dependencies with this regex option: --external [A-Za-z0-9_@$]+[A-Za-z0-9_/-]+[\\.]?[A-Za-z0-9_]+
, however react
should be taken into peerDependencies
field.
if you wish to install peer dependencies you can use i-peers
module and if you want to prove your component library on local environment mimicking a registered package you can use yalc
package globally.
Is there an update here? I'm trying to import
.woff
and.woff2
files but am not able to. Unless I'm missing something?
.ttf and other fonts would be cool