config-vp 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,13 +47,13 @@ This also pulls in everything the config needs (`oxlint`, `oxfmt`, and the lint
47
47
  **2. Create `vite.config.ts`:**
48
48
 
49
49
  ```ts
50
- import { defineConfig } from 'config-vp';
50
+ import { defineVitePlusConfig } from 'config-vp';
51
51
 
52
- const config = defineConfig({ type: 'lib' });
52
+ const config = defineVitePlusConfig({ type: 'lib' });
53
53
  export default config;
54
54
  ```
55
55
 
56
- > **Important:** Assign to a `const` and export it — don't write `export default defineConfig(...)` inline. `vp` reads your default export statically to discover tasks; a direct call hides them and `vp run` reports "Task not found". See [Troubleshooting](#troubleshooting).
56
+ > **Important:** Assign to a `const` and export it — don't write `export default defineVitePlusConfig(...)` inline. `vp` reads your default export statically to discover tasks; a direct call hides them and `vp run` reports "Task not found". See [Troubleshooting](#troubleshooting).
57
57
 
58
58
  **3. Run something:**
59
59
 
@@ -83,38 +83,32 @@ Set `type` to match what you're building. It drives Vue lint rules, library pack
83
83
 
84
84
  Customize with the `config` hook — it receives the fully built config (see [Customizing](#customizing)).
85
85
 
86
- **Library** — dual ESM + CJS output:
86
+ **Plain package** — lint + format + tests only, no build/dev (e.g. a config or scripts-only package). Just call `defineVitePlusConfig()` with no `type`:
87
87
 
88
88
  ```ts
89
- import { defineConfig } from 'config-vp';
89
+ import { defineVitePlusConfig } from 'config-vp';
90
90
 
91
- const config = defineConfig({
92
- type: 'lib',
93
- config: c => {
94
- c.pack = {
95
- ...c.pack,
96
- entry: ['src/index.ts'],
97
- format: ['esm', 'cjs'],
98
- };
99
- },
100
- });
91
+ const config = defineVitePlusConfig();
101
92
  export default config;
102
93
  ```
103
94
 
104
- **Vue library** — same, with `type: 'lib:vue'` for SFC/template lint rules.
95
+ **Vue app** — a Vite-based Vue application, with plugins and a path alias:
105
96
 
106
97
  ```ts
107
- import { defineConfig } from 'config-vp';
98
+ import vue from '@vitejs/plugin-vue';
99
+ import { defineVitePlusConfig } from 'config-vp';
100
+ import { fileURLToPath, URL } from 'node:url';
101
+ import vueDevTools from 'vite-plugin-vue-devtools';
108
102
 
109
- const config = defineConfig({
110
- type: 'lib:vue',
111
- config: c => {
112
- c.pack = {
113
- ...c.pack,
114
- entry: ['src/index.ts'],
115
- format: ['esm', 'cjs'],
116
- };
117
- },
103
+ const config = defineVitePlusConfig({
104
+ type: 'vue',
105
+ config: c => ({
106
+ ...c,
107
+ plugins: [vue(), vueDevTools()],
108
+ resolve: {
109
+ alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) },
110
+ },
111
+ }),
118
112
  });
119
113
  export default config;
120
114
  ```
@@ -124,9 +118,9 @@ export default config;
124
118
  ```ts
125
119
  // nuxt.config.vite.ts
126
120
  import type { NuxtConfig } from 'nuxt/schema';
127
- import { defineConfig } from 'config-vp';
121
+ import { defineVitePlusConfig } from 'config-vp';
128
122
 
129
- export const vite = defineConfig({
123
+ export const vite = defineVitePlusConfig({
130
124
  type: 'nuxt:spa', // or 'nuxt:ssr'
131
125
  config: c => {
132
126
  // any Vite/vite-plus options the app needs, e.g. plugins, define, test, …
@@ -144,12 +138,39 @@ export default defineNuxtConfig({ vite });
144
138
 
145
139
  The `export const vite = …` form is itself a const export, so `vp` discovers any tasks you add in the `config` hook.
146
140
 
147
- **Plain package** — lint + format + tests only, no build/dev (e.g. a config or scripts-only package). Just call `defineConfig()` with no `type`:
141
+ **Library** — dual ESM + CJS output:
142
+
143
+ ```ts
144
+ import { defineVitePlusConfig } from 'config-vp';
145
+
146
+ const config = defineVitePlusConfig({
147
+ type: 'lib',
148
+ config: c => {
149
+ c.pack = {
150
+ ...c.pack,
151
+ entry: ['src/index.ts'],
152
+ format: ['esm', 'cjs'],
153
+ };
154
+ },
155
+ });
156
+ export default config;
157
+ ```
158
+
159
+ **Vue library** — same, with `type: 'lib:vue'` for SFC/template lint rules.
148
160
 
149
161
  ```ts
150
- import { defineConfig } from 'config-vp';
162
+ import { defineVitePlusConfig } from 'config-vp';
151
163
 
152
- const config = defineConfig();
164
+ const config = defineVitePlusConfig({
165
+ type: 'lib:vue',
166
+ config: c => {
167
+ c.pack = {
168
+ ...c.pack,
169
+ entry: ['src/index.ts'],
170
+ format: ['esm', 'cjs'],
171
+ };
172
+ },
173
+ });
153
174
  export default config;
154
175
  ```
155
176
 
@@ -192,12 +213,31 @@ Run any task with `vp run <task>`. Tasks are cached and run in dependency order
192
213
 
193
214
  > For a whole-workspace lint/format, use the built-in `vp check`. To build every package, use `vp run -r build`.
194
215
 
216
+ ### Overriding a task with a package.json script
217
+
218
+ **Your `package.json` scripts win.** If a package defines a script with the same name as a generated task, config-vp drops its own task and your script takes over — no clash, no config needed:
219
+
220
+ ```jsonc
221
+ // package.json
222
+ {
223
+ "scripts": {
224
+ "build": "tsx scripts/build.ts", // replaces the generated `build` task
225
+ },
226
+ }
227
+ ```
228
+
229
+ ```sh
230
+ vp run build # runs your script, not `vp pack`
231
+ ```
232
+
233
+ This is the simplest way to special-case one task while keeping every other default. (Without it, `vp` errors with _"Task `build` conflicts with a package.json script of the same name"_.) For richer changes — tweaking a task's command, cache behavior, or adding new tasks — use the [`config` hook](#customizing) instead; reach for a script only when you want to shadow a task outright.
234
+
195
235
  ## Customizing
196
236
 
197
237
  There's one customization hook: **`config`**. It receives the fully built config — lint, fmt, staged, run tasks, and (for `lib*`) pack, all already populated — and you change whatever you want with plain JS. Mutate it in place, or return a new object (a returned value wins; otherwise the mutated argument is used). It's fully typed, so autocomplete shows you exactly what's there.
198
238
 
199
239
  ```ts
200
- const config = defineConfig({
240
+ const config = defineVitePlusConfig({
201
241
  type: 'lib',
202
242
  config: c => {
203
243
  c.pack = {
@@ -220,7 +260,7 @@ The hook works two ways — use whichever reads better:
220
260
 
221
261
  ```ts
222
262
  // Mutate in place and return nothing — best for a few targeted tweaks:
223
- defineConfig({
263
+ defineVitePlusConfig({
224
264
  type: 'lib',
225
265
  config: c => {
226
266
  c.pack = {
@@ -231,7 +271,7 @@ defineConfig({
231
271
  });
232
272
 
233
273
  // Return a new object — best when you want to build the result explicitly:
234
- defineConfig({
274
+ defineVitePlusConfig({
235
275
  type: 'lib',
236
276
  config: c => ({
237
277
  ...c,
@@ -250,7 +290,7 @@ A returned value wins; if you return nothing, the mutated argument is used. Don'
250
290
  Anything in a normal Vite / vite-plus config — `plugins`, `resolve`, `define`, `server`, `optimizeDeps`, `worker`, `test`, `build`, extra `run.tasks`, … — is just a field you set in the hook. Nothing config-vp-specific to learn; keep writing Vite config.
251
291
 
252
292
  ```ts
253
- const config = defineConfig({
293
+ const config = defineVitePlusConfig({
254
294
  type: 'nuxt:spa',
255
295
  config: c => {
256
296
  c.plugins = [...tailwindcss()];
@@ -279,13 +319,13 @@ export default config;
279
319
  `ignorePatterns` sets the ignore globs for **both** the linter and the formatter. Pass an array to set the whole list, or a function to derive it from the built-in defaults:
280
320
 
281
321
  ```ts
282
- defineConfig({
322
+ defineVitePlusConfig({
283
323
  type: 'lib',
284
324
  // add to the defaults:
285
325
  ignorePatterns: defaults => [...defaults, 'generated/**', 'vendor/**'],
286
326
  });
287
327
 
288
- defineConfig({
328
+ defineVitePlusConfig({
289
329
  type: 'lib',
290
330
  // …or set the list outright:
291
331
  ignorePatterns: ['only-this/**'],
@@ -297,7 +337,7 @@ defineConfig({
297
337
  A `lib*` type includes packaging by default. To skip it, delete `pack` in the hook:
298
338
 
299
339
  ```ts
300
- defineConfig({
340
+ defineVitePlusConfig({
301
341
  type: 'lib',
302
342
  config: c => {
303
343
  delete c.pack;
@@ -327,7 +367,7 @@ The base list applied to both linting and formatting (override or extend it via
327
367
 
328
368
  ## API
329
369
 
330
- The package exports a single function, `defineConfig`, plus the types `ConfigOptions` (its argument), `ProjectType`, and `ResolvedConfig` (the value passed to the `config` hook).
370
+ The package exports a single function, `defineVitePlusConfig`, plus the types `ConfigOptions` (its argument), `ProjectType`, and `ResolvedConfig` (the value passed to the `config` hook).
331
371
 
332
372
  ## Troubleshooting
333
373
 
@@ -337,10 +377,10 @@ Your config almost certainly uses an inline default export. `vp` discovers tasks
337
377
 
338
378
  ```ts
339
379
  // ❌ tasks are invisible to `vp run`
340
- export default defineConfig({ type: 'lib' });
380
+ export default defineVitePlusConfig({ type: 'lib' });
341
381
 
342
382
  // ✅ assign, then export
343
- const config = defineConfig({ type: 'lib' });
383
+ const config = defineVitePlusConfig({ type: 'lib' });
344
384
  export default config;
345
385
  ```
346
386
 
package/dist/index.d.mts CHANGED
@@ -36,6 +36,6 @@ interface ConfigOptions {
36
36
  */
37
37
  config?: (config: ResolvedConfig) => ResolvedConfig | undefined;
38
38
  }
39
- declare function defineConfig(options?: ConfigOptions): UserConfig;
39
+ declare function defineVitePlusConfig(options?: ConfigOptions): UserConfig;
40
40
  //#endregion
41
- export { ConfigOptions, ProjectType, ResolvedConfig, defineConfig };
41
+ export { ConfigOptions, ProjectType, ResolvedConfig, defineVitePlusConfig };
package/dist/index.mjs CHANGED
@@ -531,6 +531,16 @@ function callerPackageDir() {
531
531
  if (direct && !direct[1].includes("/node_modules/")) return direct[1];
532
532
  }
533
533
  }
534
+ /** Script names in the calling package's package.json — these override our generated tasks. */
535
+ function packageScriptNames() {
536
+ const dir = callerPackageDir() ?? process.cwd();
537
+ try {
538
+ const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
539
+ return new Set(Object.keys(pkg.scripts ?? {}));
540
+ } catch {
541
+ return /* @__PURE__ */ new Set();
542
+ }
543
+ }
534
544
  /** True when the calling config's package is the workspace root (or a standalone project). */
535
545
  function isProjectRoot() {
536
546
  const dir = callerPackageDir() ?? process.cwd();
@@ -590,7 +600,8 @@ function buildRunConfig(options = {}) {
590
600
  command: "vp-setup-vscode",
591
601
  cache: false
592
602
  };
593
- return { tasks };
603
+ const scripts = packageScriptNames();
604
+ return { tasks: Object.fromEntries(Object.entries(tasks).filter(([name]) => !scripts.has(name))) };
594
605
  }
595
606
  //#endregion
596
607
  //#region src/staged.ts
@@ -652,7 +663,7 @@ function mergeLintConfigs(...configs) {
652
663
  return merged;
653
664
  });
654
665
  }
655
- function defineConfig(options = {}) {
666
+ function defineVitePlusConfig(options = {}) {
656
667
  const t = options.type;
657
668
  const isVue = t === "lib:vue" || t === "lib:nuxt" || t === "vue" || t === "nuxt:spa" || t === "nuxt:ssr";
658
669
  const isLib = t === "lib" || t === "lib:vue" || t === "lib:nuxt";
@@ -680,4 +691,4 @@ function defineConfig(options = {}) {
680
691
  return options.config ? options.config(base) ?? base : base;
681
692
  }
682
693
  //#endregion
683
- export { defineConfig };
694
+ export { defineVitePlusConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "config-vp",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Shared vite-plus configuration — opinionated defaults for linting, formatting, task running, staged checks, and VSCode setup. Optional Vue and pack layers with deep-merge overrides.",
5
5
  "keywords": [
6
6
  "config",