Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lib): multiple entries for umd/iife #10609

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

schummar
Copy link
Contributor

@schummar schummar commented Oct 23, 2022

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 rollup/rollup#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
  • New Feature
  • Documentation update
  • Other

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines and follow the Commit Convention.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.

@schummar schummar mentioned this pull request Oct 23, 2022
9 tasks
@schummar
Copy link
Contributor Author

schummar commented Oct 23, 2022

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.

@Juice10
Copy link

Juice10 commented Oct 24, 2022

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

@Kilbourne
Copy link

Kilbourne commented Oct 25, 2022

Any way to test the branch without manually build ?

@Juice10
Copy link

Juice10 commented Oct 25, 2022

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

logixode
logixode previously approved these changes Oct 28, 2022
@logixode
Copy link

logixode commented Nov 9, 2022

conflict sir @schummar

@schummar
Copy link
Contributor Author

schummar commented Nov 9, 2022

conflict sir @schummar

Indeed. Will resolve it this evening or tomorrow.

@logixode
Copy link

logixode commented Nov 25, 2022

1 failed sir @schummar

@schummar
Copy link
Contributor Author

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.

@keithkirton
Copy link

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

@schummar
Copy link
Contributor Author

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

@kawazoe
Copy link

kawazoe commented Dec 19, 2022

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?

@eghernqvist
Copy link

Any updates on this?

@SSShooter
Copy link

When will it be merged 😢

@keithkirton
Copy link

keithkirton commented Apr 4, 2023

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.

@schummar
Copy link
Contributor Author

schummar commented Apr 4, 2023

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.

@Arthurin915
Copy link

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?

@tobiasdalhof
Copy link

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

@gaucj-t
Copy link

gaucj-t commented May 31, 2023

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

@yoyo837
Copy link
Contributor

yoyo837 commented Sep 15, 2023

Need this for dynamic import.

@crummy
Copy link

crummy commented Sep 15, 2023

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

@yoyo837
Copy link
Contributor

yoyo837 commented Sep 15, 2023

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.

@QuentiumYT
Copy link

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
#7047
#10116
rollup/rollup#2072
rollup/rollup#2374

@patricknelson
Copy link

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

@edwardw-cit
Copy link

Any update on this? 😄

@KevinCalmant
Copy link

Hello!

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

@looloosha
Copy link

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

@gabrielcordeiro-dev
Copy link

Any updates on this?

@patak-dev patak-dev added feat: library mode p2-to-be-discussed Enhancement under consideration (priority) labels Feb 21, 2024
@nocive
Copy link

nocive commented Feb 29, 2024

bump

@el-j
Copy link

el-j commented Apr 11, 2024

... this would be so awesome ...

@Juice10
Copy link

Juice10 commented Apr 16, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: library mode p2-to-be-discussed Enhancement under consideration (priority)
Projects
Status: P2 - 3
Development

Successfully merging this pull request may close these issues.

None yet