vite-magic-tree-shaking
v1.0.0
Published
Auto-generate tree-shakeable lib entries for Vite build.lib.entry
Maintainers
Readme
vite-magic-tree-shaking
Auto-generate tree-shakeable build.lib.entry for Vite from your source directory.
Install
npm install -D vite-magic-tree-shakingUsage
// vite.config.ts
import { defineConfig } from 'vite'
import { fileURLToPath } from 'node:url'
import { generateEntries } from 'vite-magic-tree-shaking'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
export default defineConfig({
build: {
lib: {
entry: generateEntries(__dirname), // scans src/ by default
// entry: generateEntries(__dirname, 'lib'), // custom source dir
formats: ['es'],
fileName: (_, entryName) => `${entryName}.js`,
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
preserveModules: true,
preserveModulesRoot: 'src',
},
},
},
})Warn when package.json exports are out of sync
Pass warnOnExportsMismatch: true to get a console.warn at build/dev time if
the exports field in package.json does not match the entries resolved from
your source directory:
entry: generateEntries(__dirname, 'src', { warnOnExportsMismatch: true })[vite-magic-tree-shaking] package.json exports are out of sync with src entries.
Run: npx vite-magic generateCLI
The package ships a vite-magic binary with two commands.
generate
Reads your source directory, derives the entry map, and writes the matching
exports field into package.json. Run this after adding or removing source
files.
# using npx (no install required)
npx vite-magic generate
# custom rootDir and srcDir
npx vite-magic generate /path/to/project libExample output:
✓ package.json exports updated:
.
./Button/Button
./Users
./Users/domain/user
./Users/types/UserDTOvalidate
Checks that the exports field in package.json matches the entries derived
from the source directory. Exits with code 1 if they are out of sync — useful
in CI.
npx vite-magic validateExample output when in sync:
✓ package.json exports are in syncExample output when out of sync:
✗ package.json exports are out of sync with src entries
Missing : ./NewFeature
Extra : ./OldFeature
Changed : ./Users
Run: npx vite-magic generateAdd to package.json scripts
{
"scripts": {
"sync-exports": "vite-magic generate",
"validate-exports": "vite-magic validate",
"prebuild": "vite-magic validate"
}
}With prebuild wired up, running npm run build will abort with a clear error
if package.json exports are stale, before Vite even starts.
How entries are resolved
Given this structure:
src/
├── index.ts
├── Users/
│ ├── index.ts
│ ├── domain/
│ │ └── user.ts
│ └── types/
│ └── UserDTO.ts
└── Button/
└── Button.tsxgenerateEntries(__dirname) produces:
{
index: '/abs/src/index.ts',
Users: '/abs/src/Users/index.ts',
'Users/domain/user': '/abs/src/Users/domain/user.ts',
'Users/types/UserDTO': '/abs/src/Users/types/UserDTO.ts',
'Button/Button': '/abs/src/Button/Button.tsx',
}And vite-magic generate writes the corresponding exports to package.json:
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./Users": {
"types": "./dist/Users.d.ts",
"import": "./dist/Users.js",
"require": "./dist/Users.cjs"
},
"./Users/domain/user": {
"types": "./dist/Users/domain/user.d.ts",
"import": "./dist/Users/domain/user.js",
"require": "./dist/Users/domain/user.cjs"
},
"./Users/types/UserDTO": {
"types": "./dist/Users/types/UserDTO.d.ts",
"import": "./dist/Users/types/UserDTO.js",
"require": "./dist/Users/types/UserDTO.cjs"
},
"./Button/Button": {
"types": "./dist/Button/Button.d.ts",
"import": "./dist/Button/Button.js",
"require": "./dist/Button/Button.cjs"
}
}
}Rules
| Source | Entry key |
|---|---|
| src/index.ts | index |
| src/Users/index.ts | Users |
| src/Button/Button.tsx (no index in dir) | Button/Button |
| src/Users/domain/user.ts (subdir of indexed dir) | Users/domain/user |
Directories with an index file use the directory name as key. Their subdirectories are still scanned recursively.
Directories without an index expose each file individually using its relative path (without extension).
Ignored files
The following are never included as entries:
*.test.ts/*.spec.ts*.stories.tsx*.d.ts/*.d.mts/*.d.cts- Any file with an extension other than
.ts,.tsx,.js,.jsx,.mts,.cts
API
generateEntries(rootDir: string, srcDir?: string, options?: GenerateEntriesOptions): Record<string, string>| Parameter | Type | Default | Description |
|---|---|---|---|
| rootDir | string | — | Absolute path to the project root |
| srcDir | string | 'src' | Source directory name, relative to rootDir |
| options | GenerateEntriesOptions | {} | Optional configuration |
GenerateEntriesOptions
| Option | Type | Default | Description |
|---|---|---|---|
| warnOnExportsMismatch | boolean | false | Emit a console.warn if package.json exports do not match the resolved entries |
License
MIT
