vite icon indicating copy to clipboard operation
vite copied to clipboard

feat(lib): multiple entries for umd/iife

Open schummar opened this issue 3 years ago • 30 comments
trafficstars

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:

  1. Have one main build for other output formats (and umd/iife if only one entry). Business as usual.
  2. 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: true to 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.

schummar avatar Oct 23 '22 22:10 schummar

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.

schummar avatar Oct 23 '22 22:10 schummar

Tested this out on a large code base and this works well. Thanks for the PR @schummar!

Juice10 avatar Oct 24 '22 05:10 Juice10

Any way to test the branch without manually build ?

Kilbourne avatar Oct 25 '22 14:10 Kilbourne

@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.

Juice10 avatar Oct 25 '22 16:10 Juice10

conflict sir @schummar

logixode avatar Nov 09 '22 06:11 logixode

conflict sir @schummar

Indeed. Will resolve it this evening or tomorrow.

schummar avatar Nov 09 '22 08:11 schummar

1 failed sir @schummar

logixode avatar Nov 25 '22 01:11 logixode

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.

schummar avatar Nov 28 '22 13:11 schummar

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 avatar Dec 13 '22 06:12 keithkirton

@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.

schummar avatar Dec 13 '22 09:12 schummar

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?

kawazoe avatar Dec 19 '22 06:12 kawazoe

Any updates on this?

eghernqvist avatar Feb 20 '23 14:02 eghernqvist

When will it be merged 😢

SSShooter avatar Mar 17 '23 15:03 SSShooter

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.

keithkirton avatar Apr 04 '23 09:04 keithkirton

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.

schummar avatar Apr 04 '23 15:04 schummar

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?

Arthurin915 avatar Apr 05 '23 20:04 Arthurin915

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

tobiasdalhof avatar Apr 06 '23 05:04 tobiasdalhof

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).

joshuagauci avatar May 31 '23 08:05 joshuagauci

Need this for dynamic import.

yoyo837 avatar Sep 15 '23 02:09 yoyo837

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",
        [...]
     }
  }
}

crummy avatar Sep 15 '23 03:09 crummy

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.

yoyo837 avatar Sep 15 '23 04:09 yoyo837

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

QuentiumYT avatar Oct 18 '23 13:10 QuentiumYT

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. 😄

patricknelson avatar Oct 18 '23 23:10 patricknelson

Any update on this? :smile:

edwardw-cit avatar Nov 28 '23 09:11 edwardw-cit

Hello!

Could we expect this pull request to be merged soon? It's crucial for our transition from Webpack to Vite.

KevinCalmant avatar Nov 29 '23 10:11 KevinCalmant

Following! Would really like to see this in Vite too!

looloosha avatar Jan 03 '24 17:01 looloosha

Any updates on this?

gabrielcordeiro-dev avatar Jan 11 '24 19:01 gabrielcordeiro-dev

bump

nocive avatar Feb 29 '24 08:02 nocive

... this would be so awesome ...

el-j avatar Apr 11 '24 09:04 el-j

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

Juice10 avatar Apr 16 '24 23:04 Juice10