@richapps/ong 0.1.1 → 0.1.3
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/cli.js +12 -1
- package/dist/config.d.ts +6 -1
- package/dist/config.js +67 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/log.js +1 -0
- package/dist/plugins.js +7 -8
- package/dist/prebundle.d.ts +8 -0
- package/dist/prebundle.js +113 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createServer, build } from 'vite';
|
|
2
2
|
import { resolveWorkspace } from './workspace.js';
|
|
3
3
|
import { createViteConfig } from './config.js';
|
|
4
|
+
import { prebundleLibs } from './prebundle.js';
|
|
4
5
|
import { banner, printBuildStats, printHelp, error } from './log.js';
|
|
5
6
|
function parseArgs(argv) {
|
|
6
7
|
const args = argv.slice(2);
|
|
@@ -37,9 +38,16 @@ function parseArgs(argv) {
|
|
|
37
38
|
else if (arg === '--watch' || arg === '-w') {
|
|
38
39
|
result.watch = true;
|
|
39
40
|
}
|
|
41
|
+
else if (arg === '--prebundle-libs') {
|
|
42
|
+
result.prebundleLibs = true;
|
|
43
|
+
}
|
|
40
44
|
else if (arg === '--help' || arg === '-h') {
|
|
41
45
|
return { command: 'help' };
|
|
42
46
|
}
|
|
47
|
+
else if (!arg.startsWith('-') && !result.project) {
|
|
48
|
+
// Treat bare positional arg as project (e.g. "ong serve apps/editor")
|
|
49
|
+
result.project = arg;
|
|
50
|
+
}
|
|
43
51
|
}
|
|
44
52
|
return result;
|
|
45
53
|
}
|
|
@@ -64,7 +72,10 @@ async function main() {
|
|
|
64
72
|
};
|
|
65
73
|
const buildOpts = resolveWorkspace(cwd, resolveOpts);
|
|
66
74
|
banner(args.command, buildOpts.projectName, buildOpts.configName);
|
|
67
|
-
|
|
75
|
+
let viteConfig = createViteConfig(buildOpts);
|
|
76
|
+
if (args.prebundleLibs && args.command === 'serve') {
|
|
77
|
+
viteConfig = await prebundleLibs(viteConfig, buildOpts);
|
|
78
|
+
}
|
|
68
79
|
if (args.command === 'serve') {
|
|
69
80
|
const server = await createServer(viteConfig);
|
|
70
81
|
await server.listen();
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import type { InlineConfig } from 'vite';
|
|
1
|
+
import type { InlineConfig, Alias } from 'vite';
|
|
2
2
|
import type { ResolvedBuildOptions } from './workspace.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reads tsconfig paths and converts them to Vite resolve aliases.
|
|
5
|
+
* Follows tsconfig "extends" chain to find paths from base configs.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveTsconfigPaths(tsconfig: string, workspaceRoot: string): Alias[];
|
|
3
8
|
/**
|
|
4
9
|
* Creates a Vite InlineConfig from resolved Angular build options.
|
|
5
10
|
*/
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
1
|
import { resolve } from 'node:path';
|
|
2
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
3
|
import { angular } from '@oxc-angular/vite';
|
|
3
4
|
import { htmlInjectPlugin, assetCopyPlugin } from './plugins.js';
|
|
5
|
+
/**
|
|
6
|
+
* Reads tsconfig paths and converts them to Vite resolve aliases.
|
|
7
|
+
* Follows tsconfig "extends" chain to find paths from base configs.
|
|
8
|
+
*/
|
|
9
|
+
export function resolveTsconfigPaths(tsconfig, workspaceRoot) {
|
|
10
|
+
const aliases = [];
|
|
11
|
+
try {
|
|
12
|
+
let configPath = tsconfig;
|
|
13
|
+
let paths;
|
|
14
|
+
let baseUrl = '.';
|
|
15
|
+
// Walk the extends chain to find paths
|
|
16
|
+
while (configPath && !paths) {
|
|
17
|
+
if (!existsSync(configPath))
|
|
18
|
+
break;
|
|
19
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
20
|
+
// Strip comments (single-line // and multi-line /* */)
|
|
21
|
+
const stripped = raw.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
|
|
22
|
+
const config = JSON.parse(stripped);
|
|
23
|
+
const compilerOptions = config.compilerOptions ?? {};
|
|
24
|
+
if (compilerOptions.paths) {
|
|
25
|
+
paths = compilerOptions.paths;
|
|
26
|
+
baseUrl = compilerOptions.baseUrl ?? '.';
|
|
27
|
+
}
|
|
28
|
+
if (config.extends) {
|
|
29
|
+
configPath = resolve(configPath, '..', config.extends);
|
|
30
|
+
// Add .json if not present
|
|
31
|
+
if (!configPath.endsWith('.json'))
|
|
32
|
+
configPath += '.json';
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!paths)
|
|
39
|
+
return aliases;
|
|
40
|
+
const baseDir = resolve(workspaceRoot, baseUrl);
|
|
41
|
+
for (const [pattern, targets] of Object.entries(paths)) {
|
|
42
|
+
if (!targets.length)
|
|
43
|
+
continue;
|
|
44
|
+
const target = targets[0];
|
|
45
|
+
if (pattern.endsWith('/*')) {
|
|
46
|
+
// Wildcard mapping: "@scope/lib/*" -> "libs/lib/src/*"
|
|
47
|
+
const prefix = pattern.slice(0, -2);
|
|
48
|
+
const targetDir = resolve(baseDir, target.slice(0, -2));
|
|
49
|
+
aliases.push({ find: new RegExp(`^${escapeRegex(prefix)}/(.*)`), replacement: `${targetDir}/$1` });
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Exact mapping: "@scope/lib" -> "libs/lib/src/index.ts"
|
|
53
|
+
aliases.push({ find: pattern, replacement: resolve(baseDir, target) });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Ignore tsconfig parse errors — fall back to no aliases
|
|
59
|
+
}
|
|
60
|
+
return aliases;
|
|
61
|
+
}
|
|
62
|
+
function escapeRegex(str) {
|
|
63
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
64
|
+
}
|
|
4
65
|
/**
|
|
5
66
|
* Creates a Vite InlineConfig from resolved Angular build options.
|
|
6
67
|
*/
|
|
@@ -29,8 +90,8 @@ export function createViteConfig(opts) {
|
|
|
29
90
|
const cssPreprocessorOptions = {};
|
|
30
91
|
if (opts.stylePreprocessorOptions.includePaths.length) {
|
|
31
92
|
const paths = opts.stylePreprocessorOptions.includePaths;
|
|
32
|
-
cssPreprocessorOptions.scss = {
|
|
33
|
-
cssPreprocessorOptions.sass = {
|
|
93
|
+
cssPreprocessorOptions.scss = { api: 'modern-compiler', loadPaths: paths };
|
|
94
|
+
cssPreprocessorOptions.sass = { api: 'modern-compiler', loadPaths: paths };
|
|
34
95
|
cssPreprocessorOptions.less = { paths };
|
|
35
96
|
}
|
|
36
97
|
return {
|
|
@@ -53,6 +114,7 @@ export function createViteConfig(opts) {
|
|
|
53
114
|
...(Object.keys(opts.define).length ? { define: opts.define } : {}),
|
|
54
115
|
resolve: {
|
|
55
116
|
preserveSymlinks: opts.preserveSymlinks,
|
|
117
|
+
alias: resolveTsconfigPaths(opts.tsconfig, workspaceRoot),
|
|
56
118
|
},
|
|
57
119
|
css: Object.keys(cssPreprocessorOptions).length
|
|
58
120
|
? { preprocessorOptions: cssPreprocessorOptions }
|
|
@@ -84,6 +146,9 @@ export function createViteConfig(opts) {
|
|
|
84
146
|
open: opts.serve.open,
|
|
85
147
|
host: opts.serve.host ?? false,
|
|
86
148
|
watch: opts.poll ? { usePolling: true, interval: opts.poll } : undefined,
|
|
149
|
+
fs: {
|
|
150
|
+
allow: [workspaceRoot],
|
|
151
|
+
},
|
|
87
152
|
},
|
|
88
153
|
};
|
|
89
154
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,3 +11,4 @@ export { resolveWorkspace, detectWorkspace } from './workspace.js';
|
|
|
11
11
|
export type { ResolvedBuildOptions, ResolveOptions, AssetConfig } from './workspace.js';
|
|
12
12
|
export { createViteConfig } from './config.js';
|
|
13
13
|
export { htmlInjectPlugin, assetCopyPlugin } from './plugins.js';
|
|
14
|
+
export { prebundleLibs } from './prebundle.js';
|
package/dist/index.js
CHANGED
package/dist/log.js
CHANGED
|
@@ -80,6 +80,7 @@ export function printHelp() {
|
|
|
80
80
|
-o, --open Open browser on start
|
|
81
81
|
--host <host> Dev server host
|
|
82
82
|
-w, --watch Rebuild on file changes (build mode)
|
|
83
|
+
--prebundle-libs Pre-bundle local libs to resolve circular deps
|
|
83
84
|
|
|
84
85
|
${c.bold}Workspace support:${c.reset}
|
|
85
86
|
angular.json Standard Angular CLI workspace
|
package/dist/plugins.js
CHANGED
|
@@ -43,17 +43,16 @@ export function htmlInjectPlugin(opts) {
|
|
|
43
43
|
}
|
|
44
44
|
// Inject polyfills before the entry point
|
|
45
45
|
if (opts.polyfills.length) {
|
|
46
|
-
const
|
|
46
|
+
const imports = opts.polyfills
|
|
47
47
|
.map(p => {
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
return ` <script type="module">import '${p}';</script>`;
|
|
48
|
+
// Check if it's a file path (relative to workspace root or absolute)
|
|
49
|
+
const resolved = resolve(opts.workspaceRoot, p);
|
|
50
|
+
const isFile = p.startsWith('.') || p.startsWith('/') || existsSync(resolved);
|
|
51
|
+
// Use absolute path for file imports so Vite can resolve them regardless of root
|
|
52
|
+
return isFile ? `import '${resolved}';` : `import '${p}';`;
|
|
54
53
|
})
|
|
55
54
|
.join('\n');
|
|
56
|
-
result = result.replace('</body>',
|
|
55
|
+
result = result.replace('</body>', ` <script type="module">\n${imports}\n</script>\n</body>`);
|
|
57
56
|
}
|
|
58
57
|
// Inject entry point if not already present
|
|
59
58
|
const hasEntry = html.includes(`src="${browserRelative}"`) ||
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type InlineConfig } from 'vite';
|
|
2
|
+
import type { ResolvedBuildOptions } from './workspace.js';
|
|
3
|
+
/**
|
|
4
|
+
* Pre-bundles local workspace libraries using rolldown + OXC.
|
|
5
|
+
* This resolves circular dependencies within libs by bundling each
|
|
6
|
+
* into a single ESM file before the Vite dev server starts.
|
|
7
|
+
*/
|
|
8
|
+
export declare function prebundleLibs(viteConfig: InlineConfig, opts: ResolvedBuildOptions): Promise<InlineConfig>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { mkdirSync, rmSync } from 'node:fs';
|
|
3
|
+
import { build } from 'vite';
|
|
4
|
+
import { angular } from '@oxc-angular/vite';
|
|
5
|
+
import { resolveTsconfigPaths } from './config.js';
|
|
6
|
+
import { c } from './log.js';
|
|
7
|
+
/**
|
|
8
|
+
* Pre-bundles local workspace libraries using rolldown + OXC.
|
|
9
|
+
* This resolves circular dependencies within libs by bundling each
|
|
10
|
+
* into a single ESM file before the Vite dev server starts.
|
|
11
|
+
*/
|
|
12
|
+
export async function prebundleLibs(viteConfig, opts) {
|
|
13
|
+
const aliases = resolveTsconfigPaths(opts.tsconfig, opts.workspaceRoot);
|
|
14
|
+
// Find aliases pointing to local workspace files (not node_modules)
|
|
15
|
+
const localLibs = [];
|
|
16
|
+
for (const alias of aliases) {
|
|
17
|
+
// Only handle exact-match aliases (string find), not wildcards (RegExp)
|
|
18
|
+
if (typeof alias.find !== 'string')
|
|
19
|
+
continue;
|
|
20
|
+
const target = alias.replacement;
|
|
21
|
+
// Must be inside workspace and not in node_modules
|
|
22
|
+
if (!target.startsWith(opts.workspaceRoot))
|
|
23
|
+
continue;
|
|
24
|
+
if (target.includes('node_modules'))
|
|
25
|
+
continue;
|
|
26
|
+
localLibs.push({
|
|
27
|
+
find: alias.find,
|
|
28
|
+
entry: target,
|
|
29
|
+
fileName: alias.find.replace(/[@/]/g, '_').replace(/^_+/, ''),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (localLibs.length === 0)
|
|
33
|
+
return viteConfig;
|
|
34
|
+
const start = Date.now();
|
|
35
|
+
console.log(` ${c.cyan}Pre-bundling ${localLibs.length} local lib${localLibs.length > 1 ? 's' : ''}...${c.reset}`);
|
|
36
|
+
// Output inside workspace node_modules so Vite can resolve bare imports
|
|
37
|
+
const tempDir = join(opts.workspaceRoot, 'node_modules', '.ong-prebundle');
|
|
38
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
39
|
+
mkdirSync(tempDir, { recursive: true });
|
|
40
|
+
// Bundle each lib in parallel
|
|
41
|
+
const results = await Promise.allSettled(localLibs.map(lib => bundleLib(lib, tempDir, aliases, opts, viteConfig)));
|
|
42
|
+
// Collect successfully bundled libs
|
|
43
|
+
const bundled = new Map();
|
|
44
|
+
results.forEach((result, i) => {
|
|
45
|
+
if (result.status === 'fulfilled') {
|
|
46
|
+
bundled.set(localLibs[i].find, join(tempDir, `${localLibs[i].fileName}.mjs`));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.log(` ${c.yellow}Warning: failed to pre-bundle ${localLibs[i].find}${c.reset}`);
|
|
50
|
+
console.log(` ${c.dim}${result.reason?.message ?? result.reason}${c.reset}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
if (bundled.size === 0)
|
|
54
|
+
return viteConfig;
|
|
55
|
+
const duration = Date.now() - start;
|
|
56
|
+
const names = [...bundled.keys()].join(', ');
|
|
57
|
+
console.log(` ${c.green}Pre-bundled in ${duration}ms:${c.reset} ${c.dim}${names}${c.reset}`);
|
|
58
|
+
console.log();
|
|
59
|
+
// Rewrite aliases: bundled libs point to the temp output
|
|
60
|
+
const newAliases = aliases.map(alias => {
|
|
61
|
+
if (typeof alias.find === 'string' && bundled.has(alias.find)) {
|
|
62
|
+
return { find: alias.find, replacement: bundled.get(alias.find) };
|
|
63
|
+
}
|
|
64
|
+
return alias;
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
...viteConfig,
|
|
68
|
+
resolve: {
|
|
69
|
+
...(viteConfig.resolve ?? {}),
|
|
70
|
+
alias: newAliases,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function bundleLib(lib, outDir, allAliases, opts, parentConfig) {
|
|
75
|
+
await build({
|
|
76
|
+
configFile: false,
|
|
77
|
+
root: opts.workspaceRoot,
|
|
78
|
+
logLevel: 'warn',
|
|
79
|
+
plugins: [
|
|
80
|
+
...angular({
|
|
81
|
+
tsconfig: opts.tsconfig,
|
|
82
|
+
sourceMap: opts.sourceMap,
|
|
83
|
+
workspaceRoot: opts.workspaceRoot,
|
|
84
|
+
}),
|
|
85
|
+
],
|
|
86
|
+
resolve: {
|
|
87
|
+
// All tsconfig aliases so inter-lib imports resolve
|
|
88
|
+
alias: allAliases,
|
|
89
|
+
},
|
|
90
|
+
// Pass through same CSS config for SCSS/Less resolution
|
|
91
|
+
css: parentConfig.css,
|
|
92
|
+
build: {
|
|
93
|
+
lib: {
|
|
94
|
+
entry: lib.entry,
|
|
95
|
+
formats: ['es'],
|
|
96
|
+
fileName: lib.fileName,
|
|
97
|
+
},
|
|
98
|
+
outDir,
|
|
99
|
+
emptyOutDir: false,
|
|
100
|
+
sourcemap: opts.sourceMap,
|
|
101
|
+
minify: false,
|
|
102
|
+
rollupOptions: {
|
|
103
|
+
external: (id) => {
|
|
104
|
+
// Bundle relative/absolute imports (internal to the lib)
|
|
105
|
+
if (id.startsWith('.') || id.startsWith('/'))
|
|
106
|
+
return false;
|
|
107
|
+
// Externalize everything else (npm packages, other local lib aliases)
|
|
108
|
+
return true;
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|