vite
vite copied to clipboard
feat(lib): multiple entries for umd/iife
Description
This is a follow up to #7047. This enables multi entry builds for the "umd" and "iife" formats.
Since Rollup does not support code splitting builds for them (see https://github.com/rollup/rollup/issues/2072), the strategy is:
- Have one main build for other output formats (and umd/iife if only one entry). Business as usual.
- One more separate Rollout build per entry point for umd/iife.
Example outputs:
For normal build:
vite v3.2.0-beta.3 building for production...
✓ 2 modules transformed.
dist/foo.js 97.79 KiB / gzip: 73.58 KiB
dist/bar.js 97.81 KiB / gzip: 73.62 KiB
dist/foo.mjs 97.69 KiB / gzip: 73.50 KiB
dist/bar.mjs 97.73 KiB / gzip: 73.55 KiB
Extra non code splitting build for entry: foo
✓ 1 modules transformed.
dist/foo.umd.js 97.98 KiB / gzip: 73.75 KiB
dist/foo.iife.js 97.81 KiB / gzip: 73.61 KiB
Extra non code splitting build for entry: bar
✓ 2 modules transformed.
dist/bar.umd.js 195.64 KiB / gzip: 147.21 KiB
dist/bar.iife.js 195.47 KiB / gzip: 147.07 KiB
In watch mode:
vite v3.2.0-beta.3 building for production...
watching for file changes...
build started...
✓ 2 modules transformed.
dist/foo.mjs 97.69 KiB / gzip: 73.50 KiB
dist/bar.mjs 97.73 KiB / gzip: 73.55 KiB
dist/foo.js 97.79 KiB / gzip: 73.58 KiB
dist/bar.js 97.81 KiB / gzip: 73.62 KiB
built in 82ms.
build started (Extra non code splitting build for entry: foo)...
✓ 1 modules transformed.
dist/foo.umd.js 97.98 KiB / gzip: 73.75 KiB
dist/foo.iife.js 97.81 KiB / gzip: 73.61 KiB
built in 49ms.
build started (Extra non code splitting build for entry: bar)...
✓ 2 modules transformed.
dist/bar.umd.js 195.64 KiB / gzip: 147.21 KiB
dist/bar.iife.js 195.47 KiB / gzip: 147.07 KiB
built in 62ms.
Drawbacks
Notice that this is not without drawbacks, but depending on the use case it might be perfectly fine. Shared code will be exported multiple times which
- causes bigger output
- could cause runtime problems (if e.g. a shared state is expected - each chunk would have its own state)
Open questions
-
Since there are potential problems as described above, should the behaviour be opt-in? Something like
allowNonCodeSplittingBuilds: trueto state that there is no shared code between entry points or duplication is accepted. Or does the console output make it clear enought? -
Is the output fine like this? Should it rather appear as if there was only one build, with one big list of chunks at the end? (Would need heavier modification of the reporter plugin)
-
Choosing the right label in watch mode is a bit hacky atm. Code reviewers let me know if there is a better way. Or whether we should just leave out the labels there.
What is the purpose of this pull request?
- [ ] Bug fix
- [x] New Feature
- [ ] Documentation update
- [ ] Other
Before submitting the PR, please make sure you do the following
- [x] Read the Contributing Guidelines.
- [x] Read the Pull Request Guidelines and follow the Commit Convention.
- [x] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
- [x] Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g.
fixes #123). - [x] Ideally, include relevant tests that fail without this PR but pass with it.
Ah, I see there is a failed test, likely because of the change. I will fix it tomorrow, it's getting late 😁
Edit: nvm, I think I got it. I think the test was doing something wrong.
Tested this out on a large code base and this works well. Thanks for the PR @schummar!
Any way to test the branch without manually build ?
@Kilbourne Not that I know of. I built it manually and then copied the either the dist or the build folder (forgot which one sorry) to my own project's vite to try it out in a real life project.
conflict sir @schummar
conflict sir @schummar
Indeed. Will resolve it this evening or tomorrow.
1 failed sir @schummar
1 failed sir @schummar
Unfortunately, there seem to be some very flaky tests, so I almost always see some error or another when running these tests. I look at them of course and try to see if it could be affected by my changes. In this instance I can't see any connection, so I'm assuming it's nothing I can do. Correct me if I'm wrong.
Thanks for this @schummar, this PR is going to be so helpful! Is there any chance someone can help with getting these test issues sorted out? I see it's just been chilling here for a couple of weeks now. I tried having a look myself, but without any prior experience with the Vite codebase, I felt way out of my depth. 🏊
@keithkirton as I said before, I don't think that the tests are broken because of this PR. Rerunning them might be enough.
There are also merge conflicts again, but I would prefer to solve them once I got some feedback. Otherwise, I will have to redo the same kind of work over and over again. If the team agrees with the PR in general, I will have it cleaned up quickly.
I really like this solution and was actually looking to do this by hand in my own project. However, in my case, I have multiple entry points that are actually extensions to my main library and not meant to be used independently. They all import the main library and add to it in their own way, like plugins.
This gave me an idea to actually support manual code splitting in UMD bundles.
lib: {
entry: {
main: 'src/main.js',
plugin: {
path: 'src/plugin.js',
external: ['main']
},
},
name: 'mylib_[name]',
format: ['es', 'umd']
}
This config would describe a case like mine, where we have a main entry point that we expect everyone to use, and a secondary entry point, that only some people would use. There could be more entry point like these, and if there are any static variables in the main entry point, trying to import multiple plugins built using UMD will not yield the expected result without properly sharing the main bundle between all of them.
The solution here is that, since vite will build each entry point one at a time, it can also generate different configurations for each of them. To deal with code splitting, we provide an additional external property to the plugin entry point. In this case, we say that when 'main' is imported, it should be considered as an external value accessible on the global scope (which is the case for UMD and iife, as long as they are loaded before the plugin). This means that rollup will properly exclude the code of the main module from the plugin, and correctly share static state like it would with an es build with actual code splitting.
This solution would assume that any time the plugin imports shared dependencies from the main module, it does so through its entry point. It couldn't detect a deep import, and would fallback to a non-code splitting solution in that case.
What do you think? Worth adding to this PR or turn it into a separate issue?
Any updates on this?
When will it be merged 😢
I feel like this PR has somehow been lost to the ether 😭 @schummar are you able to explicitly re-request a review from @logixode? Or if he's not around could we ping one of the more active maintainers? I am desperate for this feature to be merged, it'll be a great quality-of-life improvement in our current project.
I don't think @logixode is part of the Vite team, he just made a review as anyone can 😉
Mentioning team members is probably not the right thing to do. The team has a lot of PRs and issues to take care of and my guess is that lib mode doesn't have the highest priority. One could try and start a discussion on the Discord server.
I think this solution is exactly what I need! @schummar did u start a discussion in Vite discord? I'd like to contribute. Also I want to test it locally, since it's my first time doing it can you give a hint of what I have to do?
since it's my first time doing it can you give a hint of what I have to do?
https://github.com/vitejs/vite/blob/main/CONTRIBUTING.md
Any updates on this PR ? This is exactly what we require since currently the only way to achieve the above is to loop multiple times for each entry file (IIFE).
Need this for dynamic import.
This is maybe a stupid post, but if anyone else stumbles here because they want multiple entrypoints but they are not building a library, please know that you can already do this like so:
export default {
build: {
rollupOptions: {
input: {
"foo": __dirname + "/src/foo/index.tsx",
"bar": __dirname + "/src/bar/index.tsx",
[...]
}
}
}
This is maybe a stupid post, but if anyone else stumbles here because they want multiple entrypoints but they are not building a library, please know that you can already do this like so:
export default { build: { rollupOptions: { input: { "foo": __dirname + "/src/foo/index.tsx", "bar": __dirname + "/src/bar/index.tsx", [...] } } }
I got Invalid value "umd" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds from your suggestion.
It has been a year since this PR, would really love to see it live :)
Related references (for people looking about this feature): https://github.com/vitejs/vite/discussions/17363 https://github.com/vitejs/vite/pull/7047 https://github.com/vitejs/vite/pull/10116 https://github.com/rollup/rollup/issues/2072 https://github.com/rollup/rollup/issues/2374
There are also merge conflicts again, but I would prefer to solve them once I got some feedback. Otherwise, I will have to redo the same kind of work over and over again. If the team agrees with the PR in general, I will have it cleaned up quickly.
Makes sense, @schummar. Your PR is now the second most popular one for Vite at the moment (with 25 likes and counting, tied for third right now in the history of Vite, actually)! I know I'd love to see this as well.
Above you also said that maybe it would be best not to tag a team member. While I'm not bold or eloquent enough to do it, hopefully the popularity of this PR at least bolsters the argument of putting it in front of someone so they can take a quick look, maybe at least triage it or even offer that essential feedback you might need. 😄
Any update on this? :smile:
Hello!
Could we expect this pull request to be merged soon? It's crucial for our transition from Webpack to Vite.
Following! Would really like to see this in Vite too!
Any updates on this?
bump
... this would be so awesome ...
I ended up writing an (inline) plugin for vite to generate the .umd & minified files: https://github.com/rrweb-io/rrweb/blob/a6c933a23f8c6e913067650a199993e38e8b62fc/vite.config.default.ts#L6-L99
Hope this helps someone