vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
67.68k stars 6.09k forks source link

Feature Request: Generating both dev and prod builds in library mode #1814

Open utkarshkukreti opened 3 years ago

utkarshkukreti commented 3 years ago

Is your feature request related to a problem? Please describe.

I'm building a library and I want to generate output similar to what popular libraries like React and Vue do: esm + cjs/umd builds for both dev and prod modes, with only prod builds being minified and having source maps.

Right now, library mode generates esm and umd for prod mode by default and I can enable sourcemaps with a single line in the vite config file.

Describe the solution you'd like

Would be nice to have a builtin option (possibly enabled by default) to also generate dev builds which are not minified and include conditional code that uses import.meta.env.DEV (as mentioned here).

Describe alternatives you've considered

It should be possible to achieve this using rollupOptions with custom input/output but I think this is a necessary feature for library authors.

utkarshkukreti commented 3 years ago

For quick reference, files included in the react@17 and vue@3:

/cjs/react-jsx-dev-runtime.development.js
/cjs/react-jsx-dev-runtime.production.min.js
/cjs/react-jsx-dev-runtime.profiling.min.js
/cjs/react-jsx-runtime.development.js
/cjs/react-jsx-runtime.production.min.js
/cjs/react-jsx-runtime.profiling.min.js
/cjs/react.development.js
/cjs/react.production.min.js
/umd/react.development.js
/umd/react.production.min.js
/umd/react.profiling.min.js
/dist/vue.cjs.js
/dist/vue.cjs.prod.js
/dist/vue.d.ts
/dist/vue.esm-browser.js
/dist/vue.esm-browser.prod.js
/dist/vue.esm-bundler.js
/dist/vue.global.js
/dist/vue.global.prod.js
/dist/vue.runtime.esm-browser.js
/dist/vue.runtime.esm-browser.prod.js
/dist/vue.runtime.esm-bundler.js
/dist/vue.runtime.global.js
/dist/vue.runtime.global.prod.js
mgdodge commented 3 years ago

Yes, non-minified code would be nice to have, even if it's optional. I was curious to see if the vite library output still suffered from this treeshaking bug (it does), and spent some time de-minifying the code for comparison with some output from my own vue-library attempts.

In the utility I have been maintaining for scaffolding vue libraries, I only minify the version intended to be used via script tag (directly in browser) since that's where bandwidth is a concern. In the esm versions, I leave it unminified, since esm is typically used in the context of other bundlers, and so will be minified as part of that process.

LinusBorg commented 3 years ago

Im personally torn about this. What you ask for is achievable right now by running build two times, changing options as required with an env variable.

A built-in option would be nicer, but can be a can of worms with all sorts of requirements popping up.

Ou don't want the vite config to become a webpack config because we keep adding stuff.

utkarshkukreti commented 3 years ago

@LinusBorg I agree that users might have different requirements, but IMO the current output is not a good default - I've yet to see a popular library that ships only minified builds in dist which is the current default in vite library mode.

LinusBorg commented 3 years ago

I've yet to see a popular library that ships only minified builds in dist which is the current default in vite library mode.

Agree. But at the same time, you will probably not find two big libraries that have enough similarities in the build versions they provide that you can come up with a good standard for vite.

As things stand now, you can always write two different configs, set emptyOutDir: false in the second one, and run vite build && vite build -c vite.config.dev.js.

But of course I'd be interested in a cool idea of how to make such builds flexible enough to be configured for the variety of use cases out there.

ldexterldesign commented 3 years ago

👋 https://github.com/vitejs/vite/discussions/3278#discussioncomment-721347

AdrianMrn commented 3 years ago

@ldexterldesign This fixed my issue, thanks!

luxaritas commented 2 years ago

Something I'd like to tack on here is a desire to output both a version with bundled dependencies and without. EG, it would be nice to bundle dependencies in a UMD build intended to be loaded via CDN, but allow dependencies to be resolved from node_modules in an esm/cjs build when installed via npm. The workaround is of course to run vite multiple times, but it would be nice to have it handled in one go

bluwy commented 1 year ago

For import.meta.env.DEV, and alternative is to use https://github.com/benmccann/esm-env, which prevents double build size and works in non-Node environments too.

svallory commented 1 year ago

I think there are many cases where multiple separately configured outputs are desired or even needed. By the way, the "single output" should be better documented in the docs. I haven't seen any indication that configuring lib outputs, for example, disables the output configured inside rollupOptions.

Anyways... I'm developing a Figma plugin and spent two sad days trying to get Vite to do what I needed and couldn't, so I gave up. The main problem for Figma plugins, which I believe may be the case for all environments that have your code run in two separate workers (plugin code and UI), is that the builds you need are not independent so I cannot simply have two builds running unless I want to rebuild both regardless of where the change was made.

My code is split in three folders: code, shared, and ui. Sometimes changes in code affect interfaces exported by shared and imported by ui, sometimes not.

My suggestion is... have the Vite CLI orchestrate that. I don't mind configuring two files, or one for each output I want, if vite understands the relationship between them and I have a single terminal screen to watch for issues

ccforeverd commented 1 year ago

"dev": "vite build --watch"