@rsaf/bundler 0.0.4 → 0.0.5
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/dist/bundler/Bundler.d.ts +39 -27
- package/dist/bundler/Bundler.js +42 -35
- package/dist/bundler/config.d.ts +27 -1
- package/dist/bundler/config.js +33 -11
- package/dist/bundler/create-plugin.d.ts +85 -0
- package/dist/bundler/create-plugin.js +58 -0
- package/dist/cache/cache-store.d.ts +46 -41
- package/dist/cache/cache-store.js +47 -44
- package/dist/config/esbuild.d.ts +24 -0
- package/dist/config/esbuild.js +32 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types/config.d.ts +67 -0
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.js +1 -0
- package/package.json +1 -1
- package/dist/config/path.d.ts +0 -38
- package/dist/config/path.js +0 -67
|
@@ -2,59 +2,71 @@ import esbuild from 'esbuild';
|
|
|
2
2
|
import type { BuildResult } from 'esbuild';
|
|
3
3
|
import type { ESBuildConfig } from '../types/config.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
5
|
+
* A thin wrapper around the `esbuild` API designed to manage build lifecycles.
|
|
6
|
+
* The `Bundler` class abstracts the complexity of esbuild's `context()` and `watch()`
|
|
7
|
+
* APIs, providing a unified interface for initial builds, incremental rebuilds,
|
|
8
|
+
* and persistent file watching.
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const bundler = new Bundler(config);
|
|
12
|
+
* await bundler.build();
|
|
13
|
+
* ```
|
|
14
14
|
*/
|
|
15
15
|
export declare class Bundler {
|
|
16
16
|
private options;
|
|
17
17
|
private context?;
|
|
18
18
|
private lastResult?;
|
|
19
19
|
private isWatching;
|
|
20
|
+
/**
|
|
21
|
+
* Creates an instance of the Bundler.
|
|
22
|
+
* @param options - Configuration options for the esbuild engine.
|
|
23
|
+
*/
|
|
20
24
|
constructor(options: ESBuildConfig);
|
|
21
25
|
/**
|
|
22
|
-
*
|
|
26
|
+
* Injects an esbuild plugin into the current configuration.
|
|
27
|
+
* @param plugin - The esbuild plugin to add.
|
|
28
|
+
* @returns The current {@link Bundler} instance for method chaining.
|
|
23
29
|
*/
|
|
24
30
|
addPlugin(plugin: esbuild.Plugin): this;
|
|
25
31
|
/**
|
|
26
|
-
*
|
|
32
|
+
* Executes a build process.
|
|
33
|
+
* If the bundler is currently in watch mode, it performs an incremental
|
|
34
|
+
* rebuild using the existing context. Otherwise, it performs a fresh build.
|
|
35
|
+
* @returns A promise resolving to the {@link BuildResult}.
|
|
36
|
+
* @throws {@link AppError} with code `BUILD_FAILED` if the build process encounters errors.
|
|
27
37
|
*/
|
|
28
38
|
build(): Promise<BuildResult>;
|
|
29
39
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* but file watching is controlled externally.
|
|
40
|
+
* Initializes and starts esbuild's internal watch mode.
|
|
41
|
+
* This method creates a persistent build context. While esbuild's native
|
|
42
|
+
* watcher is activated, this setup is often used in conjunction with
|
|
43
|
+
* external watchers (like Chokidar) by calling {@link rebuild}.
|
|
44
|
+
* @remarks
|
|
45
|
+
* If a context already exists, it will be disposed of before creating a new one.
|
|
46
|
+
* @throws {@link AppError} if the context cannot be initialized.
|
|
38
47
|
*/
|
|
39
48
|
watch(): Promise<void>;
|
|
40
49
|
/**
|
|
41
|
-
* Manually
|
|
42
|
-
*
|
|
43
|
-
*
|
|
50
|
+
* Manually triggers an incremental rebuild.
|
|
51
|
+
* This is typically invoked by an external file watcher when changes are detected.
|
|
52
|
+
* @returns A promise resolving to the {@link BuildResult} of the increment.
|
|
53
|
+
* @throws {@link AppError} if called before {@link watch} has initialized a context.
|
|
44
54
|
*/
|
|
45
55
|
rebuild(): Promise<BuildResult>;
|
|
46
56
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
57
|
+
* Gracefully shuts down the bundler and releases system resources.
|
|
58
|
+
* This disposes of the esbuild context, stops watchers, and clears internal cache.
|
|
59
|
+
* @throws {@link AppError} if the disposal process fails.
|
|
50
60
|
*/
|
|
51
61
|
dispose(): Promise<void>;
|
|
52
62
|
/**
|
|
53
|
-
*
|
|
63
|
+
* Retrieves the result of the most recent successful build or rebuild.
|
|
64
|
+
* @returns The {@link BuildResult} or `undefined` if no build has occurred yet.
|
|
54
65
|
*/
|
|
55
66
|
getLastResult(): BuildResult | undefined;
|
|
56
67
|
/**
|
|
57
|
-
*
|
|
68
|
+
* Indicates whether the bundler is currently in an active watch state.
|
|
69
|
+
* @returns `true` if watching, otherwise `false`.
|
|
58
70
|
*/
|
|
59
71
|
isInWatchMode(): boolean;
|
|
60
72
|
}
|
package/dist/bundler/Bundler.js
CHANGED
|
@@ -2,26 +2,32 @@
|
|
|
2
2
|
import { AppError } from '@rsaf/core';
|
|
3
3
|
import esbuild from 'esbuild';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
5
|
+
* A thin wrapper around the `esbuild` API designed to manage build lifecycles.
|
|
6
|
+
* The `Bundler` class abstracts the complexity of esbuild's `context()` and `watch()`
|
|
7
|
+
* APIs, providing a unified interface for initial builds, incremental rebuilds,
|
|
8
|
+
* and persistent file watching.
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const bundler = new Bundler(config);
|
|
12
|
+
* await bundler.build();
|
|
13
|
+
* ```
|
|
14
14
|
*/
|
|
15
15
|
export class Bundler {
|
|
16
16
|
options;
|
|
17
17
|
context;
|
|
18
18
|
lastResult;
|
|
19
19
|
isWatching = false;
|
|
20
|
+
/**
|
|
21
|
+
* Creates an instance of the Bundler.
|
|
22
|
+
* @param options - Configuration options for the esbuild engine.
|
|
23
|
+
*/
|
|
20
24
|
constructor(options) {
|
|
21
25
|
this.options = options;
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
|
-
*
|
|
28
|
+
* Injects an esbuild plugin into the current configuration.
|
|
29
|
+
* @param plugin - The esbuild plugin to add.
|
|
30
|
+
* @returns The current {@link Bundler} instance for method chaining.
|
|
25
31
|
*/
|
|
26
32
|
addPlugin(plugin) {
|
|
27
33
|
if (!this.options.plugins) {
|
|
@@ -31,16 +37,18 @@ export class Bundler {
|
|
|
31
37
|
return this;
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
34
|
-
*
|
|
40
|
+
* Executes a build process.
|
|
41
|
+
* If the bundler is currently in watch mode, it performs an incremental
|
|
42
|
+
* rebuild using the existing context. Otherwise, it performs a fresh build.
|
|
43
|
+
* @returns A promise resolving to the {@link BuildResult}.
|
|
44
|
+
* @throws {@link AppError} with code `BUILD_FAILED` if the build process encounters errors.
|
|
35
45
|
*/
|
|
36
46
|
async build() {
|
|
37
47
|
try {
|
|
38
48
|
if (this.isWatching && this.context) {
|
|
39
|
-
// In watch mode, we can use rebuild
|
|
40
49
|
this.lastResult = await this.context.rebuild();
|
|
41
50
|
}
|
|
42
51
|
else {
|
|
43
|
-
// Initial build
|
|
44
52
|
this.lastResult = await esbuild.build(this.options);
|
|
45
53
|
}
|
|
46
54
|
return this.lastResult;
|
|
@@ -55,27 +63,23 @@ export class Bundler {
|
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* but file watching is controlled externally.
|
|
66
|
+
* Initializes and starts esbuild's internal watch mode.
|
|
67
|
+
* This method creates a persistent build context. While esbuild's native
|
|
68
|
+
* watcher is activated, this setup is often used in conjunction with
|
|
69
|
+
* external watchers (like Chokidar) by calling {@link rebuild}.
|
|
70
|
+
* @remarks
|
|
71
|
+
* If a context already exists, it will be disposed of before creating a new one.
|
|
72
|
+
* @throws {@link AppError} if the context cannot be initialized.
|
|
66
73
|
*/
|
|
67
74
|
async watch() {
|
|
68
75
|
if (this.isWatching)
|
|
69
76
|
return;
|
|
70
77
|
this.isWatching = true;
|
|
71
|
-
// If an old context exists, dispose it
|
|
72
78
|
if (this.context) {
|
|
73
79
|
await this.dispose();
|
|
74
80
|
}
|
|
75
81
|
try {
|
|
76
|
-
// Create a new esbuild build context
|
|
77
82
|
this.context = await esbuild.context(this.options);
|
|
78
|
-
// Start esbuild's watch mode with no onRebuild handlers
|
|
79
83
|
await this.context.watch();
|
|
80
84
|
}
|
|
81
85
|
catch (error // eslint-disable-line
|
|
@@ -88,13 +92,14 @@ export class Bundler {
|
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
/**
|
|
91
|
-
* Manually
|
|
92
|
-
*
|
|
93
|
-
*
|
|
95
|
+
* Manually triggers an incremental rebuild.
|
|
96
|
+
* This is typically invoked by an external file watcher when changes are detected.
|
|
97
|
+
* @returns A promise resolving to the {@link BuildResult} of the increment.
|
|
98
|
+
* @throws {@link AppError} if called before {@link watch} has initialized a context.
|
|
94
99
|
*/
|
|
95
100
|
async rebuild() {
|
|
96
101
|
if (!this.context) {
|
|
97
|
-
throw new AppError('You must call "watch()" before
|
|
102
|
+
throw new AppError('You must call "watch()" before using "rebuild()"', {
|
|
98
103
|
code: 'BUILD_FAILED',
|
|
99
104
|
category: 'build',
|
|
100
105
|
});
|
|
@@ -103,7 +108,7 @@ export class Bundler {
|
|
|
103
108
|
this.lastResult = await this.context.rebuild();
|
|
104
109
|
return this.lastResult;
|
|
105
110
|
}
|
|
106
|
-
catch (error //eslint-disable-line
|
|
111
|
+
catch (error // eslint-disable-line
|
|
107
112
|
) {
|
|
108
113
|
throw new AppError('Looks like there is some errors while rebuilding', {
|
|
109
114
|
code: 'BUILD_FAILED',
|
|
@@ -113,9 +118,9 @@ export class Bundler {
|
|
|
113
118
|
}
|
|
114
119
|
}
|
|
115
120
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
121
|
+
* Gracefully shuts down the bundler and releases system resources.
|
|
122
|
+
* This disposes of the esbuild context, stops watchers, and clears internal cache.
|
|
123
|
+
* @throws {@link AppError} if the disposal process fails.
|
|
119
124
|
*/
|
|
120
125
|
async dispose() {
|
|
121
126
|
if (!this.context)
|
|
@@ -123,7 +128,7 @@ export class Bundler {
|
|
|
123
128
|
try {
|
|
124
129
|
await this.context.dispose();
|
|
125
130
|
}
|
|
126
|
-
catch (error //eslint-disable-line
|
|
131
|
+
catch (error // eslint-disable-line
|
|
127
132
|
) {
|
|
128
133
|
throw new AppError('Failed to stop. Try again', {
|
|
129
134
|
code: 'BUILD_FAILED',
|
|
@@ -136,13 +141,15 @@ export class Bundler {
|
|
|
136
141
|
this.isWatching = false;
|
|
137
142
|
}
|
|
138
143
|
/**
|
|
139
|
-
*
|
|
144
|
+
* Retrieves the result of the most recent successful build or rebuild.
|
|
145
|
+
* @returns The {@link BuildResult} or `undefined` if no build has occurred yet.
|
|
140
146
|
*/
|
|
141
147
|
getLastResult() {
|
|
142
148
|
return this.lastResult;
|
|
143
149
|
}
|
|
144
150
|
/**
|
|
145
|
-
*
|
|
151
|
+
* Indicates whether the bundler is currently in an active watch state.
|
|
152
|
+
* @returns `true` if watching, otherwise `false`.
|
|
146
153
|
*/
|
|
147
154
|
isInWatchMode() {
|
|
148
155
|
return this.isWatching;
|
package/dist/bundler/config.d.ts
CHANGED
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import type { ESBuildClientDevConfig, ESBuildClientProdConfig, ESBuildServerDevConfig, ESBuildServerProdConfig } from '../types/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates an esbuild configuration specifically for the Client (browser) environment.
|
|
4
|
+
* * @remarks
|
|
5
|
+
* The client configuration differs from the server in several key ways:
|
|
6
|
+
* - **Platform**: Targeted for the `browser`.
|
|
7
|
+
* - **Asset Loaders**: Includes loaders for images/styles (`ASSET_LOADERS`).
|
|
8
|
+
* - **Bundling**: `bundle: true` is used to resolve all dependencies for the browser.
|
|
9
|
+
* - **Write Mode**: In `dev`, `write` is set to `false` to support in-memory serving.
|
|
10
|
+
* * @param env - The build environment: `'dev'` for development or `'prod'` for production.
|
|
11
|
+
* @param options - Configuration details.
|
|
12
|
+
* @param options.absWorkingDir - The absolute path to the project root.
|
|
13
|
+
* @param options.entryPoints - File paths or a mapping for the entry points to be bundled.
|
|
14
|
+
* * @returns A configuration object typed for either {@link ESBuildClientDevConfig} or {@link ESBuildClientProdConfig}.
|
|
15
|
+
*/
|
|
2
16
|
export declare function createClientConfig(env: 'dev' | 'prod', options: {
|
|
3
17
|
absWorkingDir: string;
|
|
4
18
|
entryPoints: string[] | Record<string, string>;
|
|
5
19
|
}): ESBuildClientDevConfig | ESBuildClientProdConfig;
|
|
6
20
|
/**
|
|
7
|
-
*
|
|
21
|
+
* Generates an esbuild configuration specifically for the Server (Node.js) environment.
|
|
22
|
+
* * @remarks
|
|
23
|
+
* The server configuration is optimized for SSR and runtime execution:
|
|
24
|
+
* - **Platform**: Targeted for `node`.
|
|
25
|
+
* - **Asset Loaders**: Uses `NO_ASSET_LOADERS` as assets are typically handled by the client build.
|
|
26
|
+
* - **Externalization**: Automatically marks `react` and `react-dom` as external to avoid
|
|
27
|
+
* duplicate instances during server-side rendering.
|
|
28
|
+
* - **Bundling**: `bundle: false` and `packages: 'external'` are used to leverage Node's native module resolution.
|
|
29
|
+
* * @param env - The build environment: `'dev'` for development or `'prod'` for production.
|
|
30
|
+
* @param options - Configuration details.
|
|
31
|
+
* @param options.absWorkingDir - The absolute path to the project root.
|
|
32
|
+
* @param options.entryPoints - File paths or a mapping for the entry points (e.g., the SSR entry).
|
|
33
|
+
* * @returns A configuration object typed for either {@link ESBuildServerDevConfig} or {@link ESBuildServerProdConfig}.
|
|
8
34
|
*/
|
|
9
35
|
export declare function createServerConfig(env: 'dev' | 'prod', options: {
|
|
10
36
|
absWorkingDir: string;
|
package/dist/bundler/config.js
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
1
2
|
import { ASSET_LOADERS, BASE_LOADERS, ESBUILD_BASE_CONFIG, NO_ASSET_LOADERS, } from '../config/esbuild.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
3
|
+
import { CACHE_DIR } from '../utils/constants.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generates an esbuild configuration specifically for the Client (browser) environment.
|
|
6
|
+
* * @remarks
|
|
7
|
+
* The client configuration differs from the server in several key ways:
|
|
8
|
+
* - **Platform**: Targeted for the `browser`.
|
|
9
|
+
* - **Asset Loaders**: Includes loaders for images/styles (`ASSET_LOADERS`).
|
|
10
|
+
* - **Bundling**: `bundle: true` is used to resolve all dependencies for the browser.
|
|
11
|
+
* - **Write Mode**: In `dev`, `write` is set to `false` to support in-memory serving.
|
|
12
|
+
* * @param env - The build environment: `'dev'` for development or `'prod'` for production.
|
|
13
|
+
* @param options - Configuration details.
|
|
14
|
+
* @param options.absWorkingDir - The absolute path to the project root.
|
|
15
|
+
* @param options.entryPoints - File paths or a mapping for the entry points to be bundled.
|
|
16
|
+
* * @returns A configuration object typed for either {@link ESBuildClientDevConfig} or {@link ESBuildClientProdConfig}.
|
|
17
|
+
*/
|
|
4
18
|
export function createClientConfig(env, options) {
|
|
5
19
|
const isDev = env === 'dev';
|
|
6
|
-
|
|
20
|
+
const cwd = process.cwd();
|
|
7
21
|
const baseConfig = {
|
|
8
22
|
...ESBUILD_BASE_CONFIG,
|
|
9
23
|
absWorkingDir: options.absWorkingDir,
|
|
10
24
|
entryPoints: options.entryPoints,
|
|
11
|
-
outdir:
|
|
25
|
+
outdir: join(cwd, CACHE_DIR, 'client'),
|
|
12
26
|
plugins: [],
|
|
13
27
|
};
|
|
14
28
|
if (isDev) {
|
|
15
|
-
// Dev configuration
|
|
16
29
|
return {
|
|
17
30
|
...baseConfig,
|
|
18
31
|
platform: 'browser',
|
|
@@ -33,7 +46,6 @@ export function createClientConfig(env, options) {
|
|
|
33
46
|
};
|
|
34
47
|
}
|
|
35
48
|
else {
|
|
36
|
-
// Prod configuration
|
|
37
49
|
return {
|
|
38
50
|
...baseConfig,
|
|
39
51
|
platform: 'browser',
|
|
@@ -55,20 +67,31 @@ export function createClientConfig(env, options) {
|
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
69
|
/**
|
|
58
|
-
*
|
|
70
|
+
* Generates an esbuild configuration specifically for the Server (Node.js) environment.
|
|
71
|
+
* * @remarks
|
|
72
|
+
* The server configuration is optimized for SSR and runtime execution:
|
|
73
|
+
* - **Platform**: Targeted for `node`.
|
|
74
|
+
* - **Asset Loaders**: Uses `NO_ASSET_LOADERS` as assets are typically handled by the client build.
|
|
75
|
+
* - **Externalization**: Automatically marks `react` and `react-dom` as external to avoid
|
|
76
|
+
* duplicate instances during server-side rendering.
|
|
77
|
+
* - **Bundling**: `bundle: false` and `packages: 'external'` are used to leverage Node's native module resolution.
|
|
78
|
+
* * @param env - The build environment: `'dev'` for development or `'prod'` for production.
|
|
79
|
+
* @param options - Configuration details.
|
|
80
|
+
* @param options.absWorkingDir - The absolute path to the project root.
|
|
81
|
+
* @param options.entryPoints - File paths or a mapping for the entry points (e.g., the SSR entry).
|
|
82
|
+
* * @returns A configuration object typed for either {@link ESBuildServerDevConfig} or {@link ESBuildServerProdConfig}.
|
|
59
83
|
*/
|
|
60
84
|
export function createServerConfig(env, options) {
|
|
61
85
|
const isDev = env === 'dev';
|
|
62
|
-
|
|
86
|
+
const cwd = process.cwd();
|
|
63
87
|
const baseConfig = {
|
|
64
88
|
...ESBUILD_BASE_CONFIG,
|
|
65
89
|
absWorkingDir: options.absWorkingDir,
|
|
66
90
|
entryPoints: options.entryPoints,
|
|
67
|
-
outdir:
|
|
91
|
+
outdir: join(cwd, CACHE_DIR, 'server'),
|
|
68
92
|
plugins: [],
|
|
69
93
|
};
|
|
70
94
|
if (isDev) {
|
|
71
|
-
// Dev configuration
|
|
72
95
|
return {
|
|
73
96
|
...baseConfig,
|
|
74
97
|
platform: 'node',
|
|
@@ -90,7 +113,6 @@ export function createServerConfig(env, options) {
|
|
|
90
113
|
};
|
|
91
114
|
}
|
|
92
115
|
else {
|
|
93
|
-
// Prod configuration
|
|
94
116
|
return {
|
|
95
117
|
...baseConfig,
|
|
96
118
|
platform: 'node',
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { BuildResult, OnLoadArgs, OnLoadOptions, OnResolveArgs, OnResolveOptions, Plugin, OnLoadResult, OnResolveResult, PluginBuild } from 'esbuild';
|
|
2
|
+
/**
|
|
3
|
+
* Defines the execution logic for various stages of the esbuild bundling process.
|
|
4
|
+
* * This interface provides a structured, declarative way to tap into the
|
|
5
|
+
* {@link https://esbuild.github.io/plugins/#build-callbacks | esbuild plugin lifecycle}.
|
|
6
|
+
*/
|
|
7
|
+
interface PluginLifecycleHooks {
|
|
8
|
+
/**
|
|
9
|
+
* Invoked at the very beginning of every build or rebuild.
|
|
10
|
+
* * @remarks
|
|
11
|
+
* Use this for setup logic, initializing build-specific state, or clear/prepare output directories.
|
|
12
|
+
* If this function returns a `Promise`, esbuild will wait for it to resolve before starting the build.
|
|
13
|
+
*/
|
|
14
|
+
onStart?: (this: PluginBuild) => void | Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Invoked at the end of every build or rebuild.
|
|
17
|
+
* * @param result - The outcome of the build, including errors, warnings, and the metafile (if enabled).
|
|
18
|
+
* @remarks
|
|
19
|
+
* Ideal for post-processing tasks, such as generating manifest files,
|
|
20
|
+
* triggering notifications, or cleaning up temporary files.
|
|
21
|
+
*/
|
|
22
|
+
onEnd?: (this: PluginBuild, result: BuildResult) => void | Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Invoked when the plugin is disposed of, usually when the {@link Bundler.dispose} is called.
|
|
25
|
+
* * @remarks
|
|
26
|
+
* Use this to close file watchers, database connections, or long-lived child processes
|
|
27
|
+
* created within the plugin.
|
|
28
|
+
*/
|
|
29
|
+
onDispose?: (this: PluginBuild) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Intercepts the loading of files that match specific criteria.
|
|
32
|
+
*/
|
|
33
|
+
onLoad?: {
|
|
34
|
+
/** Configuration object defining the `filter` regex and `namespace`. */
|
|
35
|
+
options: OnLoadOptions;
|
|
36
|
+
/** * Executed when a file matches the filter.
|
|
37
|
+
* @returns The content and loader type for the file.
|
|
38
|
+
*/
|
|
39
|
+
callback: (args: OnLoadArgs) => OnLoadResult | Promise<OnLoadResult>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Intercepts the resolution of import paths.
|
|
43
|
+
*/
|
|
44
|
+
onResolve?: {
|
|
45
|
+
/** Configuration object defining the `filter` regex and `namespace`. */
|
|
46
|
+
options: OnResolveOptions;
|
|
47
|
+
/** * Executed when an import matches the filter.
|
|
48
|
+
* @returns The resolved path or instructions to externalize the module.
|
|
49
|
+
*/
|
|
50
|
+
callback: (args: OnResolveArgs) => OnResolveResult | Promise<OnResolveResult>;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A factory function that creates a declarative esbuild plugin.
|
|
55
|
+
* * This utility abstracts the imperative nature of the `setup(build)` function,
|
|
56
|
+
* making plugin code more readable and easier to maintain.
|
|
57
|
+
* * @example
|
|
58
|
+
* **Basic Usage (Logging)**
|
|
59
|
+
* ```ts
|
|
60
|
+
* const loggerPlugin = createDeclarativePlugin('rsaf-logger', {
|
|
61
|
+
* onStart: () => console.log('Building...'),
|
|
62
|
+
* onEnd: (res) => console.log(`Done with ${res.errors.length} errors.`),
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
* * @example
|
|
66
|
+
* **Advanced Usage (Virtual Modules)**
|
|
67
|
+
* ```ts
|
|
68
|
+
* const virtualModule = createDeclarativePlugin('virtual-config', {
|
|
69
|
+
* onResolve: {
|
|
70
|
+
* options: { filter: /^virtual:config$/ },
|
|
71
|
+
* callback: () => ({ path: 'config', namespace: 'v-space' })
|
|
72
|
+
* },
|
|
73
|
+
* onLoad: {
|
|
74
|
+
* options: { filter: /*.ts., namespace: 'v-space' },
|
|
75
|
+
* callback: () => ({ contents: 'export const val = 42;', loader: 'js' })
|
|
76
|
+
* }
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
* * @param pluginName - A unique name for the plugin (used for error reporting and debugging).
|
|
80
|
+
* @param lifecycleHooks - An object containing the hooks to be registered.
|
|
81
|
+
* @returns A standard esbuild {@link Plugin} object.
|
|
82
|
+
* * @throws {TypeError} If `pluginName` is empty or not a string.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createDeclarativePlugin(pluginName: string, lifecycleHooks: PluginLifecycleHooks): Plugin;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A factory function that creates a declarative esbuild plugin.
|
|
3
|
+
* * This utility abstracts the imperative nature of the `setup(build)` function,
|
|
4
|
+
* making plugin code more readable and easier to maintain.
|
|
5
|
+
* * @example
|
|
6
|
+
* **Basic Usage (Logging)**
|
|
7
|
+
* ```ts
|
|
8
|
+
* const loggerPlugin = createDeclarativePlugin('rsaf-logger', {
|
|
9
|
+
* onStart: () => console.log('Building...'),
|
|
10
|
+
* onEnd: (res) => console.log(`Done with ${res.errors.length} errors.`),
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
* * @example
|
|
14
|
+
* **Advanced Usage (Virtual Modules)**
|
|
15
|
+
* ```ts
|
|
16
|
+
* const virtualModule = createDeclarativePlugin('virtual-config', {
|
|
17
|
+
* onResolve: {
|
|
18
|
+
* options: { filter: /^virtual:config$/ },
|
|
19
|
+
* callback: () => ({ path: 'config', namespace: 'v-space' })
|
|
20
|
+
* },
|
|
21
|
+
* onLoad: {
|
|
22
|
+
* options: { filter: /*.ts., namespace: 'v-space' },
|
|
23
|
+
* callback: () => ({ contents: 'export const val = 42;', loader: 'js' })
|
|
24
|
+
* }
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
* * @param pluginName - A unique name for the plugin (used for error reporting and debugging).
|
|
28
|
+
* @param lifecycleHooks - An object containing the hooks to be registered.
|
|
29
|
+
* @returns A standard esbuild {@link Plugin} object.
|
|
30
|
+
* * @throws {TypeError} If `pluginName` is empty or not a string.
|
|
31
|
+
*/
|
|
32
|
+
export function createDeclarativePlugin(pluginName, lifecycleHooks) {
|
|
33
|
+
if (typeof pluginName !== 'string' || pluginName.trim().length === 0) {
|
|
34
|
+
throw new TypeError('[createDeclarativePlugin]: Plugin name must be a non-empty string');
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
name: pluginName,
|
|
38
|
+
setup(build) {
|
|
39
|
+
if (lifecycleHooks.onStart) {
|
|
40
|
+
build.onStart(lifecycleHooks.onStart.bind(build));
|
|
41
|
+
}
|
|
42
|
+
if (lifecycleHooks.onEnd) {
|
|
43
|
+
build.onEnd(lifecycleHooks.onEnd.bind(build));
|
|
44
|
+
}
|
|
45
|
+
if (lifecycleHooks.onDispose) {
|
|
46
|
+
build.onDispose(lifecycleHooks.onDispose.bind(build));
|
|
47
|
+
}
|
|
48
|
+
if (lifecycleHooks.onLoad) {
|
|
49
|
+
const { options, callback } = lifecycleHooks.onLoad;
|
|
50
|
+
build.onLoad(options, callback);
|
|
51
|
+
}
|
|
52
|
+
if (lifecycleHooks.onResolve) {
|
|
53
|
+
const { options, callback } = lifecycleHooks.onResolve;
|
|
54
|
+
build.onResolve(options, callback);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -1,64 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A type-safe cache that
|
|
3
|
-
*
|
|
2
|
+
* A type-safe, generic cache store that enforces structural integrity based on a provided interface.
|
|
3
|
+
* * * This class provides a wrapper around the native `Map` API, ensuring that keys and values
|
|
4
|
+
* are strictly typed according to the shape of {@link T}.
|
|
5
|
+
* * @template T - An object-like type where keys represent the cache keys and values represent
|
|
6
|
+
* the corresponding data types.
|
|
7
|
+
* * @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* interface AppCache {
|
|
10
|
+
* port: number;
|
|
11
|
+
* isReady: boolean;
|
|
12
|
+
* config: { debug: boolean };
|
|
13
|
+
* }
|
|
14
|
+
* * const cache = new CacheStore<AppCache>();
|
|
15
|
+
* cache.set('port', 3000); // Type-safe
|
|
16
|
+
* // cache.set('port', '3000'); // Static type error
|
|
17
|
+
* ```
|
|
4
18
|
*/
|
|
5
19
|
export declare class CacheStore<T extends Record<string, any>> {
|
|
20
|
+
/**
|
|
21
|
+
* Internal storage mechanism.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
6
24
|
private store;
|
|
7
25
|
/**
|
|
8
|
-
* Retrieves a value from the cache
|
|
9
|
-
* @template K -
|
|
10
|
-
* @param key - The
|
|
11
|
-
* @returns The value
|
|
12
|
-
* @
|
|
13
|
-
*
|
|
14
|
-
*
|
|
26
|
+
* Retrieves a value from the cache associated with the specified key.
|
|
27
|
+
* * @template K - A specific property key within type {@link T}.
|
|
28
|
+
* @param key - The identifier to look up.
|
|
29
|
+
* @returns The stored value of type `T[K]`, or `undefined` if the key does not exist.
|
|
30
|
+
* * @remarks
|
|
31
|
+
* If you require a guarantee that the value exists (and want to avoid manual `undefined` checks),
|
|
32
|
+
* consider using {@link require} instead.
|
|
15
33
|
*/
|
|
16
34
|
get<K extends keyof T>(key: K): T[K] | undefined;
|
|
17
35
|
/**
|
|
18
|
-
* Retrieves a value from the cache, throwing
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
22
|
-
* @
|
|
23
|
-
* @
|
|
24
|
-
* @
|
|
25
|
-
* // Given T = { name: string, age: number }
|
|
26
|
-
* cache.require('name'); // Returns string, throws if 'name' not found
|
|
36
|
+
* Retrieves a value from the cache, throwing a runtime error if the key is missing.
|
|
37
|
+
* * * Use this method when a key is expected to be initialized during a bootstrap phase
|
|
38
|
+
* and its absence indicates a critical logic error.
|
|
39
|
+
* * @template K - A specific property key within type {@link T}.
|
|
40
|
+
* @param key - The identifier to look up.
|
|
41
|
+
* @returns The strictly-typed value associated with the key.
|
|
42
|
+
* * @throws {Error} If the key has not been set in the store.
|
|
27
43
|
*/
|
|
28
44
|
require<K extends keyof T>(key: K): T[K];
|
|
29
45
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @template K -
|
|
32
|
-
* @param key - The
|
|
33
|
-
* @param value - The
|
|
34
|
-
* @example
|
|
35
|
-
* // Given T = { name: string, age: number }
|
|
36
|
-
* cache.set('name', 'Alice'); // OK
|
|
37
|
-
* cache.set('age', 'thirty'); // Type error: string not assignable to number
|
|
46
|
+
* Inserts or updates a value in the cache.
|
|
47
|
+
* * @template K - A specific property key within type {@link T}.
|
|
48
|
+
* @param key - The identifier to associate the value with.
|
|
49
|
+
* @param value - The data to store, matching the type defined in {@link T} for this key.
|
|
38
50
|
*/
|
|
39
51
|
set<K extends keyof T>(key: K, value: T[K]): void;
|
|
40
52
|
/**
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
43
|
-
* @
|
|
44
|
-
* @returns True if the key exists in the cache, false otherwise.
|
|
45
|
-
* @example
|
|
46
|
-
* cache.has('name'); // Returns boolean
|
|
53
|
+
* Determines whether a specific key exists in the store.
|
|
54
|
+
* * @param key - The identifier to check.
|
|
55
|
+
* @returns `true` if the key is present; otherwise `false`.
|
|
47
56
|
*/
|
|
48
57
|
has<K extends keyof T>(key: K): boolean;
|
|
49
58
|
/**
|
|
50
|
-
* Removes
|
|
51
|
-
* @
|
|
52
|
-
* @
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* cache.delete('name'); // Returns boolean
|
|
59
|
+
* Removes the specified key and its associated value from the cache.
|
|
60
|
+
* * @param key - The identifier to remove.
|
|
61
|
+
* @returns `true` if an element in the CacheStore existed and has been removed,
|
|
62
|
+
* or `false` if the element does not exist.
|
|
56
63
|
*/
|
|
57
64
|
delete<K extends keyof T>(key: K): boolean;
|
|
58
65
|
/**
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* cache.clear(); // Empties the entire cache
|
|
66
|
+
* Clears all entries from the cache store, resetting it to an empty state.
|
|
62
67
|
*/
|
|
63
68
|
clear(): void;
|
|
64
69
|
}
|
|
@@ -1,81 +1,84 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A type-safe cache that
|
|
3
|
-
*
|
|
2
|
+
* A type-safe, generic cache store that enforces structural integrity based on a provided interface.
|
|
3
|
+
* * * This class provides a wrapper around the native `Map` API, ensuring that keys and values
|
|
4
|
+
* are strictly typed according to the shape of {@link T}.
|
|
5
|
+
* * @template T - An object-like type where keys represent the cache keys and values represent
|
|
6
|
+
* the corresponding data types.
|
|
7
|
+
* * @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* interface AppCache {
|
|
10
|
+
* port: number;
|
|
11
|
+
* isReady: boolean;
|
|
12
|
+
* config: { debug: boolean };
|
|
13
|
+
* }
|
|
14
|
+
* * const cache = new CacheStore<AppCache>();
|
|
15
|
+
* cache.set('port', 3000); // Type-safe
|
|
16
|
+
* // cache.set('port', '3000'); // Static type error
|
|
17
|
+
* ```
|
|
4
18
|
*/
|
|
5
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
20
|
export class CacheStore {
|
|
7
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Internal storage mechanism.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
8
25
|
store = new Map();
|
|
9
26
|
/**
|
|
10
|
-
* Retrieves a value from the cache
|
|
11
|
-
* @template K -
|
|
12
|
-
* @param key - The
|
|
13
|
-
* @returns The value
|
|
14
|
-
* @
|
|
15
|
-
*
|
|
16
|
-
*
|
|
27
|
+
* Retrieves a value from the cache associated with the specified key.
|
|
28
|
+
* * @template K - A specific property key within type {@link T}.
|
|
29
|
+
* @param key - The identifier to look up.
|
|
30
|
+
* @returns The stored value of type `T[K]`, or `undefined` if the key does not exist.
|
|
31
|
+
* * @remarks
|
|
32
|
+
* If you require a guarantee that the value exists (and want to avoid manual `undefined` checks),
|
|
33
|
+
* consider using {@link require} instead.
|
|
17
34
|
*/
|
|
18
35
|
get(key) {
|
|
19
|
-
// Type assertion is safe because we only store T[keyof T] values
|
|
20
36
|
return this.store.get(key);
|
|
21
37
|
}
|
|
22
38
|
/**
|
|
23
|
-
* Retrieves a value from the cache, throwing
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @
|
|
27
|
-
* @
|
|
28
|
-
* @
|
|
29
|
-
* @
|
|
30
|
-
* // Given T = { name: string, age: number }
|
|
31
|
-
* cache.require('name'); // Returns string, throws if 'name' not found
|
|
39
|
+
* Retrieves a value from the cache, throwing a runtime error if the key is missing.
|
|
40
|
+
* * * Use this method when a key is expected to be initialized during a bootstrap phase
|
|
41
|
+
* and its absence indicates a critical logic error.
|
|
42
|
+
* * @template K - A specific property key within type {@link T}.
|
|
43
|
+
* @param key - The identifier to look up.
|
|
44
|
+
* @returns The strictly-typed value associated with the key.
|
|
45
|
+
* * @throws {Error} If the key has not been set in the store.
|
|
32
46
|
*/
|
|
33
47
|
require(key) {
|
|
34
48
|
const value = this.store.get(key);
|
|
35
49
|
if (value === undefined) {
|
|
36
|
-
throw new Error(`
|
|
50
|
+
throw new Error(`[CacheStore]: Accessing uninitialized key '${String(key)}'. Ensure it is set before calling require().`);
|
|
37
51
|
}
|
|
38
52
|
return value;
|
|
39
53
|
}
|
|
40
54
|
/**
|
|
41
|
-
*
|
|
42
|
-
* @template K -
|
|
43
|
-
* @param key - The
|
|
44
|
-
* @param value - The
|
|
45
|
-
* @example
|
|
46
|
-
* // Given T = { name: string, age: number }
|
|
47
|
-
* cache.set('name', 'Alice'); // OK
|
|
48
|
-
* cache.set('age', 'thirty'); // Type error: string not assignable to number
|
|
55
|
+
* Inserts or updates a value in the cache.
|
|
56
|
+
* * @template K - A specific property key within type {@link T}.
|
|
57
|
+
* @param key - The identifier to associate the value with.
|
|
58
|
+
* @param value - The data to store, matching the type defined in {@link T} for this key.
|
|
49
59
|
*/
|
|
50
60
|
set(key, value) {
|
|
51
61
|
this.store.set(key, value);
|
|
52
62
|
}
|
|
53
63
|
/**
|
|
54
|
-
*
|
|
55
|
-
* @
|
|
56
|
-
* @
|
|
57
|
-
* @returns True if the key exists in the cache, false otherwise.
|
|
58
|
-
* @example
|
|
59
|
-
* cache.has('name'); // Returns boolean
|
|
64
|
+
* Determines whether a specific key exists in the store.
|
|
65
|
+
* * @param key - The identifier to check.
|
|
66
|
+
* @returns `true` if the key is present; otherwise `false`.
|
|
60
67
|
*/
|
|
61
68
|
has(key) {
|
|
62
69
|
return this.store.has(key);
|
|
63
70
|
}
|
|
64
71
|
/**
|
|
65
|
-
* Removes
|
|
66
|
-
* @
|
|
67
|
-
* @
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* cache.delete('name'); // Returns boolean
|
|
72
|
+
* Removes the specified key and its associated value from the cache.
|
|
73
|
+
* * @param key - The identifier to remove.
|
|
74
|
+
* @returns `true` if an element in the CacheStore existed and has been removed,
|
|
75
|
+
* or `false` if the element does not exist.
|
|
71
76
|
*/
|
|
72
77
|
delete(key) {
|
|
73
78
|
return this.store.delete(key);
|
|
74
79
|
}
|
|
75
80
|
/**
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* cache.clear(); // Empties the entire cache
|
|
81
|
+
* Clears all entries from the cache store, resetting it to an empty state.
|
|
79
82
|
*/
|
|
80
83
|
clear() {
|
|
81
84
|
this.store.clear();
|
package/dist/config/esbuild.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ESBuildConfig } from '../types/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Standard loaders for source code files.
|
|
4
|
+
* * Maps common ECMAScript and TypeScript extensions to their respective esbuild parsers.
|
|
5
|
+
*/
|
|
2
6
|
export declare const BASE_LOADERS: {
|
|
3
7
|
readonly '.js': "js";
|
|
4
8
|
readonly '.jsx': "jsx";
|
|
@@ -6,6 +10,13 @@ export declare const BASE_LOADERS: {
|
|
|
6
10
|
readonly '.tsx': "tsx";
|
|
7
11
|
readonly '.json': "json";
|
|
8
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Loaders for static assets and styling.
|
|
15
|
+
* * Used primarily in Client builds to ensure that CSS and media files are
|
|
16
|
+
* processed and emitted to the output directory.
|
|
17
|
+
* - **CSS**: Processed as standard stylesheets.
|
|
18
|
+
* - **Images/Fonts**: Handled using the `file` loader (emits a file and returns a URL).
|
|
19
|
+
*/
|
|
9
20
|
export declare const ASSET_LOADERS: {
|
|
10
21
|
readonly '.css': "css";
|
|
11
22
|
readonly '.png': "file";
|
|
@@ -17,6 +28,13 @@ export declare const ASSET_LOADERS: {
|
|
|
17
28
|
readonly '.woff': "file";
|
|
18
29
|
readonly '.woff2': "file";
|
|
19
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* "Null" loaders used to ignore static assets during specific build phases.
|
|
33
|
+
* * @remarks
|
|
34
|
+
* This is primarily used in **Server (SSR)** builds. On the server, we want to
|
|
35
|
+
* resolve imports for assets (so the code doesn't throw) but we don't want to
|
|
36
|
+
* actually process or emit those files, as the Client build handles them.
|
|
37
|
+
*/
|
|
20
38
|
export declare const NO_ASSET_LOADERS: {
|
|
21
39
|
readonly '.css': "empty";
|
|
22
40
|
readonly '.png': "empty";
|
|
@@ -28,4 +46,10 @@ export declare const NO_ASSET_LOADERS: {
|
|
|
28
46
|
readonly '.woff': "empty";
|
|
29
47
|
readonly '.woff2': "empty";
|
|
30
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* The default base configuration shared across all build targets.
|
|
51
|
+
* * This configuration prioritizes modern standards (ESM) and silent execution
|
|
52
|
+
* to allow the parent CLI or framework to manage logging.
|
|
53
|
+
* * @see {@link createClientConfig} and {@link createServerConfig} for how this is extended.
|
|
54
|
+
*/
|
|
31
55
|
export declare const ESBUILD_BASE_CONFIG: Partial<ESBuildConfig>;
|
package/dist/config/esbuild.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Standard loaders for source code files.
|
|
3
|
+
* * Maps common ECMAScript and TypeScript extensions to their respective esbuild parsers.
|
|
4
|
+
*/
|
|
2
5
|
export const BASE_LOADERS = {
|
|
3
6
|
'.js': 'js',
|
|
4
7
|
'.jsx': 'jsx',
|
|
@@ -6,6 +9,13 @@ export const BASE_LOADERS = {
|
|
|
6
9
|
'.tsx': 'tsx',
|
|
7
10
|
'.json': 'json',
|
|
8
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Loaders for static assets and styling.
|
|
14
|
+
* * Used primarily in Client builds to ensure that CSS and media files are
|
|
15
|
+
* processed and emitted to the output directory.
|
|
16
|
+
* - **CSS**: Processed as standard stylesheets.
|
|
17
|
+
* - **Images/Fonts**: Handled using the `file` loader (emits a file and returns a URL).
|
|
18
|
+
*/
|
|
9
19
|
export const ASSET_LOADERS = {
|
|
10
20
|
'.css': 'css',
|
|
11
21
|
'.png': 'file',
|
|
@@ -17,6 +27,13 @@ export const ASSET_LOADERS = {
|
|
|
17
27
|
'.woff': 'file',
|
|
18
28
|
'.woff2': 'file',
|
|
19
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* "Null" loaders used to ignore static assets during specific build phases.
|
|
32
|
+
* * @remarks
|
|
33
|
+
* This is primarily used in **Server (SSR)** builds. On the server, we want to
|
|
34
|
+
* resolve imports for assets (so the code doesn't throw) but we don't want to
|
|
35
|
+
* actually process or emit those files, as the Client build handles them.
|
|
36
|
+
*/
|
|
20
37
|
export const NO_ASSET_LOADERS = {
|
|
21
38
|
'.css': 'empty',
|
|
22
39
|
'.png': 'empty',
|
|
@@ -28,16 +45,25 @@ export const NO_ASSET_LOADERS = {
|
|
|
28
45
|
'.woff': 'empty',
|
|
29
46
|
'.woff2': 'empty',
|
|
30
47
|
};
|
|
31
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The default base configuration shared across all build targets.
|
|
50
|
+
* * This configuration prioritizes modern standards (ESM) and silent execution
|
|
51
|
+
* to allow the parent CLI or framework to manage logging.
|
|
52
|
+
* * @see {@link createClientConfig} and {@link createServerConfig} for how this is extended.
|
|
53
|
+
*/
|
|
32
54
|
export const ESBUILD_BASE_CONFIG = {
|
|
33
|
-
|
|
55
|
+
/** Generates a JSON file for bundle analysis and size tracking. */
|
|
34
56
|
metafile: true,
|
|
57
|
+
/** Enables terminal colors for errors and warnings. */
|
|
35
58
|
color: true,
|
|
59
|
+
/** Disables esbuild's default logging to favor custom application error handling. */
|
|
36
60
|
logLevel: 'silent',
|
|
37
|
-
|
|
61
|
+
/** Removes unreachable code to reduce bundle size. */
|
|
38
62
|
treeShaking: true,
|
|
39
|
-
|
|
63
|
+
/** * Disabled by default. Only enabled for Client Production builds
|
|
64
|
+
* where browser-native ESM loading is required.
|
|
65
|
+
*/
|
|
40
66
|
splitting: false,
|
|
41
|
-
|
|
67
|
+
/** Standardizes on ECMAScript Modules for modern Node.js and Browser environments. */
|
|
42
68
|
format: 'esm',
|
|
43
69
|
};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/types/config.d.ts
CHANGED
|
@@ -1,53 +1,120 @@
|
|
|
1
1
|
import type { Loader, Plugin } from 'esbuild';
|
|
2
|
+
/**
|
|
3
|
+
* The foundational configuration shared by all build targets (Client, Server, Dev, Prod).
|
|
4
|
+
* * Defines the environment-agnostic settings such as project paths,
|
|
5
|
+
* tree-shaking logic, and the default JSX transformation.
|
|
6
|
+
*/
|
|
2
7
|
export interface ESBuildBaseConfig {
|
|
8
|
+
/** Enables terminal colors for errors and warnings. */
|
|
3
9
|
color: true;
|
|
10
|
+
/** Disables esbuild's default logging to favor custom application error handling. */
|
|
4
11
|
logLevel: 'silent';
|
|
12
|
+
/** Removes unreachable code to reduce bundle size across all platforms. */
|
|
5
13
|
treeShaking: true;
|
|
14
|
+
/** Standardizes on ECMAScript Modules (ESM) for modern runtime support. */
|
|
6
15
|
format: 'esm';
|
|
16
|
+
/** The absolute path to the project root directory. */
|
|
7
17
|
absWorkingDir: string;
|
|
18
|
+
/** The output directory for the build artifacts. Optional if `write` is false. */
|
|
8
19
|
outdir?: string;
|
|
20
|
+
/** The specific output file path. Alternative to `outdir`. */
|
|
9
21
|
outfile?: string;
|
|
22
|
+
/** The entry file(s) where esbuild starts the bundling process. */
|
|
10
23
|
entryPoints: string[];
|
|
24
|
+
/** An array of {@link Plugin} instances to extend esbuild functionality. */
|
|
11
25
|
plugins: Plugin[];
|
|
26
|
+
/** Configures the React transformation to use the modern 'automatic' runtime. */
|
|
12
27
|
jsx: 'automatic';
|
|
13
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* A dictionary mapping file extensions (e.g., `.png`) to their respective esbuild {@link Loader}.
|
|
31
|
+
*/
|
|
14
32
|
export type LoaderFiles = Record<string, Loader>;
|
|
33
|
+
/**
|
|
34
|
+
* Configuration specific to Browser-targeted builds.
|
|
35
|
+
* * Sets the platform to `browser` and ensures all packages are bundled
|
|
36
|
+
* to be compatible with client-side execution.
|
|
37
|
+
*/
|
|
15
38
|
export interface ESBuildClientConfig {
|
|
39
|
+
/** Targets the browser environment. */
|
|
16
40
|
platform: 'browser';
|
|
41
|
+
/** Specifies the ECMAScript version for the output. */
|
|
17
42
|
target: ['es2022'];
|
|
43
|
+
/** Loaders for client-side assets (CSS, Images, etc.). */
|
|
18
44
|
loader: LoaderFiles;
|
|
45
|
+
/** Ensures dependencies are bundled into the final output. */
|
|
19
46
|
bundle: true;
|
|
47
|
+
/** Aggressively bundles all node_modules into the browser chunks. */
|
|
20
48
|
packages: 'bundle';
|
|
21
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Configuration specific to Node.js-targeted builds.
|
|
52
|
+
* * Optimized for Server-Side Rendering (SSR) where `node_modules` should
|
|
53
|
+
* remain external for faster execution and compatibility.
|
|
54
|
+
*/
|
|
22
55
|
export interface ESBuildServerConfig {
|
|
56
|
+
/** Targets the Node.js environment. */
|
|
23
57
|
platform: 'node';
|
|
58
|
+
/** Specifies the minimum supported Node version. */
|
|
24
59
|
target: ['node18'];
|
|
60
|
+
/** Loaders for server-side assets (often uses 'empty' for styles). */
|
|
25
61
|
loader: LoaderFiles;
|
|
62
|
+
/** Prevents node_modules from being bundled into the server file. */
|
|
26
63
|
packages: 'external';
|
|
64
|
+
/** Specific package names to explicitly exclude from the bundle. */
|
|
27
65
|
external: string[];
|
|
66
|
+
/** Disabled for server to leverage native Node module resolution. */
|
|
28
67
|
bundle: false;
|
|
29
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Settings applied during local development.
|
|
71
|
+
* * Focuses on build speed and debuggability rather than file size.
|
|
72
|
+
*/
|
|
30
73
|
export interface ESBuildDevConfig {
|
|
74
|
+
/** Disables minification for readable source code. */
|
|
31
75
|
minify: false;
|
|
32
76
|
minifyWhitespace: false;
|
|
33
77
|
minifyIdentifiers: false;
|
|
34
78
|
minifySyntax: false;
|
|
79
|
+
/** Keeps output in memory to speed up hot-reloading/serving. */
|
|
35
80
|
write: false;
|
|
81
|
+
/** Code splitting is disabled in dev to simplify module resolution. */
|
|
36
82
|
splitting: false;
|
|
83
|
+
/** Generates a metafile for real-time dependency analysis. */
|
|
37
84
|
metafile: true;
|
|
38
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Settings applied during production builds.
|
|
88
|
+
* * Focuses on aggressive optimization, minification, and disk-ready output.
|
|
89
|
+
*/
|
|
39
90
|
export interface ESBuildProdConfig {
|
|
91
|
+
/** Enables full minification suite for smallest possible file size. */
|
|
40
92
|
minify: true;
|
|
41
93
|
minifyWhitespace: true;
|
|
42
94
|
minifyIdentifiers: true;
|
|
43
95
|
minifySyntax: true;
|
|
96
|
+
/** Writes files to the `outdir` for deployment. */
|
|
44
97
|
write: true;
|
|
98
|
+
/** Enables ESM-based code splitting for lazy loading. */
|
|
45
99
|
splitting: true;
|
|
100
|
+
/** Metafile is typically disabled in production to save build time. */
|
|
46
101
|
metafile: false;
|
|
47
102
|
}
|
|
103
|
+
/** Intersection type for a Client-side Development build. */
|
|
48
104
|
export type ESBuildClientDevConfig = ESBuildBaseConfig & ESBuildClientConfig & ESBuildDevConfig;
|
|
105
|
+
/** Intersection type for a Client-side Production build. */
|
|
49
106
|
export type ESBuildClientProdConfig = ESBuildBaseConfig & ESBuildClientConfig & ESBuildProdConfig;
|
|
107
|
+
/** Intersection type for a Server-side Development build. */
|
|
50
108
|
export type ESBuildServerDevConfig = ESBuildBaseConfig & ESBuildServerConfig & ESBuildDevConfig;
|
|
109
|
+
/** Intersection type for a Server-side Production build. */
|
|
51
110
|
export type ESBuildServerProdConfig = ESBuildBaseConfig & ESBuildServerConfig & ESBuildProdConfig;
|
|
111
|
+
/**
|
|
112
|
+
* A exhaustive union of all valid configuration states for the Bundler.
|
|
113
|
+
* * Using this type ensures that a configuration cannot have invalid
|
|
114
|
+
* property combinations (e.g., a Server build cannot accidentally have 'bundle: true').
|
|
115
|
+
*/
|
|
52
116
|
export type ESBuildConfig = ESBuildClientDevConfig | ESBuildClientProdConfig | ESBuildServerDevConfig | ESBuildServerProdConfig;
|
|
117
|
+
/**
|
|
118
|
+
* Type alias for a map of file extensions to esbuild Loaders.
|
|
119
|
+
*/
|
|
53
120
|
export type Loaders = Record<string, Loader>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CACHE_DIR = "/.rsaf";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CACHE_DIR = '/.rsaf';
|
package/package.json
CHANGED
package/dist/config/path.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param path - The path to normalize
|
|
3
|
-
* @returns Normalized Path
|
|
4
|
-
*/
|
|
5
|
-
export declare const normalizePath: (path: string) => string;
|
|
6
|
-
/**
|
|
7
|
-
* Generates the correct relative path to the static directory based on the current URL depth
|
|
8
|
-
* @param currentPath - The current page URL path
|
|
9
|
-
* @param staticDir - The static directory name (default: "static")
|
|
10
|
-
* @returns The relative path to the static directory
|
|
11
|
-
*/
|
|
12
|
-
export declare function getStaticPath(currentPath: string, staticDir?: string): string;
|
|
13
|
-
export declare const DEV_RUNTIME_DIR: string;
|
|
14
|
-
export declare const DEV_CLIENT_DIR: string;
|
|
15
|
-
export declare const DEV_SERVER_DIR: string;
|
|
16
|
-
export declare const DEV_SERVER_ENTRY: string;
|
|
17
|
-
export declare const DEV_CLIENT_ENTRY: string;
|
|
18
|
-
export declare const DEV_CLIENT_STATIC_DIR: string;
|
|
19
|
-
export declare const DEV_CLIENT_APP_ENTRY: string;
|
|
20
|
-
export declare const DEV_CLIENT_STYLES_ENTRY: string;
|
|
21
|
-
export declare const DEV_CLIENT_HYDRATE_ENTRY: string;
|
|
22
|
-
export declare const DEV_SERVER_RENDERER_ENTRY: string;
|
|
23
|
-
export declare const DEV_SERVER_APP_ENTRY: string;
|
|
24
|
-
export declare const DEV_SERVER_ROUTER_ENTRY: string;
|
|
25
|
-
export declare const DEV_SSR_CACHE_DIR: string;
|
|
26
|
-
export declare const DEV_SSR_TEMP_MODULE_DIR: string;
|
|
27
|
-
export declare const DEV_CLIENT_MANIFEST_PATH: string;
|
|
28
|
-
export declare const DEV_SERVER_MANIFEST_PATH: string;
|
|
29
|
-
export declare const APP_CONFIG_FILE_PATH: string;
|
|
30
|
-
export declare const APP_STYLESHEET_PATH: string;
|
|
31
|
-
export declare const PATH_PATTERNS: {
|
|
32
|
-
STATIC_FILES: RegExp;
|
|
33
|
-
API_ROUTES: RegExp;
|
|
34
|
-
JS_FILES: RegExp;
|
|
35
|
-
CSS_FILES: RegExp;
|
|
36
|
-
ASSET_FILES: RegExp;
|
|
37
|
-
CONFIG_FILES: RegExp;
|
|
38
|
-
};
|
package/dist/config/path.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param path - The path to normalize
|
|
3
|
-
* @returns Normalized Path
|
|
4
|
-
*/
|
|
5
|
-
export const normalizePath = (path) => '/' + (path || '').replace(/\/+/g, '/').replace(/^\/+|\/+$/g, '');
|
|
6
|
-
/**
|
|
7
|
-
* Generates the correct relative path to the static directory based on the current URL depth
|
|
8
|
-
* @param currentPath - The current page URL path
|
|
9
|
-
* @param staticDir - The static directory name (default: "static")
|
|
10
|
-
* @returns The relative path to the static directory
|
|
11
|
-
*/
|
|
12
|
-
export function getStaticPath(currentPath, staticDir = 'static') {
|
|
13
|
-
// Normalize path: remove leading/trailing slashes
|
|
14
|
-
const segments = currentPath
|
|
15
|
-
.replace(/^\/+|\/+$/g, '')
|
|
16
|
-
.split('/')
|
|
17
|
-
.filter(p => p);
|
|
18
|
-
const depth = segments.length;
|
|
19
|
-
// Build the relative path
|
|
20
|
-
if (depth === 0) {
|
|
21
|
-
// Root level
|
|
22
|
-
return `./${staticDir}`;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
// Go up one level for each directory segment
|
|
26
|
-
const upLevels = '../'.repeat(depth);
|
|
27
|
-
return `${upLevels}${staticDir}`;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
// Root runtime directories
|
|
31
|
-
export const DEV_RUNTIME_DIR = normalizePath('.nexus');
|
|
32
|
-
export const DEV_CLIENT_DIR = normalizePath('.nexus/client');
|
|
33
|
-
export const DEV_SERVER_DIR = normalizePath('.nexus/server');
|
|
34
|
-
// App Entry Paths
|
|
35
|
-
export const DEV_SERVER_ENTRY = normalizePath('.nexus/server/entry.tsx');
|
|
36
|
-
export const DEV_CLIENT_ENTRY = normalizePath('.nexus/client/entry.tsx');
|
|
37
|
-
// Client build outputs
|
|
38
|
-
export const DEV_CLIENT_STATIC_DIR = normalizePath('.nexus/client/static');
|
|
39
|
-
export const DEV_CLIENT_APP_ENTRY = normalizePath('.nexus/client/hydrate.js');
|
|
40
|
-
export const DEV_CLIENT_STYLES_ENTRY = normalizePath('.nexus/client/styles.css');
|
|
41
|
-
export const DEV_CLIENT_HYDRATE_ENTRY = normalizePath('.nexus/client/hydrate.tsx');
|
|
42
|
-
export const DEV_SERVER_RENDERER_ENTRY = normalizePath('.nexus/server/renderer.tsx');
|
|
43
|
-
// Server build outputs
|
|
44
|
-
export const DEV_SERVER_APP_ENTRY = normalizePath('.nexus/server/App.ssr.js');
|
|
45
|
-
export const DEV_SERVER_ROUTER_ENTRY = normalizePath('.nexus/server/router.js');
|
|
46
|
-
// Runtime + SSR state
|
|
47
|
-
export const DEV_SSR_CACHE_DIR = normalizePath('.nexus/cache');
|
|
48
|
-
export const DEV_SSR_TEMP_MODULE_DIR = normalizePath('.nexus/runtime/modules');
|
|
49
|
-
// Build result manifests
|
|
50
|
-
export const DEV_CLIENT_MANIFEST_PATH = normalizePath('.nexus/client/manifest.json');
|
|
51
|
-
export const DEV_SERVER_MANIFEST_PATH = normalizePath('.nexus/server/manifest.json');
|
|
52
|
-
// App Config paths
|
|
53
|
-
export const APP_CONFIG_FILE_PATH = normalizePath('nexus.config.ts');
|
|
54
|
-
// Server Paths
|
|
55
|
-
export const APP_STYLESHEET_PATH = normalizePath('static/styles.css');
|
|
56
|
-
// Constants for common path patterns
|
|
57
|
-
export const PATH_PATTERNS = {
|
|
58
|
-
// Pattern matchers for routes
|
|
59
|
-
STATIC_FILES: /^\/static\//,
|
|
60
|
-
API_ROUTES: /^\/api\//,
|
|
61
|
-
// File extensions
|
|
62
|
-
JS_FILES: /\.(js|mjs|cjs|jsx|ts|tsx)$/,
|
|
63
|
-
CSS_FILES: /\.(css|scss|sass|less)$/,
|
|
64
|
-
ASSET_FILES: /\.(png|jpg|jpeg|gif|svg|ico|webp|avif|woff|woff2|ttf|eot)$/,
|
|
65
|
-
// Configuration files
|
|
66
|
-
CONFIG_FILES: /\.config\.(js|ts|json)$/,
|
|
67
|
-
};
|