Skip to content

Commit 637d0e9

Browse files
committed
feat(editor): limit npm.scriptRunner to vp create only
1 parent 964d87a commit 637d0e9

4 files changed

Lines changed: 43 additions & 5 deletions

File tree

docs/guide/ide-integration.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ For the best VS Code experience with Vite+, install the [Vite Plus Extension Pac
99
- `Oxc` for formatting and linting via `vp check`
1010
- `Vitest` for test runs via `vp test`
1111

12-
When you create or migrate a project, Vite+ prompts whether you want editor config written for VS Code. You can also manually set up the VS Code config:
12+
When you create or migrate a project, Vite+ prompts whether you want editor config written for VS Code. `vp create` additionally sets `npm.scriptRunner` to `vp` so the VS Code NPM Scripts panel runs scripts through the Vite+ task runner. For migrated or existing projects, you can add this setting manually (see below).
13+
14+
You can also manually set up the VS Code config:
1315

1416
`.vscode/extensions.json`
1517

@@ -29,9 +31,18 @@ When you create or migrate a project, Vite+ prompts whether you want editor conf
2931
"editor.formatOnSaveMode": "file",
3032
"editor.codeActionsOnSave": {
3133
"source.fixAll.oxc": "explicit"
32-
},
33-
"npm.scriptRunner": "vp"
34+
}
3435
}
3536
```
3637

3738
This gives the project a shared default formatter and enables Oxc-powered fix actions on save. Setting `oxc.fmt.configPath` to `./vite.config.ts` keeps editor format-on-save aligned with the `fmt` block in your Vite+ config. Vite+ uses `formatOnSaveMode: "file"` because Oxfmt does not support partial formatting.
39+
40+
To let the VS Code NPM Scripts panel run scripts through `vp`, add the following to your `.vscode/settings.json`:
41+
42+
```json
43+
{
44+
"npm.scriptRunner": "vp"
45+
}
46+
```
47+
48+
This is included automatically by `vp create` but not by `vp migrate`, since existing projects may have team members who do not have `vp` installed locally.

packages/cli/src/create/bin.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
796796
editorId: selectedEditor,
797797
interactive: options.interactive,
798798
silent: compactOutput,
799+
additionalSettings: { 'npm.scriptRunner': 'vp' },
799800
});
800801
resumeCreateProgress();
801802
workspaceInfo.rootDir = fullPath;
@@ -885,6 +886,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
885886
editorId: selectedEditor,
886887
interactive: options.interactive,
887888
silent: compactOutput,
889+
additionalSettings: { 'npm.scriptRunner': 'vp' },
888890
});
889891
resumeCreateProgress();
890892

packages/cli/src/utils/__tests__/editor.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,26 @@ describe('writeEditorConfigs', () => {
3838
expect(settings['editor.defaultFormatter']).toBe('oxc.oxc-vscode');
3939
expect(settings['oxc.fmt.configPath']).toBe('./vite.config.ts');
4040
expect(settings['editor.formatOnSave']).toBe(true);
41+
expect(settings['npm.scriptRunner']).toBeUndefined();
42+
});
43+
44+
it('includes additionalSettings in vscode settings.json when provided', async () => {
45+
const projectRoot = createTempDir();
46+
47+
await writeEditorConfigs({
48+
projectRoot,
49+
editorId: 'vscode',
50+
interactive: false,
51+
silent: true,
52+
additionalSettings: { 'npm.scriptRunner': 'vp' },
53+
});
54+
55+
const settings = JSON.parse(
56+
fs.readFileSync(path.join(projectRoot, '.vscode', 'settings.json'), 'utf8'),
57+
) as Record<string, unknown>;
58+
4159
expect(settings['npm.scriptRunner']).toBe('vp');
60+
expect(settings['editor.defaultFormatter']).toBe('oxc.oxc-vscode');
4261
});
4362

4463
it('merges existing vscode JSONC settings (comments, trailing commas)', async () => {
@@ -65,6 +84,7 @@ describe('writeEditorConfigs', () => {
6584
editorId: 'vscode',
6685
interactive: false,
6786
silent: true,
87+
additionalSettings: { 'npm.scriptRunner': 'vp' },
6888
});
6989

7090
const settings = JSON.parse(

packages/cli/src/utils/editor.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const VSCODE_SETTINGS = {
1717
'editor.codeActionsOnSave': {
1818
'source.fixAll.oxc': 'explicit',
1919
},
20-
'npm.scriptRunner': 'vp',
2120
} as const;
2221

2322
const VSCODE_EXTENSIONS = {
@@ -268,12 +267,14 @@ export async function writeEditorConfigs({
268267
interactive,
269268
conflictDecisions,
270269
silent = false,
270+
additionalSettings,
271271
}: {
272272
projectRoot: string;
273273
editorId: EditorId | undefined;
274274
interactive: boolean;
275275
conflictDecisions?: Map<string, 'merge' | 'skip'>;
276276
silent?: boolean;
277+
additionalSettings?: Record<string, unknown>;
277278
}) {
278279
if (!editorId) {
279280
return;
@@ -287,7 +288,11 @@ export async function writeEditorConfigs({
287288
const targetDir = path.join(projectRoot, editorConfig.targetDir);
288289
await fsPromises.mkdir(targetDir, { recursive: true });
289290

290-
for (const [fileName, incoming] of Object.entries(editorConfig.files)) {
291+
for (const [fileName, baseIncoming] of Object.entries(editorConfig.files)) {
292+
const incoming =
293+
fileName === 'settings.json' && additionalSettings
294+
? { ...baseIncoming, ...additionalSettings }
295+
: baseIncoming;
291296
const filePath = path.join(targetDir, fileName);
292297

293298
if (fs.existsSync(filePath)) {

0 commit comments

Comments
 (0)