@adonisjs/vite 5.1.0 → 6.0.0-next.0

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.
@@ -0,0 +1,13 @@
1
+ import { type Plugin } from 'vite';
2
+ export interface ReloadOptions {
3
+ delay?: number;
4
+ }
5
+ /**
6
+ * Returns a Vite plugin that triggers a full browser reload whenever any file
7
+ * matching the supplied glob patterns changes. Patterns are resolved relative
8
+ * to the Vite project root.
9
+ *
10
+ * Replaces the previous `vite-plugin-restart` dependency. Only the reload
11
+ * (browser refresh) feature is implemented — server restart is not.
12
+ */
13
+ export declare function reload(patterns: string | string[], options?: ReloadOptions): Plugin;
@@ -0,0 +1,20 @@
1
+ import type { Plugin } from 'vite';
2
+ import type { PluginOptions } from './types.ts';
3
+ /**
4
+ * Returns a plugin that emits user-supplied files into the build output.
5
+ *
6
+ * `chunks` are passed to Vite's `emitFile({ type: 'chunk' })` after glob
7
+ * expansion. They are processed by the bundler and surface in the manifest
8
+ * with hashed filenames.
9
+ *
10
+ * `assets` are emitted as raw `type: 'asset'` files (no glob expansion —
11
+ * exact paths only) so the original source content is preserved verbatim.
12
+ * The `originalFileName` field tells Vite to use the source path as the
13
+ * manifest key, so templates can resolve them via
14
+ * `vite.assetPath('resources/images/logo.png')` without any post-build
15
+ * manifest rewriting.
16
+ *
17
+ * Returns an empty array (no-op) when neither chunks nor assets are
18
+ * configured.
19
+ */
20
+ export declare function resolveAssets(input: PluginOptions['assets']): Plugin[];
@@ -22,5 +22,30 @@ export interface PluginOptions {
22
22
  * @default 'public/assets'
23
23
  */
24
24
  buildDirectory?: string;
25
+ /**
26
+ * Server-side entrypoints bundled into the SSR build output. Each
27
+ * entry is emitted as a single bundle (no hash, no shared chunks)
28
+ * under `<buildDirectory>/server/<name>.js` and becomes loadable
29
+ * through `vite.loadServerModule()` at runtime.
30
+ *
31
+ * Paths are relative to the project root.
32
+ */
33
+ serverEntrypoints?: string[];
34
+ /**
35
+ * Additional files to include in the build that are not imported by the
36
+ * entrypoints.
37
+ *
38
+ * - When passed as a `string[]`, every entry is treated as a chunk: glob
39
+ * patterns are expanded and each matching file is emitted via Vite's
40
+ * `emitFile({ type: 'chunk' })`.
41
+ * - When passed as `{ chunks?, assets? }`, `chunks` behaves identically
42
+ * to the array form, while `assets` files are emitted as raw assets
43
+ * (no glob support, exact paths only) and the manifest is rewritten so
44
+ * the manifest key matches the source path.
45
+ */
46
+ assets?: string[] | {
47
+ chunks?: string[];
48
+ assets?: string[];
49
+ };
25
50
  }
26
- export type PluginFullOptions = Required<PluginOptions>;
51
+ export type PluginFullOptions = Required<Omit<PluginOptions, 'assets'>>;
@@ -1,11 +1,24 @@
1
- // src/hooks/build_hook.ts
2
1
  import { hooks } from "@adonisjs/core/app";
3
2
  import { createBuilder } from "vite";
3
+ //#region src/hooks/build_hook.ts
4
+ /**
5
+ * This is an Assembler hook that should be executed when the application is
6
+ * builded using the `node ace build` command.
7
+ *
8
+ * The hook is responsible for launching a Vite multi-build process.
9
+ */
4
10
  var build_hook_default = hooks.buildStarting(async (parent) => {
5
- parent.ui.logger.info("building assets with vite");
6
- const builder = await createBuilder({}, null);
7
- await builder.buildApp();
11
+ /**
12
+ * Vite's CLI sets NODE_ENV to 'production' automatically when running
13
+ * `vite build`, but the programmatic `createBuilder` API does not.
14
+ * Without this, framework plugins (React, Vue, MDX, …) emit dev-only
15
+ * code paths in the production bundle.
16
+ *
17
+ * See https://github.com/remix-run/remix/issues/4081
18
+ */
19
+ process.env.NODE_ENV = "production";
20
+ parent.ui.logger.info("building assets with vite");
21
+ await (await createBuilder({}, false)).buildApp();
8
22
  });
9
- export {
10
- build_hook_default as default
11
- };
23
+ //#endregion
24
+ export { build_hook_default as default };
@@ -1,69 +1,87 @@
1
- // src/plugins/edge.ts
2
1
  import { EdgeError } from "edge-error";
3
- var edgePluginVite = (vite) => {
4
- const edgeVite = (edge) => {
5
- edge.global("vite", vite);
6
- edge.global("asset", vite.assetPath.bind(vite));
7
- edge.registerTag({
8
- tagName: "viteReactRefresh",
9
- seekable: true,
10
- block: false,
11
- compile(parser, buffer, token) {
12
- let attributes = "";
13
- if (token.properties.jsArg.trim()) {
14
- const jsArg = `a,${token.properties.jsArg}`;
15
- const parsed = parser.utils.transformAst(
16
- parser.utils.generateAST(jsArg, token.loc, token.filename),
17
- token.filename,
18
- parser
19
- );
20
- attributes = parser.utils.stringify(parsed.expressions[1]);
21
- }
22
- buffer.writeExpression(
23
- `const __vite_hmr_script = state.vite.getReactHmrScript(${attributes})`,
24
- token.filename,
25
- token.loc.start.line
26
- );
27
- buffer.writeStatement("if(__vite_hmr_script) {", token.filename, token.loc.start.line);
28
- buffer.outputExpression(
29
- `__vite_hmr_script.toString()`,
30
- token.filename,
31
- token.loc.start.line,
32
- false
33
- );
34
- buffer.writeStatement("}", token.filename, token.loc.start.line);
35
- }
36
- });
37
- edge.registerTag({
38
- tagName: "vite",
39
- seekable: true,
40
- block: false,
41
- compile(parser, buffer, token) {
42
- if (!token.properties.jsArg.trim()) {
43
- throw new EdgeError("Missing entrypoint name", "E_RUNTIME_EXCEPTION", {
44
- filename: token.filename,
45
- line: token.loc.start.line,
46
- col: token.loc.start.col
47
- });
48
- }
49
- const parsed = parser.utils.transformAst(
50
- parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
51
- token.filename,
52
- parser
53
- );
54
- const entrypoints = parser.utils.stringify(parsed);
55
- const methodCall = parsed.type === "SequenceExpression" ? `generateEntryPointsTags${entrypoints}` : `generateEntryPointsTags(${entrypoints})`;
56
- buffer.outputExpression(
57
- `(await state.vite.${methodCall}).join('\\n')`,
58
- token.filename,
59
- token.loc.start.line,
60
- false
61
- );
62
- }
63
- });
64
- };
65
- return edgeVite;
66
- };
67
- export {
68
- edgePluginVite
2
+ //#region src/plugins/edge.ts
3
+ /**
4
+ * Creates an Edge.js plugin that integrates Vite functionality into templates
5
+ *
6
+ * Registers global helpers and custom tags (@vite, @viteReactRefresh) for use in Edge templates.
7
+ * Provides access to asset paths and HMR functionality within template rendering.
8
+ *
9
+ * @param vite - The Vite instance to integrate with Edge templates
10
+ *
11
+ * @example
12
+ * const plugin = edgePluginVite(viteInstance)
13
+ * edge.use(plugin)
14
+ *
15
+ * // In templates:
16
+ * // @vite('app.js')
17
+ * // @viteReactRefresh({ nonce: 'abc123' })
18
+ */
19
+ const edgePluginVite = (vite) => {
20
+ const edgeVite = (edge) => {
21
+ edge.global("vite", vite);
22
+ edge.global("asset", vite.assetPath.bind(vite));
23
+ edge.registerTag({
24
+ tagName: "viteReactRefresh",
25
+ seekable: true,
26
+ block: false,
27
+ compile(parser, buffer, token) {
28
+ let attributes = "";
29
+ if (token.properties.jsArg.trim()) {
30
+ /**
31
+ * Converting a single argument to a SequenceExpression so that we
32
+ * work around the following edge cases.
33
+ *
34
+ * - If someone passes an object literal to the tag, ie { nonce: 'foo' }
35
+ * it will be parsed as a LabeledStatement and not an object.
36
+ * - If we wrap the object literal inside parenthesis, ie ({nonce: 'foo'})
37
+ * then we will end up messing other expressions like a variable reference
38
+ * , or a member expression and so on.
39
+ * - So the best bet is to convert user supplied argument to a sequence expression
40
+ * and hence ignore it during stringification.
41
+ */
42
+ const jsArg = `a,${token.properties.jsArg}`;
43
+ const parsed = parser.utils.transformAst(parser.utils.generateAST(jsArg, token.loc, token.filename), token.filename, parser);
44
+ attributes = parser.utils.stringify(parsed.expressions[1]);
45
+ }
46
+ /**
47
+ * Get HMR script
48
+ */
49
+ buffer.writeExpression(`const __vite_hmr_script = state.vite.getReactHmrScript(${attributes})`, token.filename, token.loc.start.line);
50
+ /**
51
+ * Check if the script exists (only in hot mode)
52
+ */
53
+ buffer.writeStatement("if(__vite_hmr_script) {", token.filename, token.loc.start.line);
54
+ /**
55
+ * Write output
56
+ */
57
+ buffer.outputExpression(`__vite_hmr_script.toString()`, token.filename, token.loc.start.line, false);
58
+ /**
59
+ * Close if block
60
+ */
61
+ buffer.writeStatement("}", token.filename, token.loc.start.line);
62
+ }
63
+ });
64
+ edge.registerTag({
65
+ tagName: "vite",
66
+ seekable: true,
67
+ block: false,
68
+ compile(parser, buffer, token) {
69
+ /**
70
+ * Ensure an argument is defined
71
+ */
72
+ if (!token.properties.jsArg.trim()) throw new EdgeError("Missing entrypoint name", "E_RUNTIME_EXCEPTION", {
73
+ filename: token.filename,
74
+ line: token.loc.start.line,
75
+ col: token.loc.start.col
76
+ });
77
+ const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
78
+ const entrypoints = parser.utils.stringify(parsed);
79
+ const methodCall = parsed.type === "SequenceExpression" ? `generateEntryPointsTags${entrypoints}` : `generateEntryPointsTags(${entrypoints})`;
80
+ buffer.outputExpression(`(await state.vite.${methodCall}).join('\\n')`, token.filename, token.loc.start.line, false);
81
+ }
82
+ });
83
+ };
84
+ return edgeVite;
69
85
  };
86
+ //#endregion
87
+ export { edgePluginVite };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Resolves and imports server-side modules from the production SSR build.
3
+ *
4
+ * In production there is no Vite dev server — entrypoints declared as
5
+ * `serverEntrypoints` are pre-built into `<buildDirectory>/server` and
6
+ * recorded in `<buildDirectory>/server/.vite/manifest.json`. The
7
+ * resolver reads that manifest to map an entry source path to the
8
+ * emitted bundle file, then imports it through Node's native `import()`.
9
+ *
10
+ * Imports are cached per entry so repeated calls reuse the same module
11
+ * instance and side-effects only run once.
12
+ */
13
+ export declare class BundledModuleResolver {
14
+ #private;
15
+ constructor(buildDirectory: string);
16
+ import<T>(entry: string): Promise<T>;
17
+ }
@@ -0,0 +1,25 @@
1
+ import type { ViteDevServer } from 'vite';
2
+ import type { ModuleRunner } from 'vite/module-runner';
3
+ import type { LoadServerModuleOptions } from '../types.ts';
4
+ /**
5
+ * Hosts the Vite `ModuleRunner` used to evaluate server-side modules in
6
+ * development mode.
7
+ *
8
+ * Owns a single shared runner across all `loadServerModule` calls, and
9
+ * detects Vite dev server restarts (which replace `server.environments.ssr`
10
+ * with a fresh instance) so the stale runner is closed and recreated.
11
+ */
12
+ export declare class DevModuleRunner {
13
+ #private;
14
+ constructor(createRunner: () => Promise<ModuleRunner>);
15
+ /**
16
+ * Imports a module through the runner. Recreates the runner if the
17
+ * dev server's SSR environment was swapped underneath us.
18
+ */
19
+ import<T>(server: ViteDevServer, entry: string, opts: LoadServerModuleOptions): Promise<T>;
20
+ /**
21
+ * Closes the runner, if any. Safe to call when no runner has been
22
+ * created yet.
23
+ */
24
+ close(): Promise<void>;
25
+ }
@@ -0,0 +1,25 @@
1
+ import type { ViteDevServer } from 'vite';
2
+ import type { ModuleRunner } from 'vite/module-runner';
3
+ import type { LoadServerModuleOptions } from '../types.ts';
4
+ /**
5
+ * Public entry point for loading server-side modules processed by Vite.
6
+ *
7
+ * Picks between two collaborators based on whether the Vite dev server
8
+ * is running:
9
+ *
10
+ * - In development, delegates to {@link DevModuleRunner} which evaluates
11
+ * the entry through Vite's `ModuleRunner`, with HMR-driven cache
12
+ * invalidation.
13
+ * - In production, delegates to {@link BundledModuleResolver} which
14
+ * imports the pre-built bundle from disk.
15
+ *
16
+ * Entry strings are passed through verbatim to mirror how client
17
+ * `entrypoints` are handled — the caller is responsible for using the
18
+ * exact string declared in `serverEntrypoints`.
19
+ */
20
+ export declare class ServerModuleLoader {
21
+ #private;
22
+ constructor(getDevServer: () => ViteDevServer | undefined, buildDirectory: string, createRunner: () => Promise<ModuleRunner>);
23
+ load<T>(entry: string, opts?: LoadServerModuleOptions): Promise<T>;
24
+ close(): Promise<void>;
25
+ }
@@ -54,3 +54,35 @@ export interface ViteOptions {
54
54
  */
55
55
  scriptAttributes?: SetAttributes;
56
56
  }
57
+ /**
58
+ * Augmentable map for typing entries passed to `vite.loadServerModule`.
59
+ * Apps and packages merge into this interface to associate entrypoint
60
+ * paths with the shape of their default exports.
61
+ *
62
+ * @example
63
+ * declare module '@adonisjs/vite/types' {
64
+ * interface ServerModuleMap {
65
+ * 'inertia/app/ssr.ts': typeof import('../inertia/app/ssr.ts')
66
+ * }
67
+ * }
68
+ */
69
+ export interface ServerModuleMap {
70
+ }
71
+ /**
72
+ * Options accepted by `vite.loadServerModule`.
73
+ */
74
+ export interface LoadServerModuleOptions {
75
+ /**
76
+ * Clear the module runner cache before importing in dev mode.
77
+ *
78
+ * Defaults to `false` — Vite's HMR pushes invalidations into the
79
+ * runner, so cached modules are already kept fresh on file change.
80
+ * Set to `true` only when the entrypoint registers top-level state
81
+ * that must be reset on every load.
82
+ *
83
+ * Has no effect in production (bundled imports are always cached).
84
+ *
85
+ * @default false
86
+ */
87
+ fresh?: boolean;
88
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { type ModuleRunner } from 'vite/module-runner';
2
2
  import type { Manifest, InlineConfig, ViteDevServer, ServerModuleRunnerOptions } from 'vite';
3
- import type { AdonisViteElement, ViteOptions } from './types.ts';
3
+ import type { AdonisViteElement, LoadServerModuleOptions, ServerModuleMap, ViteOptions } from './types.ts';
4
4
  /**
5
5
  * Vite class exposes the APIs to generate tags and URLs for
6
6
  * assets processed using vite.
@@ -111,6 +111,27 @@ export declare class Vite {
111
111
  * const mod = await runner.import('./app.js')
112
112
  */
113
113
  createModuleRunner(options?: ServerModuleRunnerOptions): Promise<ModuleRunner>;
114
+ /**
115
+ * Loads a server-side module that has been processed by Vite.
116
+ *
117
+ * In development, the entry is evaluated through Vite's `ModuleRunner`,
118
+ * giving full TypeScript / JSX / plugin support and HMR-driven cache
119
+ * invalidation. In production, the entry is imported from the
120
+ * pre-built SSR bundle on disk.
121
+ *
122
+ * The entry path must be declared in `serverEntrypoints` for the
123
+ * production import to succeed — otherwise the bundle won't exist.
124
+ *
125
+ * @example
126
+ * const mod = await vite.loadServerModule('inertia/app/ssr.ts')
127
+ * const html = await mod.default(payload)
128
+ *
129
+ * @example
130
+ * // Force re-evaluation (clear runner cache before import)
131
+ * await vite.loadServerModule('emails/welcome.ts', { fresh: true })
132
+ */
133
+ loadServerModule<K extends keyof ServerModuleMap>(entry: K, opts?: LoadServerModuleOptions): Promise<ServerModuleMap[K]>;
134
+ loadServerModule<T = unknown>(entry: string, opts?: LoadServerModuleOptions): Promise<T>;
114
135
  /**
115
136
  * Gracefully stops the Vite development server
116
137
  *
@@ -1,6 +1,2 @@
1
- import {
2
- ViteMiddleware
3
- } from "../chunk-AF6PV64J.js";
4
- export {
5
- ViteMiddleware as default
6
- };
1
+ import { t as ViteMiddleware } from "../vite_middleware-CuOBHhnt.js";
2
+ export { ViteMiddleware as default };
@@ -0,0 +1,50 @@
1
+ //#region src/utils.ts
2
+ /**
3
+ * Returns a new array with unique items filtered by the specified key
4
+ *
5
+ * @param array - The array to filter for unique items
6
+ * @param key - The key to use for uniqueness comparison
7
+ *
8
+ * @example
9
+ * const users = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 1, name: 'John' }]
10
+ * const unique = uniqBy(users, 'id')
11
+ * // Returns: [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]
12
+ */
13
+ function uniqBy(array, key) {
14
+ const seen = /* @__PURE__ */ new Set();
15
+ return array.filter((item) => {
16
+ const k = item[key];
17
+ return seen.has(k) ? false : seen.add(k);
18
+ });
19
+ }
20
+ /**
21
+ * Converts an object of HTML attributes to a valid HTML attribute string
22
+ *
23
+ * @param attributes - Object containing HTML attributes where values can be strings or booleans
24
+ *
25
+ * @example
26
+ * const attrs = makeAttributes({ class: 'btn', disabled: true, hidden: false })
27
+ * // Returns: 'class="btn" disabled'
28
+ */
29
+ function makeAttributes(attributes) {
30
+ return Object.keys(attributes).map((key) => {
31
+ const value = attributes[key];
32
+ if (value === true) return key;
33
+ if (!value) return null;
34
+ return `${key}="${value}"`;
35
+ }).filter((attr) => attr !== null).join(" ");
36
+ }
37
+ /**
38
+ * Adds a trailing slash to a URL if it doesn't already have one
39
+ *
40
+ * @param url - The URL string to process
41
+ *
42
+ * @example
43
+ * addTrailingSlash('/api') // Returns: '/api/'
44
+ * addTrailingSlash('/api/') // Returns: '/api/'
45
+ */
46
+ const addTrailingSlash = (url) => {
47
+ return url.endsWith("/") ? url : `${url}/`;
48
+ };
49
+ //#endregion
50
+ export { makeAttributes as n, uniqBy as r, addTrailingSlash as t };