@richapps/ong 0.1.2 → 0.1.4

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 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,6 +38,9 @@ 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
  }
@@ -68,7 +72,10 @@ async function main() {
68
72
  };
69
73
  const buildOpts = resolveWorkspace(cwd, resolveOpts);
70
74
  banner(args.command, buildOpts.projectName, buildOpts.configName);
71
- const viteConfig = createViteConfig(buildOpts);
75
+ let viteConfig = createViteConfig(buildOpts);
76
+ if (args.prebundleLibs && args.command === 'serve') {
77
+ viteConfig = await prebundleLibs(viteConfig, buildOpts);
78
+ }
72
79
  if (args.command === 'serve') {
73
80
  const server = await createServer(viteConfig);
74
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
@@ -6,28 +6,25 @@ import { htmlInjectPlugin, assetCopyPlugin } from './plugins.js';
6
6
  * Reads tsconfig paths and converts them to Vite resolve aliases.
7
7
  * Follows tsconfig "extends" chain to find paths from base configs.
8
8
  */
9
- function resolveTsconfigPaths(tsconfig, workspaceRoot) {
9
+ export function resolveTsconfigPaths(tsconfig, workspaceRoot) {
10
10
  const aliases = [];
11
11
  try {
12
12
  let configPath = tsconfig;
13
13
  let paths;
14
14
  let baseUrl = '.';
15
15
  // Walk the extends chain to find paths
16
- while (configPath && !paths) {
16
+ // Collect baseUrl from each level; paths from the first config that defines them
17
+ const configChain = [];
18
+ while (configPath) {
17
19
  if (!existsSync(configPath))
18
20
  break;
19
21
  const raw = readFileSync(configPath, 'utf-8');
20
22
  // Strip comments (single-line // and multi-line /* */)
21
23
  const stripped = raw.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
22
24
  const config = JSON.parse(stripped);
23
- const compilerOptions = config.compilerOptions ?? {};
24
- if (compilerOptions.paths) {
25
- paths = compilerOptions.paths;
26
- baseUrl = compilerOptions.baseUrl ?? '.';
27
- }
25
+ configChain.push(config);
28
26
  if (config.extends) {
29
27
  configPath = resolve(configPath, '..', config.extends);
30
- // Add .json if not present
31
28
  if (!configPath.endsWith('.json'))
32
29
  configPath += '.json';
33
30
  }
@@ -35,6 +32,14 @@ function resolveTsconfigPaths(tsconfig, workspaceRoot) {
35
32
  break;
36
33
  }
37
34
  }
35
+ // Resolve inherited values: child overrides parent
36
+ for (let i = configChain.length - 1; i >= 0; i--) {
37
+ const compilerOptions = configChain[i].compilerOptions ?? {};
38
+ if (compilerOptions.baseUrl !== undefined)
39
+ baseUrl = compilerOptions.baseUrl;
40
+ if (compilerOptions.paths !== undefined)
41
+ paths = compilerOptions.paths;
42
+ }
38
43
  if (!paths)
39
44
  return aliases;
40
45
  const baseDir = resolve(workspaceRoot, baseUrl);
@@ -90,8 +95,8 @@ export function createViteConfig(opts) {
90
95
  const cssPreprocessorOptions = {};
91
96
  if (opts.stylePreprocessorOptions.includePaths.length) {
92
97
  const paths = opts.stylePreprocessorOptions.includePaths;
93
- cssPreprocessorOptions.scss = { includePaths: paths };
94
- cssPreprocessorOptions.sass = { includePaths: paths };
98
+ cssPreprocessorOptions.scss = { api: 'modern-compiler', loadPaths: paths };
99
+ cssPreprocessorOptions.sass = { api: 'modern-compiler', loadPaths: paths };
95
100
  cssPreprocessorOptions.less = { paths };
96
101
  }
97
102
  return {
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
@@ -10,3 +10,4 @@
10
10
  export { resolveWorkspace, detectWorkspace } from './workspace.js';
11
11
  export { createViteConfig } from './config.js';
12
12
  export { htmlInjectPlugin, assetCopyPlugin } from './plugins.js';
13
+ export { prebundleLibs } from './prebundle.js';
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
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@richapps/ong",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Angular CLI powered by Vite + OXC — blazing fast drop-in replacement for ng serve/build",
5
5
  "keywords": [
6
6
  "angular",