Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const app = 'fixture';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
initial
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "config-resolution-hooks",
"private": true,
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const staged = {
'*.txt': 'vpt stat-file',
};

export const pack = {
entry: ['app/index.js'],
dts: false,
format: 'esm',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[[case]]
name = "staged_preserves_config_hooks"
vp = "local"
unset-env = ["NODE_ENV"]
steps = [
{ argv = ["git", "init", "--quiet"], snapshot = false },
{ argv = ["git", "add", "input.txt"], snapshot = false },
{ argv = ["git", "commit", "--quiet", "-m", "initial"], snapshot = false },
{ argv = ["vpt", "write-file", "input.txt", "changed\n"], snapshot = false },
{ argv = ["git", "add", "input.txt"], snapshot = false },
{ argv = ["vp", "staged", "--verbose", "--no-stash"], comment = "Run staged configuration supplied by a Vite plugin and print the matched files." },
]

[[case]]
name = "pack_preserves_config_hooks"
vp = "local"
env = { NODE_ENV = "development" }
steps = [
{ argv = ["vp", "pack", "--logLevel", "silent"], comment = "Build with plugin-supplied pack options and configuration metadata available in configResolved." },
["vpt", "print-file", "dist/index.mjs"],
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# pack_preserves_config_hooks

## `vp pack --logLevel silent`

Build with plugin-supplied pack options and configuration metadata available in configResolved.

```
config NODE_ENV: development
apply root: <workspace>
config root: <workspace>
configResolved root: <workspace>
configResolved configFile: <workspace>/vite.config.mjs
configResolved dependencies:
<workspace>/settings.mjs
<workspace>/vite.config.mjs
ℹ Build start
```

## `vpt print-file dist/index.mjs`

```
// app/index.js
const app = "fixture";
export { app };
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# staged_preserves_config_hooks

## `git init --quiet`


## `git add input.txt`


## `git commit --quiet -m initial`


## `vpt write-file input.txt 'changed
'`


## `git add input.txt`


## `vp staged --verbose --no-stash`

Run staged configuration supplied by a Vite plugin and print the matched files.

```
config NODE_ENV: development
apply root: <workspace>
config root: <workspace>
configResolved root: <workspace>
configResolved configFile: <workspace>/vite.config.mjs
configResolved dependencies:
<workspace>/settings.mjs
<workspace>/vite.config.mjs
⚠ Skipping backup because `--no-stash` was used. This might result in data loss.

✔ vpt stat-file

→ vpt stat-file:
<workspace>/input.txt: file
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { defineConfig, lazyPlugins, normalizePath } from 'vite-plus';

import { pack, staged } from './settings.mjs';

console.log(`config NODE_ENV: ${process.env.NODE_ENV}`);

export default defineConfig({
// CLI metadata reads retain the command's root override, even when the file sets root.
root: 'app',
plugins: [
lazyPlugins(() => {
throw new Error('metadata resolution must skip lazy plugin factories');
}),
{
name: 'provide-tool-config',
apply(config) {
console.log(`apply root: ${normalizePath(String(config.root))}`);
return true;
},
config: {
order: 'pre',
handler(config) {
console.log(`config root: ${normalizePath(String(config.root))}`);
return { staged, pack };
},
},
async configResolved(config) {
console.log(`configResolved root: ${normalizePath(config.root)}`);
console.log(`configResolved configFile: ${config.configFile}`);
console.log('configResolved dependencies:');
for (const dependency of config.configFileDependencies.map(normalizePath).sort()) {
console.log(` ${dependency}`);
}
},
},
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const source = 'configured Vite root source must not be packed';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "pack-shared-config-cwd",
"private": true,
"type": "module",
"workspaces": ["packages/*"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "shared-config-library",
"private": true,
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const source = 'package source';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages:
- packages/*
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[[case]]
name = "pack_shared_config_preserves_package_cwd"
vp = "local"
cwd = "packages/lib"
steps = [
{ argv = ["vp", "pack", "--logLevel", "silent"], comment = "Load the parent config through traverseUp while plugin hooks and pack paths stay at the package cwd, overriding the file's root." },
["vpt", "print-file", "dist/index.mjs"],
["vpt", "stat-file", "../../dist", "../../configured-root/dist"],
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# pack_shared_config_preserves_package_cwd

## `vp pack --logLevel silent`

Load the parent config through traverseUp while plugin hooks and pack paths stay at the package cwd, overriding the file's root.

```
apply root: <workspace>/packages/lib
apply cwd: <workspace>/packages/lib
config root: <workspace>/packages/lib
config cwd: <workspace>/packages/lib
configResolved root: <workspace>/packages/lib
configResolved cwd: <workspace>/packages/lib
configResolved configFile: <workspace>/vite.config.mjs
ℹ Build start
```

## `vpt print-file dist/index.mjs`

```
// src/index.js
const source = "package source";
export { source };
```

## `vpt stat-file ../../dist ../../configured-root/dist`

```
../../dist: missing
../../configured-root/dist: missing
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const source = 'workspace source must not be packed';
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { defineConfig, normalizePath } from 'vite-plus';

function printRoot(hook, config) {
console.log(`${hook} root: ${normalizePath(String(config.root))}`);
console.log(`${hook} cwd: ${normalizePath(process.cwd())}`);
}

export default defineConfig({
// The existing CLI contract overrides this with the package cwd when reading pack settings.
root: 'configured-root',
plugins: [
{
name: 'print-shared-config-package-root',
apply(config) {
printRoot('apply', config);
return true;
},
config: {
order: 'pre',
handler(config) {
printRoot('config', config);
},
},
configResolved(config) {
printRoot('configResolved', config);
console.log(`configResolved configFile: ${config.configFile}`);
},
},
],
pack: {
entry: ['src/index.js'],
outDir: 'dist',
dts: false,
format: 'esm',
},
});
2 changes: 1 addition & 1 deletion docs/guide/migrate-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ Object-valued nested npm and Bun overrides are preserved: they are user-defined

`vite` and `vite/*` imports are rewritten to `vite-plus` **only in config entry files**: `vite.config.*`, `vitest.config.*`, and any config file the migration resolved. Every other file keeps its `vite` imports, for two reasons:

- `vite-plus` is not a guaranteed superset of Vite's exposed surface. It owns only `defineConfig`, `defineProject`, and `lazyPlugins`, so rewriting a pass-through symbol such as `createBuilder` or `loadConfigFromFile` (including in `typeof import('vite')` type positions) can break.
- `vite-plus` is not a guaranteed superset of Vite's exposed surface. It owns only `defineConfig`, `defineProject`, `lazyPlugins`, and `resolveConfigFromFile`, so rewriting a pass-through symbol such as `createBuilder` or `loadConfigFromFile` (including in `typeof import('vite')` type positions) can break.
- An unrewritten `vite` import still resolves through the `@voidzero-dev/vite-plus-core` alias in a Vite+ project.

Plugin packages (an unscoped name starting with `vite-plugin-` or `unplugin-`, or `vite` in `peerDependencies`/`dependencies`) skip the rewrite even in config files. Only the `vite` specifier is in scope for this rule.
Expand Down
Loading
Loading