88 * closeBundle() in less:build plugin. No longer a standalone CLI entry.
99 * ctx parameter is required (no globalThis fallback).
1010 *
11- * Resolution: Aliases are auto-generated from workspace packages'
12- * deno.json exports — not hardcoded, not in user config. When Vite/rolldown
13- * supports Deno workspace resolution natively, this can be removed.
14- *
1511 * Usage:
1612 * deno task build (unified entry — runs all 3 phases)
1713 */
@@ -22,77 +18,16 @@ import process from 'node:process';
2218import { type ClientIslandEntry , generateClientEntry } from '../entry-generators.js' ;
2319import type { LessBuildContext } from '../build-context.js' ;
2420import { createLogger } from '@lessjs/core/logger' ;
21+ import {
22+ findWorkspaceRoot ,
23+ generateWorkspaceAliases ,
24+ } from '../workspace-alias.js' ;
2525
2626const log = createLogger ( 'ssg' ) ;
2727
2828const VIRTUAL_CLIENT_ENTRY_ID = 'virtual:less-client-entry' ;
2929const RESOLVED_CLIENT_ENTRY_ID = '\0' + VIRTUAL_CLIENT_ENTRY_ID ;
3030
31- // ─── Alias auto-generation from workspace ────────────────────────────
32-
33- interface AliasEntry {
34- find : string ;
35- replacement : string ;
36- }
37-
38- /**
39- * Walk up from startDir to find a deno.json with a "workspace" field.
40- */
41- async function findWorkspaceRoot ( startDir : string ) : Promise < string | null > {
42- let dir = resolve ( startDir ) ;
43- const fsRoot = resolve ( '/' ) ;
44- while ( dir !== fsRoot && dir !== resolve ( dir , '..' ) ) {
45- try {
46- const cfg = JSON . parse ( await Deno . readTextFile ( resolve ( dir , 'deno.json' ) ) ) ;
47- if ( cfg . workspace && Array . isArray ( cfg . workspace ) ) return dir ;
48- } catch { /* not found or no workspace */ }
49- dir = resolve ( dir , '..' ) ;
50- }
51- return null ;
52- }
53-
54- /**
55- * Generate Vite resolve.alias from workspace packages' deno.json exports.
56- * Subpath aliases come before parent (Vite prefix matching rule).
57- */
58- async function generateWorkspaceAliases ( workspaceRoot : string ) : Promise < AliasEntry [ ] > {
59- const rootCfg = JSON . parse ( await Deno . readTextFile ( resolve ( workspaceRoot , 'deno.json' ) ) ) ;
60- const members : string [ ] = rootCfg . workspace || [ ] ;
61- const aliases : AliasEntry [ ] = [ ] ;
62-
63- for ( const member of members ) {
64- const memberDir = resolve ( workspaceRoot , member ) ;
65- let memberCfg : Record < string , unknown > ;
66- try {
67- memberCfg = JSON . parse ( await Deno . readTextFile ( resolve ( memberDir , 'deno.json' ) ) ) ;
68- } catch {
69- continue ;
70- }
71- const name = memberCfg . name as string | undefined ;
72- const exports = memberCfg . exports as Record < string , string > | string | undefined ;
73- if ( ! name || ! exports ) continue ;
74-
75- if ( typeof exports === 'string' ) {
76- aliases . push ( { find : name , replacement : resolve ( memberDir , exports ) } ) ;
77- continue ;
78- }
79-
80- // Subpath aliases first (Vite prefix matching)
81- for ( const [ exportPath , sourcePath ] of Object . entries ( exports ) ) {
82- if ( exportPath === '.' ) continue ;
83- const subpath = exportPath . replace ( / ^ \. \/ / , '/' ) ;
84- aliases . push ( { find : `${ name } ${ subpath } ` , replacement : resolve ( memberDir , sourcePath as string ) } ) ;
85- }
86- // Parent alias last
87- if ( exports [ '.' ] ) {
88- aliases . push ( { find : name , replacement : resolve ( memberDir , exports [ '.' ] as string ) } ) ;
89- }
90- }
91- return aliases ;
92- }
93-
94- // ─── Build function ──────────────────────────────────────────────────
95-
9631async function buildClient ( ctx : LessBuildContext ) : Promise < void > {
9732 const root = ctx . root || process . cwd ( ) ;
9833 const outDir = ctx . outDir || 'dist' ;
@@ -101,8 +36,8 @@ async function buildClient(ctx: LessBuildContext): Promise<void> {
10136 const localIslandFiles = ctx . islandFiles || [ ] ;
10237 const packageIslands = ctx . packageIslands || [ ] ;
10338
104- // Auto-generate aliases from workspace
105- let serializedAlias : AliasEntry [ ] | null = null ;
39+ // Auto-generate aliases from workspace packages
40+ let serializedAlias = null ;
10641 const workspaceRoot = await findWorkspaceRoot ( root ) ;
10742 if ( workspaceRoot ) {
10843 serializedAlias = await generateWorkspaceAliases ( workspaceRoot ) ;
0 commit comments