Update: Vite 3.2 fixed the support for multiple files. I updated this post to cover this new approach. Check the section "Using vite 3.2 or later"
Intro
This post probably will get outdated soon.
That's because while I'm writing, Vite 3 (v3.0.4) still does not support an out-of-the-box solution for using it in Library mode with multiple entry points.
Despite proposing two strategies, I'd also point to a problem I encountered while trying to solve this: How to have multiple type definitions?
I wish everything were more straightforward than it actually is, but I'll walk you step-by-step through the problems and solutions.
About Vite
Vite is an opinionated build tool that aims to provide a faster learner development experience for modern web projects.
https://vitejs.dev/guide/#overview
It's focused on ES Modules structure (although we can use it with Common JS), and it gives us a development server (like when you run npm run dev) with a blazing-fast Hot Module Replacement (HMR).
We can define HMR for the situation when you're running a dev server, change a file, this file is processed again (to be supported by the browser), and the server gets refreshed.
Under the hood, Vite combines esbuild for a particular file optimization (due to its outstanding performance) and Rollup (for actually outputting the files), having an excellent performance in general.
If you're new to Vite, I strongly recommend you walk through their docs and try to create a simple app using one of their templates to see how amazing it's with your eyes.
Building a JS library
If you want to build a JS library, you will likely pick up Rollup.
That's because it's a mature tool, isn't as complex as Webpack, and is not that hard to configure.
Even though the configuration isn't too hard, you still have to install a bunch of plugins, care about TypeScript parsing (in case you write your lib in TS), care about transpiling CommonJS code, etc.
Luckily Vite has something called "Library Mode", which allows us to point to an entry file (like a index.ts file that exports everything the package contains) and get it compiled using all the Vite ecosystem.
The documentation around that is great, and I believe it's enough so you can have a lib ready to be published or consumed by an application itself.
The only problem with that is: "What if instead of having a single entry point, I want to have it multiple?"
You might have noticed already, that some libraries allow you to import a few things from the main import:
import { foo } from 'package'
And from the same library, also give us a sub-module:
import { bar } from 'package/another-module'
An example of it is Next.JS. When we install next, we can import a few things from the main package and other things from sub-modules:
import Link from 'next/link';
import Image from 'next/image';
import type { GetServerSideProps } from 'next';
We can't simply point to an index.ts for those cases and have multiple outputs. We need to point to other files.
In the same example used before (next), they most likely would point to multiple files like src/image.tsx, src/link.tsx are compiled to files like dist/image.js, and dist/link.js.
Side note, they don't use Vite for that. Looking at their code base, the ecosystem and building are more complex than we need and for that, they have a different approach and tooling.
Ok, but if Vite doesn't support multiple entries, how do we achieve this?
Strategies
It might be a lot of ways to solve that, but here, I want to mention two strategies I found very simple.
Internal server error