kirbyup 4.0.0-alpha.6 → 4.0.0-alpha.7

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
@@ -2,23 +2,31 @@
2
2
 
3
3
  # kirbyup
4
4
 
5
- The official bundler for Kirby Panel plugins with zero-config usage and built-in HMR.
5
+ The official bundler for Kirby Panel plugins. Zero-config, built-in HMR.
6
6
 
7
7
  - [✨  Release Notes](https://github.com/johannschopplich/kirbyup/releases)
8
8
  - [📖  Read the documentation](https://kirbyup.getkirby.com)
9
9
 
10
10
  ## Key Features
11
11
 
12
- - 🔄 [Hot module replacement](https://kirbyup.getkirby.com/guide/getting-started.html#development)
13
- - 🎒 PostCSS support
14
- - 🧭 Add custom path aliases
15
- - 🔌 Run actions based on environment variables
16
- - 🦔 [Extends Vite with `kirbyup.config.js`](https://kirbyup.getkirby.com/guide/config-file)
12
+ - 🔄 [Hot Module Replacement](https://kirbyup.getkirby.com/guide/getting-started.html#development)
13
+ - 🎒 [PostCSS & Sass](https://kirbyup.getkirby.com/guide/postcss)
14
+ - 🧩 [kirbyuse Integration](https://kirbyup.getkirby.com/guide/kirbyuse)
15
+ - 🔌 [Environment Variables](https://kirbyup.getkirby.com/guide/environment-variables)
16
+ - 🦔 [Configuration File](https://kirbyup.getkirby.com/guide/config-file)
17
+ - 🧭 [Path Aliases](https://kirbyup.getkirby.com/guide/path-aliases)
18
+
19
+ ## Requirements
20
+
21
+ - **Node.js 24+**: paired with a package manager (pnpm, npm, or yarn).
22
+ - **Kirby 6 or newer**: kirbyup 4.x targets the Vue 3-based Panel runtime introduced in Kirby 6. For Kirby 4 or 5 plugins, use kirbyup 3.x.
17
23
 
18
24
  ## Setup
19
25
 
20
26
  > [!TIP]
21
- > [📖 Read the documentation](https://kirbyup.getkirby.com)
27
+ > Skip starting from scratch and pick one of the following starters:
28
+ > - [`eslint`](./examples/eslint)
29
+ > - [`unocss`](./examples/unocss)
22
30
 
23
31
  ```bash
24
32
  # pnpm
@@ -26,16 +34,12 @@ pnpm add -D kirbyup
26
34
 
27
35
  # npm
28
36
  npm i -D kirbyup
29
- ```
30
37
 
31
- ## Basic Usage
32
-
33
- > [!TIP]
34
- > [📖 Read the documentation](https://kirbyup.getkirby.com) or skip starting from scratch and pick one of the following starters:
35
- > - [`eslint`](./examples/eslint)
36
- > - [`unocss`](./examples/unocss)
38
+ # yarn
39
+ yarn add -D kirbyup
40
+ ```
37
41
 
38
- Having installed kirbyup, you can add the following scripts as shortcuts to the commands you will use most often:
42
+ After installation, add these scripts to your `package.json`:
39
43
 
40
44
  ```json
41
45
  {
@@ -44,18 +48,18 @@ Having installed kirbyup, you can add the following scripts as shortcuts to the
44
48
  "build": "kirbyup src/index.js"
45
49
  },
46
50
  "devDependencies": {
47
- "kirbyup": "^3.4.0"
51
+ "kirbyup": "^4.0.0-alpha.6"
48
52
  }
49
53
  }
50
54
  ```
51
55
 
52
- ## 💻 Development
56
+ ## Development
53
57
 
54
58
  1. Clone this repository
55
59
  2. Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
56
60
  3. Install dependencies using `pnpm install`
57
- 4. Run `pnpm run dev:prepare`
58
- 5. Start development server using `pnpm run dev`
61
+ 4. Build with `pnpm run build`
62
+ 5. Run tests with `pnpm test`
59
63
 
60
64
  ## License
61
65
 
@@ -1,4 +1,4 @@
1
- import { r as UserConfig } from "../types-0NUTyTUQ.mjs";
1
+ import { r as UserConfig } from "../types-3hN383nZ.mjs";
2
2
 
3
3
  //#region src/client/config.d.ts
4
4
  declare function defineConfig(config: UserConfig): UserConfig;
@@ -8,6 +8,7 @@ const kirbyup = Object.freeze({
8
8
  * kirbyup.import('./components/blocks/*.vue')
9
9
  */
10
10
  import(glob) {
11
+ if (typeof glob === "string") throw new TypeError("[kirbyup] kirbyup.import() requires the kirbyup build pipeline. The call must be transformed at build time by the kirbyup:glob-import plugin.");
11
12
  return Object.entries(glob).reduce((accumulator, [path, component]) => {
12
13
  accumulator[getComponentName(path)] = component.default;
13
14
  return accumulator;
package/dist/node/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as version, i as name, n as serve, r as handleError, t as build } from "../node-Do_IAs2E.mjs";
1
+ import { a as version, i as name, n as serve, r as handleError, t as build } from "../node-BAAmufwc.mjs";
2
2
  import { cac } from "cac";
3
3
  //#region src/node/cli-start.ts
4
4
  async function startCli(cwd = process.cwd(), argv = process.argv) {
@@ -1,4 +1,4 @@
1
- import { n as ServeOptions, t as BuildOptions } from "../types-0NUTyTUQ.mjs";
1
+ import { n as ServeOptions, t as BuildOptions } from "../types-3hN383nZ.mjs";
2
2
  import { ViteDevServer } from "vite";
3
3
 
4
4
  //#region src/node/index.d.ts
@@ -1,2 +1,2 @@
1
- import { n as serve, t as build } from "../node-Do_IAs2E.mjs";
1
+ import { n as serve, t as build } from "../node-BAAmufwc.mjs";
2
2
  export { build, serve };
@@ -6,20 +6,17 @@ import { consola } from "consola";
6
6
  import { colors } from "consola/utils";
7
7
  import { basename, dirname, normalize, relative, resolve } from "pathe";
8
8
  import { debounce } from "perfect-debounce";
9
- import { build, createLogger, createServer, mergeConfig, normalizePath } from "vite";
10
- import fullReloadPlugin from "vite-plugin-full-reload";
9
+ import { build, createFilter, createLogger, createServer, mergeConfig, normalizePath } from "vite";
11
10
  import * as vueCompilerSfc from "vue/compiler-sfc";
12
11
  import { loadConfig } from "c12";
13
- import postcssrc from "postcss-load-config";
14
- import { fileURLToPath, pathToFileURL } from "node:url";
15
- import { detectPackageManager } from "nypm";
12
+ import postcssrcLoad from "postcss-load-config";
13
+ import { gzipSync } from "node:zlib";
14
+ import MagicString from "magic-string";
15
+ import { stripLiteral } from "strip-literal";
16
16
  import { isIP } from "node:net";
17
- import { Buffer } from "node:buffer";
18
- import { promisify } from "node:util";
19
- import { gzip } from "node:zlib";
20
17
  //#region package.json
21
18
  var name = "kirbyup";
22
- var version = "4.0.0-alpha.6";
19
+ var version = "4.0.0-alpha.7";
23
20
  //#endregion
24
21
  //#region src/node/config.ts
25
22
  function loadConfig$1(cwd = process.cwd()) {
@@ -32,7 +29,7 @@ function loadConfig$1(cwd = process.cwd()) {
32
29
  }
33
30
  async function resolvePostCSSConfig(cwd) {
34
31
  try {
35
- return await postcssrc(void 0, void 0, { stopDir: cwd });
32
+ return await postcssrcLoad(void 0, void 0, { stopDir: cwd });
36
33
  } catch (error) {
37
34
  if (!error.message.includes("No PostCSS Config found")) throw error;
38
35
  }
@@ -43,8 +40,7 @@ var PrettyError = class extends Error {
43
40
  constructor(message) {
44
41
  super(message);
45
42
  this.name = this.constructor.name;
46
- if (typeof Error.captureStackTrace === "function") Error.captureStackTrace(this, this.constructor);
47
- else this.stack = new Error(message).stack;
43
+ Error.captureStackTrace(this, this.constructor);
48
44
  }
49
45
  };
50
46
  function handleError(error) {
@@ -69,14 +65,93 @@ function kirbyupBuildCleanupPlugin(options) {
69
65
  };
70
66
  }
71
67
  //#endregion
68
+ //#region src/node/utils.ts
69
+ function toArray(array) {
70
+ array ??= [];
71
+ return Array.isArray(array) ? array : [array];
72
+ }
73
+ async function printFileInfo({ root, outDir, filePath, content, type, maxLength }) {
74
+ const prettyOutDir = `${normalize(relative(root, outDir))}/`;
75
+ const kibs = content.length / 1024;
76
+ const compressedKibs = gzipSync(content).length / 1024;
77
+ const writeColor = type === "chunk" ? colors.cyan : colors.magenta;
78
+ consola.log(colors.white(colors.dim(prettyOutDir)) + writeColor(filePath.padEnd(maxLength + 2)) + colors.dim(`${kibs.toFixed(2)} kB / gzip: ${compressedKibs.toFixed(2)} KiB`));
79
+ }
80
+ //#endregion
81
+ //#region src/node/plugins/full-reload.ts
82
+ /**
83
+ * Triggers a full browser reload when files matching the given globs change.
84
+ * Vite forces chokidar's `disableGlobbing: true` by default; this plugin
85
+ * resets it so glob strings passed to `watcher.add` are expanded by chokidar.
86
+ */
87
+ function kirbyupFullReloadPlugin(paths) {
88
+ return {
89
+ name: "kirbyup:full-reload",
90
+ apply: "serve",
91
+ config() {
92
+ return { server: { watch: { disableGlobbing: false } } };
93
+ },
94
+ configureServer({ watcher, ws, config: { root, logger } }) {
95
+ const files = toArray(paths).map((p) => resolve(root, p));
96
+ const matches = createFilter(files);
97
+ watcher.add(files);
98
+ const reload = (path) => {
99
+ if (!matches(path)) return;
100
+ setTimeout(() => ws.send({
101
+ type: "full-reload",
102
+ path: "*"
103
+ }), 0);
104
+ logger.info(`${colors.green("full reload")} ${colors.dim(relative(root, path))}`, {
105
+ clear: true,
106
+ timestamp: true
107
+ });
108
+ };
109
+ watcher.on("add", reload);
110
+ watcher.on("change", reload);
111
+ }
112
+ };
113
+ }
114
+ //#endregion
115
+ //#region src/node/plugins/glob-import.ts
116
+ /**
117
+ * Transforms `kirbyup.import(<path>)` to `kirbyup.import(import.meta.glob(<path>, { eager: true }))`.
118
+ *
119
+ * Must run before Vite's own `import.meta.glob` plugin (also `enforce: 'pre'`),
120
+ * otherwise the emitted call is never expanded.
121
+ */
122
+ function kirbyupGlobImportPlugin() {
123
+ let config;
124
+ return {
125
+ name: "kirbyup:glob-import",
126
+ enforce: "pre",
127
+ configResolved(resolvedConfig) {
128
+ config = resolvedConfig;
129
+ },
130
+ transform(code) {
131
+ if (!code.includes("kirbyup.import")) return;
132
+ const kirbyupImportRE = /\bkirbyup\.import\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*\)/dg;
133
+ const cleanCode = stripLiteral(code);
134
+ let s;
135
+ for (const match of cleanCode.matchAll(kirbyupImportRE)) {
136
+ const { 0: exp, index } = match;
137
+ const [argStart, argEnd] = match.indices[1];
138
+ const rawPath = code.slice(argStart, argEnd);
139
+ if (!s) s = new MagicString(code);
140
+ s.overwrite(index, index + exp.length, `kirbyup.import(import.meta.glob(${rawPath}, { eager: true }))`);
141
+ }
142
+ if (s) return {
143
+ code: s.toString(),
144
+ map: config.build.sourcemap ? s.generateMap({ hires: true }) : void 0
145
+ };
146
+ }
147
+ };
148
+ }
149
+ //#endregion
72
150
  //#region src/node/utils/server.ts
73
151
  function resolveOriginFromServerOptions(serverOptions, port, fallbackHostname) {
74
152
  const protocol = serverOptions?.https && (typeof serverOptions.https === "boolean" || Object.keys(serverOptions.https).length > 0) ? "https" : "http";
75
153
  const configuredHost = normalizeHost(serverOptions?.host);
76
- return `${protocol}://${formatHostname(configuredHost || fallbackHostname || "localhost")}${(configuredHost ? hostIncludesPort(configuredHost) : false) || !needsExplicitPort(protocol, port) ? "" : `:${port}`}`;
77
- }
78
- function ensureTrailingSlash(url) {
79
- return url.endsWith("/") ? url : `${url}/`;
154
+ return `${protocol}://${formatHostname(configuredHost || fallbackHostname || "localhost")}${(configuredHost ? hostIncludesPort(configuredHost) : false) || protocol === "http" && port === 80 || protocol === "https" && port === 443 ? "" : `:${port}`}`;
80
155
  }
81
156
  function normalizeHost(host) {
82
157
  if (host === false || host === void 0) return;
@@ -96,10 +171,6 @@ function hostIncludesPort(host) {
96
171
  if (isIP(host) === 6) return false;
97
172
  return host.includes(":");
98
173
  }
99
- function needsExplicitPort(protocol, port) {
100
- if (protocol === "http") return port !== 80;
101
- return port !== 443;
102
- }
103
174
  //#endregion
104
175
  //#region src/node/plugins/runtime/hmr-shim.js?raw
105
176
  var hmr_shim_default = "/* eslint-disable no-undef */\nimport 'vue'\n\nif (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {\n const originalReload = __VUE_HMR_RUNTIME__.reload\n\n __VUE_HMR_RUNTIME__.reload = function (id, newComp) {\n const plugins = window.panel && window.panel.plugins\n const app = window.panel && window.panel.app\n\n if (\n plugins\n && app\n && plugins.components\n && typeof plugins.resolveComponentExtension === 'function'\n && typeof plugins.resolveComponentRender === 'function'\n && typeof plugins.resolveComponentMixins === 'function'\n ) {\n for (const name in plugins.components) {\n const pluginComp = plugins.components[name]\n if (\n pluginComp.__hmrId === id\n || (newComp.__file && pluginComp.__file === newComp.__file)\n ) {\n plugins.resolveComponentExtension(app, name, newComp)\n plugins.resolveComponentRender(newComp)\n plugins.resolveComponentMixins(newComp)\n break\n }\n }\n }\n\n return originalReload.call(this, id, newComp)\n }\n}\nelse {\n console.warn(\n '[kirbyup] Vue HMR runtime not detected; component changes will fall back to full page reload. The Kirby Panel may be loading a production build of Vue.',\n )\n}\n";
@@ -118,21 +189,6 @@ var vue_stub_default = "const __kirbyupVueImportMapEl = typeof document !== 'und
118
189
  */
119
190
  const __HMR_SHIM_CODE__ = hmr_shim_default;
120
191
  /**
121
- * Extract public named exports from a Rollup-style ESM bundle. Vue's
122
- * `dist/vue.esm-browser.js` ships a single trailing `export { ... }` block
123
- * with a few `internalName as publicName` aliases.
124
- *
125
- * Only the last block is read; `as`-aliased entries yield the public name.
126
- */
127
- function extractEsmNamedExports(source) {
128
- const blockMatches = [...source.matchAll(/export\s*\{([^}]*)\}/g)];
129
- if (blockMatches.length === 0) return [];
130
- return blockMatches.at(-1)[1].split(",").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
131
- const aliasMatch = entry.match(/^\S+\s+as\s+(\S+)$/);
132
- return aliasMatch ? aliasMatch[1] : entry;
133
- });
134
- }
135
- /**
136
192
  * Reads Kirby's panel-vue URL at runtime from the page's
137
193
  * `<script type="importmap">` and dynamic-imports it; the browser's module
138
194
  * map dedups by URL, so plugin SFCs share Kirby's Vue instance (and
@@ -149,7 +205,7 @@ const SHIM_ID = "\0kirbyup:hmr-shim";
149
205
  const SHIM_PUBLIC_ID = SHIM_ID.slice(1);
150
206
  const VUE_STUB_ID = "\0kirbyup:vue-stub";
151
207
  const VUE_STUB_PUBLIC_ID = VUE_STUB_ID.slice(1);
152
- const VUE_NOT_FOUND_STUB = `throw new Error('[kirbyup] Cannot resolve "vue/dist/vue.esm-browser.js" from the plugin project. Make sure "vue" is installed as a dependency.')\n`;
208
+ const VUE_NOT_FOUND_STUB = `throw new Error('[kirbyup] Cannot resolve "vue" from the plugin project. Make sure "vue" is installed as a dependency.')\n`;
153
209
  function kirbyupHmrPlugin(options) {
154
210
  let config;
155
211
  let entry;
@@ -169,14 +225,14 @@ function kirbyupHmrPlugin(options) {
169
225
  }] }
170
226
  };
171
227
  },
172
- configResolved(resolvedConfig) {
228
+ async configResolved(resolvedConfig) {
173
229
  config = resolvedConfig;
174
230
  entry = resolve(config.root, options.entry);
175
231
  entryId = normalizePath(entry);
176
232
  devIndexPath = resolve(config.root, options.outDir ?? "", "index.dev.js");
177
233
  try {
178
- const vueUrl = import.meta.resolve("vue/dist/vue.esm-browser.js", pathToFileURL(`${config.root}/_`).href);
179
- const namedExports = extractEsmNamedExports(fs.readFileSync(fileURLToPath(vueUrl), "utf8"));
234
+ const vueModule = await import("vue");
235
+ const namedExports = Object.keys(vueModule).filter((name) => name !== "default");
180
236
  vueStubCode = namedExports.length > 0 ? buildVueStubCode(namedExports) : void 0;
181
237
  } catch {
182
238
  vueStubCode = void 0;
@@ -212,7 +268,7 @@ function kirbyupHmrPlugin(options) {
212
268
  const entryPath = entry.replace(`${config.root}/`, "");
213
269
  const baseUrl = getDevBaseUrl(server, config);
214
270
  const entryUrl = new URL(entryPath, baseUrl).href;
215
- const pm = await detectPackageManager(config.root);
271
+ const pm = detectPackageManager(config.root);
216
272
  await fsp.writeFile(devIndexPath, getViteProxyModule(entryUrl, pm));
217
273
  });
218
274
  },
@@ -222,13 +278,12 @@ function kirbyupHmrPlugin(options) {
222
278
  };
223
279
  }
224
280
  function getViteProxyModule(entryUrl, packageManager) {
225
- const pm = packageManager?.name || "npm";
226
281
  return `
227
282
  try {
228
283
  await import("${entryUrl}");
229
284
  } catch (error) {
230
285
  console.error(
231
- "[kirbyup] Couldn't connect to the development server at ${entryUrl}. Run \`${pm} run serve\` to start Vite or build the plugin with \`${pm} run build\` so Kirby uses the production version."
286
+ "[kirbyup] Couldn't connect to the development server at ${entryUrl}. Run \`${packageManager} run serve\` to start Vite or build the plugin with \`${packageManager} run build\` so Kirby uses the production version."
232
287
  );
233
288
  throw error;
234
289
  }
@@ -236,42 +291,25 @@ try {
236
291
  }
237
292
  function getDevBaseUrl(server, config) {
238
293
  const { address, port } = server.httpServer.address();
239
- const normalizedOrigin = ensureTrailingSlash(config.server?.origin ?? server.resolvedUrls?.local?.[0] ?? server.resolvedUrls?.network?.[0] ?? resolveOriginFromServerOptions(config.server, port, address));
294
+ const origin = config.server?.origin ?? server.resolvedUrls?.local?.[0] ?? server.resolvedUrls?.network?.[0] ?? resolveOriginFromServerOptions(config.server, port, address);
240
295
  const base = config.base ?? "/";
241
- return new URL(base, normalizedOrigin).href;
242
- }
243
- //#endregion
244
- //#region src/node/utils.ts
245
- const compress = promisify(gzip);
246
- function toArray(array) {
247
- array ??= [];
248
- return Array.isArray(array) ? array : [array];
296
+ return new URL(base, origin).href;
249
297
  }
250
- async function getCompressedSize(code) {
251
- return ` / gzip: ${((await compress(typeof code === "string" ? code : Buffer.from(code))).length / 1024).toFixed(2)} KiB`;
252
- }
253
- async function printFileInfo({ root, outDir, filePath, content, type, maxLength }) {
254
- const prettyOutDir = `${normalize(relative(root, resolve(root, outDir)))}/`;
255
- const kibs = content.length / 1024;
256
- const compressedSize = await getCompressedSize(content);
257
- const writeColor = type === "chunk" ? colors.cyan : colors.magenta;
258
- consola.log(colors.white(colors.dim(prettyOutDir)) + writeColor(filePath.padEnd(maxLength + 2)) + colors.dim(`${kibs.toFixed(2)} kB${compressedSize}`));
298
+ function detectPackageManager(cwd) {
299
+ if (fs.existsSync(resolve(cwd, "pnpm-lock.yaml"))) return "pnpm";
300
+ if (fs.existsSync(resolve(cwd, "bun.lock")) || fs.existsSync(resolve(cwd, "bun.lockb"))) return "bun";
301
+ if (fs.existsSync(resolve(cwd, "yarn.lock"))) return "yarn";
302
+ if (fs.existsSync(resolve(cwd, "deno.lock"))) return "deno";
303
+ return "npm";
259
304
  }
260
305
  //#endregion
261
306
  //#region src/node/index.ts
262
307
  const DEV_OUTPUT_FILENAME = "index.dev.js";
263
- let resolvedKirbyupConfig;
264
- let resolvedPostCssConfig;
308
+ const SUPPRESSED_WARNING_PREFIX = "\n(!) build.outDir";
265
309
  const logLevel = "warn";
266
- const logger = createLogger(logLevel);
267
- const loggerWarn = logger.warn;
268
- logger.warn = (msg, options) => {
269
- if (msg.includes("(!) build.outDir")) return;
270
- loggerWarn(msg, options);
271
- };
272
- function getViteConfig(command, options) {
310
+ function getViteConfig(command, options, { kirbyupConfig, postCssConfig, logger }) {
273
311
  const aliasDir = resolve(options.cwd, dirname(options.entry));
274
- const { alias = {}, vite } = resolvedKirbyupConfig;
312
+ const { alias = {}, vite } = kirbyupConfig;
275
313
  const userConfig = vite ?? {};
276
314
  const sharedConfig = {
277
315
  resolve: { alias: {
@@ -279,9 +317,16 @@ function getViteConfig(command, options) {
279
317
  "@/": `${aliasDir}/`,
280
318
  ...alias
281
319
  } },
282
- plugins: [vuePlugin({ compiler: vueCompilerSfc }), vueJsxPlugin()],
320
+ plugins: [
321
+ vuePlugin({ compiler: vueCompilerSfc }),
322
+ vueJsxPlugin(),
323
+ kirbyupGlobImportPlugin()
324
+ ],
283
325
  build: { copyPublicDir: false },
284
- ...resolvedPostCssConfig && { css: { postcss: resolvedPostCssConfig } },
326
+ ...postCssConfig && { css: { postcss: {
327
+ ...postCssConfig.options,
328
+ plugins: postCssConfig.plugins
329
+ } } },
285
330
  envDir: options.cwd,
286
331
  envPrefix: ["VITE_", "KIRBYUP_"],
287
332
  customLogger: logger,
@@ -291,7 +336,7 @@ function getViteConfig(command, options) {
291
336
  const { port, watch } = options;
292
337
  const inferredOrigin = userConfig.server?.origin ?? resolveOriginFromServerOptions(userConfig.server, port, "localhost");
293
338
  return mergeConfig(mergeConfig(sharedConfig, {
294
- plugins: [kirbyupHmrPlugin(options), watch && fullReloadPlugin(watch)].filter(Boolean),
339
+ plugins: [kirbyupHmrPlugin(options), watch && kirbyupFullReloadPlugin(watch)].filter(Boolean),
295
340
  build: { rollupOptions: { input: resolve(options.cwd, options.entry) } },
296
341
  server: {
297
342
  port,
@@ -321,58 +366,55 @@ function getViteConfig(command, options) {
321
366
  }
322
367
  }), userConfig);
323
368
  }
324
- async function generate(options) {
325
- const config = getViteConfig("build", options);
369
+ async function generate(options, context) {
370
+ const config = getViteConfig("build", options, context);
326
371
  let result;
327
372
  try {
328
373
  result = await build(config);
329
374
  } catch (error) {
330
- if (config.mode === "production") throw error;
331
- else consola.error(error);
375
+ if (!options.watch) throw error;
376
+ consola.error(error);
332
377
  }
333
- if (result && !options.watch) {
334
- const { output } = toArray(result)[0];
335
- let maxLength = 0;
336
- for (const chunkFile in output) {
337
- const fileNameLength = output[chunkFile].fileName.length;
338
- if (fileNameLength > maxLength) maxLength = fileNameLength;
339
- }
340
- for (const { fileName, type, code } of output) {
341
- const content = code || await fsp.readFile(resolve(options.outDir, fileName), "utf8");
342
- await printFileInfo({
343
- root: options.cwd,
344
- outDir: options.outDir,
345
- filePath: fileName,
346
- content,
347
- type,
348
- maxLength
349
- });
350
- }
378
+ if (!result || options.watch) return;
379
+ const { output } = toArray(result)[0];
380
+ const maxLength = Math.max(0, ...output.map((item) => item.fileName.length));
381
+ for (const item of output) {
382
+ const content = item.type === "chunk" ? item.code : await fsp.readFile(resolve(options.outDir, item.fileName), "utf8");
383
+ await printFileInfo({
384
+ root: options.cwd,
385
+ outDir: options.outDir,
386
+ filePath: item.fileName,
387
+ content,
388
+ type: item.type,
389
+ maxLength
390
+ });
351
391
  }
352
- return result;
353
392
  }
354
393
  async function build$1(options) {
355
394
  assertEntryExists(options);
356
395
  const { cwd } = options;
357
396
  const { config, configFile } = await loadConfig$1(cwd);
358
- resolvedKirbyupConfig = config ?? {};
359
- resolvedPostCssConfig = await resolvePostCSSConfig(cwd);
397
+ const postCssConfig = await resolvePostCSSConfig(cwd);
398
+ const context = {
399
+ kirbyupConfig: config ?? {},
400
+ postCssConfig,
401
+ logger: createKirbyupLogger()
402
+ };
360
403
  consola.log(colors.green(`${name} v${version}`));
361
404
  consola.start(`Building ${colors.cyan(options.entry)}`);
362
- if (options.watch) consola.info("Running in watch mode");
363
- await generate(options);
405
+ await generate(options, context);
364
406
  consola.success("Build successful");
365
407
  if (!options.watch) return;
366
408
  const { watch } = await import("chokidar");
367
- const debouncedBuild = debounce(async () => {
368
- generate(options).catch(handleError);
409
+ const debouncedBuild = debounce(() => {
410
+ generate(options, context).catch(handleError);
369
411
  }, 100);
370
412
  const ignored = [
371
413
  "**/{.git,node_modules}/**",
372
414
  "index.{css,js}",
373
415
  DEV_OUTPUT_FILENAME
374
416
  ];
375
- const watchPaths = typeof options.watch === "boolean" ? dirname(options.entry) : Array.isArray(options.watch) ? options.watch.filter((path) => typeof path === "string") : options.watch;
417
+ const watchPaths = options.watch === true ? dirname(options.entry) : toArray(options.watch);
376
418
  consola.info(`Watching for changes in ${toArray(watchPaths).map((i) => colors.cyan(i)).join(", ")}`);
377
419
  const watcher = watch(watchPaths, {
378
420
  ignoreInitial: true,
@@ -390,13 +432,15 @@ async function build$1(options) {
390
432
  fs.rmSync(devOutputPath, { force: true });
391
433
  } catch {}
392
434
  });
393
- const onShutdown = () => void cleanup().finally(() => process.exit(0));
435
+ const onShutdown = () => {
436
+ cleanup().finally(() => process.exit(0));
437
+ };
394
438
  process.once("SIGINT", onShutdown);
395
439
  process.once("SIGTERM", onShutdown);
396
440
  if (configFile) watcher.add(configFile);
397
441
  watcher.on("all", async (type, file) => {
398
442
  if (configFile === resolve(cwd, file)) {
399
- resolvedKirbyupConfig = (await loadConfig$1(cwd)).config ?? {};
443
+ context.kirbyupConfig = (await loadConfig$1(cwd)).config ?? {};
400
444
  consola.info(`${colors.cyan(basename(file))} changed, setting new config`);
401
445
  } else consola.log(`${colors.green(type)} ${colors.white(colors.dim(file))}`);
402
446
  debouncedBuild();
@@ -406,15 +450,29 @@ async function serve(options) {
406
450
  assertEntryExists(options);
407
451
  const { cwd } = options;
408
452
  const { config } = await loadConfig$1(cwd);
409
- resolvedKirbyupConfig = config ?? {};
410
- resolvedPostCssConfig = await resolvePostCSSConfig(cwd);
453
+ const postCssConfig = await resolvePostCSSConfig(cwd);
454
+ const context = {
455
+ kirbyupConfig: config ?? {},
456
+ postCssConfig,
457
+ logger: createKirbyupLogger()
458
+ };
411
459
  consola.log(colors.green(`${name} v${version}`));
412
460
  consola.info("Starting development server…");
413
- const server = await createServer(getViteConfig("serve", options));
461
+ const server = await createServer(getViteConfig("serve", options, context));
414
462
  await server.listen();
415
463
  consola.success(`Server is listening on :${server.config.server.port}`);
416
464
  return server;
417
465
  }
466
+ function createKirbyupLogger() {
467
+ const baseLogger = createLogger(logLevel);
468
+ return {
469
+ ...baseLogger,
470
+ warn(msg, options) {
471
+ if (msg.startsWith(SUPPRESSED_WARNING_PREFIX)) return;
472
+ baseLogger.warn(msg, options);
473
+ }
474
+ };
475
+ }
418
476
  function assertEntryExists(options) {
419
477
  if (!fs.existsSync(resolve(options.cwd, options.entry))) throw new PrettyError(`Cannot find "${options.entry}"`);
420
478
  }
@@ -1,4 +1,5 @@
1
1
  import { AliasOptions, InlineConfig } from "vite";
2
+
2
3
  //#region src/node/types.d.ts
3
4
  interface BaseOptions {
4
5
  cwd: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kirbyup",
3
3
  "type": "module",
4
- "version": "4.0.0-alpha.6",
4
+ "version": "4.0.0-alpha.7",
5
5
  "packageManager": "pnpm@10.33.3",
6
6
  "description": "Zero-config bundler for Kirby Panel plugins",
7
7
  "author": {
@@ -79,14 +79,13 @@
79
79
  "chokidar": "^5.0.0",
80
80
  "consola": "^3.4.2",
81
81
  "magic-string": "^0.30.21",
82
- "nypm": "^0.6.6",
83
82
  "pathe": "^2.0.3",
84
83
  "perfect-debounce": "^2.1.0",
85
84
  "postcss": "^8.5.14",
86
85
  "postcss-load-config": "^6.0.1",
87
86
  "sass": "^1.99.0",
87
+ "strip-literal": "^3.1.0",
88
88
  "vite": "^8.0.10",
89
- "vite-plugin-full-reload": "^1.2.0",
90
89
  "vue": "^3.5.34"
91
90
  },
92
91
  "devDependencies": {
@@ -95,7 +94,6 @@
95
94
  "bumpp": "^11.0.1",
96
95
  "eslint": "^10.3.0",
97
96
  "eslint-flat-config-utils": "^3.2.0",
98
- "tinyglobby": "^0.2.16",
99
97
  "tsdown": "^0.21.10",
100
98
  "typescript": "^6.0.3",
101
99
  "unplugin-raw": "^0.7.0",