@@ -2,6 +2,8 @@ import * as path from "path";
22import * as child_process from "child_process" ;
33import * as semver from "semver" ;
44import * as _ from "lodash" ;
5+ // TODO: can switch to file-system service
6+ import { mkdirSync , readdirSync , existsSync , copyFileSync , rmSync } from "fs" ;
57import { EventEmitter } from "events" ;
68import { performanceLog } from "../../common/decorators" ;
79import {
@@ -126,96 +128,37 @@ export class BundlerCompilerService
126128 }
127129
128130 // Copy Vite output files directly to platform destination
129- const distOutput = path . join ( projectData . projectDir , "dist" ) ;
131+ const distOutput = path . join (
132+ projectData . projectDir ,
133+ ".ns-vite-build" ,
134+ ) ;
130135 const destDir = path . join (
131136 platformData . appDestinationDirectoryPath ,
132137 this . $options . hostProjectModuleName ,
133138 ) ;
134139
135140 if ( debugLog ) {
136- console . log ( `🔥 Copying from ${ distOutput } to ${ destDir } ` ) ;
141+ console . log ( `Copying from ${ distOutput } to ${ destDir } . ` ) ;
137142 }
138143
139144 // Determine which files to copy based on build type and changes
140- if ( message . isHMR ) {
141- // HMR updates: only copy changed files
142- if ( debugLog ) {
143- console . log (
144- "🔥 HMR update - copying only changed files for:" ,
145- message . changedFiles ,
146- ) ;
147- }
148-
149- // For HTML template changes, we need to copy the component files that were rebuilt
150- let filesToCopy = message . emittedFiles ;
151-
152- // If we have HTML changes, identify which component files need copying
153- const hasHTMLChanges = message . changedFiles . some ( ( f ) =>
154- f . endsWith ( ".html" ) ,
155- ) ;
156- if ( hasHTMLChanges ) {
157- // Copy component-related files (the ones that would have been rebuilt due to template changes)
158- filesToCopy = message . emittedFiles . filter (
159- ( f ) =>
160- f . includes ( ".component" ) ||
161- f === "bundle.mjs" ||
162- f === "bundle.mjs.map" ,
163- ) ;
164- if ( debugLog ) {
165- console . log (
166- "🔥 HTML change detected - copying component files:" ,
167- filesToCopy ,
168- ) ;
169- }
170- }
171-
172- this . copyViteBundleToNative ( distOutput , destDir , filesToCopy ) ;
173- } else if (
145+ if (
174146 message . buildType === "incremental" &&
175- message . changedFiles &&
176- message . changedFiles . length > 0
147+ message . emittedFiles &&
148+ message . emittedFiles . length > 0
177149 ) {
178150 // Incremental builds: only copy files that are likely affected by the changes
179- if ( debugLog ) {
180- console . log (
181- "🔥 Incremental build - copying only relevant files for:" ,
182- message . changedFiles ,
183- ) ;
184- }
185-
186151 const filesToCopy = this . getIncrementalFilesToCopy (
187152 message . emittedFiles ,
188- message . changedFiles ,
189153 ) ;
190154 if ( debugLog ) {
191- console . log (
192- "🔥 Incremental build - files to copy:" ,
193- filesToCopy ,
194- ) ;
155+ console . log ( "Incremental build - files to copy:" , filesToCopy ) ;
195156 }
196157
197- this . copyViteBundleToNative ( distOutput , destDir , filesToCopy ) ;
198- } else if (
199- message . buildType === "incremental" &&
200- message . changedFiles &&
201- message . changedFiles . length > 0
202- ) {
203- // Incremental builds: only copy files that are likely affected by the changes
204- console . log (
205- "🔥 Incremental build - copying only relevant files for:" ,
206- message . changedFiles ,
207- ) ;
208-
209- const filesToCopy = this . getIncrementalFilesToCopy (
210- message . emittedFiles ,
211- message . changedFiles ,
212- ) ;
213- console . log ( "🔥 Incremental build - files to copy:" , filesToCopy ) ;
214-
215158 this . copyViteBundleToNative ( distOutput , destDir , filesToCopy ) ;
216159 } else {
217160 if ( debugLog ) {
218- console . log ( "🔥 Full build - copying all files" ) ;
161+ console . log ( "Full build - copying all files. " ) ;
219162 }
220163 this . copyViteBundleToNative ( distOutput , destDir ) ;
221164 }
@@ -254,31 +197,14 @@ export class BundlerCompilerService
254197 this . $logger . info (
255198 `Vite build completed! Files copied to native platform.` ,
256199 ) ;
257- // Send HMR notification to connected WebSocket clients first
258- this . notifyHMRClients ( {
259- type : message . isHMR ? "js-update" : "build-complete" ,
260- timestamp : Date . now ( ) ,
261- changedFiles : message . changedFiles || [ ] ,
262- buildType : message . buildType || "incremental" ,
263- isHMR : message . isHMR || false ,
264- } ) ;
265-
266- if ( message . isHMR ) {
267- if ( debugLog ) {
268- console . log (
269- "🔥 Skipping BUNDLER_COMPILATION_COMPLETE for HMR update - app will not restart" ,
270- ) ;
271- }
272- } else {
273- // Only emit BUNDLER_COMPILATION_COMPLETE for non-HMR builds
274- // This prevents the CLI from restarting the app during HMR updates
275- if ( debugLog ) {
276- console . log (
277- "🔥 Emitting BUNDLER_COMPILATION_COMPLETE for full build" ,
278- ) ;
279- }
280- this . emit ( BUNDLER_COMPILATION_COMPLETE , data ) ;
200+
201+ if ( debugLog ) {
202+ console . log (
203+ "Emitting BUNDLER_COMPILATION_COMPLETE for full build." ,
204+ ) ;
281205 }
206+ this . emit ( BUNDLER_COMPILATION_COMPLETE , data ) ;
207+
282208 return ;
283209 }
284210
@@ -548,7 +474,7 @@ export class BundlerCompilerService
548474 const args = [
549475 ...additionalNodeArgs ,
550476 this . getBundlerExecutablePath ( projectData ) ,
551- isVite ? "build" : this . isModernBundler ( projectData ) ? ` build` : null ,
477+ isVite || this . isModernBundler ( projectData ) ? " build" : null ,
552478 `--config=${ projectData . bundlerConfigPath } ` ,
553479 ...envParams ,
554480 ] . filter ( Boolean ) ;
@@ -928,55 +854,53 @@ export class BundlerCompilerService
928854 ) {
929855 // Clean and copy Vite output to native platform folder
930856 if ( debugLog ) {
931- console . log ( `Copying Vite bundle from "${ distOutput } " to "${ destDir } "` ) ;
857+ console . log ( `Copying Vite bundle from "${ distOutput } " to "${ destDir } ". ` ) ;
932858 }
933859
934- const fs = require ( "fs" ) ;
935-
936860 try {
937861 if ( specificFiles ) {
938- // Selective mode: only copy specific files (HMR or incremental)
862+ // Selective mode: only copy specific files (incremental)
939863 if ( debugLog ) {
940864 console . log (
941- "🔥 Selective copy - copying specific files:" ,
865+ "Selective copy - copying specific files:" ,
942866 specificFiles ,
943867 ) ;
944868 }
945869
946870 // Ensure destination directory exists
947- fs . mkdirSync ( destDir , { recursive : true } ) ;
871+ mkdirSync ( destDir , { recursive : true } ) ;
948872
949873 // Copy only the specified files
950874 for ( const file of specificFiles ) {
951875 const srcPath = path . join ( distOutput , file ) ;
952876 const destPath = path . join ( destDir , file ) ;
953877
954- if ( ! fs . existsSync ( srcPath ) ) continue ;
878+ if ( ! existsSync ( srcPath ) ) continue ;
955879
956880 // create parent dirs
957- fs . mkdirSync ( path . dirname ( destPath ) , { recursive : true } ) ;
881+ mkdirSync ( path . dirname ( destPath ) , { recursive : true } ) ;
958882
959- fs . copyFileSync ( srcPath , destPath ) ;
883+ copyFileSync ( srcPath , destPath ) ;
960884
961885 if ( debugLog ) {
962- console . log ( `🔥 Copied ${ file } ` ) ;
886+ console . log ( `Copied ${ file } ` ) ;
963887 }
964888 }
965889 } else {
966890 // Full build mode: clean and copy everything
967891 if ( debugLog ) {
968- console . log ( "🔥 Full build: Copying all files" ) ;
892+ console . log ( "Full build: Copying all files. " ) ;
969893 }
970894
971895 // Clean destination directory
972- if ( fs . existsSync ( destDir ) ) {
973- fs . rmSync ( destDir , { recursive : true , force : true } ) ;
896+ if ( existsSync ( destDir ) ) {
897+ rmSync ( destDir , { recursive : true , force : true } ) ;
974898 }
975- fs . mkdirSync ( destDir , { recursive : true } ) ;
899+ mkdirSync ( destDir , { recursive : true } ) ;
976900
977901 // Copy all files from dist to platform destination
978- if ( fs . existsSync ( distOutput ) ) {
979- this . copyRecursiveSync ( distOutput , destDir , fs ) ;
902+ if ( existsSync ( distOutput ) ) {
903+ this . copyRecursiveSync ( distOutput , destDir ) ;
980904 } else {
981905 this . $logger . warn (
982906 `Vite output directory does not exist: ${ distOutput } ` ,
@@ -988,100 +912,48 @@ export class BundlerCompilerService
988912 }
989913 }
990914
991- private getIncrementalFilesToCopy (
992- emittedFiles : string [ ] ,
993- changedFiles : string [ ] ,
994- ) : string [ ] {
915+ private getIncrementalFilesToCopy ( emittedFiles : string [ ] ) : string [ ] {
995916 // For incremental builds, we need to determine which emitted files are likely affected
996917 // by the source file changes
997918
998919 const filesToCopy : string [ ] = [ ] ;
999920
1000- // Always copy bundle files as they contain the compiled source code
1001- // ignoring vendor files as they are less likely to change frequently
921+ // default to ignoring vendor files as they are less likely to change during live reloads
1002922 const bundleFiles = emittedFiles . filter (
1003923 ( file ) =>
1004924 ! file . includes ( "vendor" ) &&
1005- ( file . includes ( "bundle" ) ||
1006- file . includes ( "main" ) ||
1007- file . includes ( "app" ) ||
1008- file . endsWith ( ".mjs" ) ||
1009- file . endsWith ( ".js" ) ) ,
925+ ( file . endsWith ( ".mjs" ) ||
926+ file . endsWith ( ".js" ) ||
927+ file . endsWith ( ".map" ) ) ,
1010928 ) ;
1011929 filesToCopy . push ( ...bundleFiles ) ;
1012930
1013- // Always copy source maps for debugging
1014- const sourceMapFiles = emittedFiles . filter (
1015- ( file ) => ! file . includes ( "vendor" ) && file . endsWith ( ".map" ) ,
1016- ) ;
1017- filesToCopy . push ( ...sourceMapFiles ) ;
1018-
1019- // Only handle assets if they're explicitly referenced in the changed files
1020- const hasAssetChanges = changedFiles . some (
931+ // Only copy assets if there are explicit asset-related changes
932+ const assetFiles = emittedFiles . filter (
1021933 ( file ) =>
1022- file . includes ( "/assets/" ) ||
1023- file . includes ( "/static/" ) ||
1024- file . includes ( "/public/" ) ,
934+ file . includes ( "assets/" ) ||
935+ file . includes ( "static/" ) ||
936+ file . includes ( "fonts/" ) ||
937+ file . includes ( "images/" ) ,
1025938 ) ;
1026-
1027- if ( hasAssetChanges ) {
1028- // Only copy assets if there are explicit asset-related changes
1029- const assetFiles = emittedFiles . filter (
1030- ( file ) =>
1031- file . includes ( "assets/" ) ||
1032- file . includes ( "static/" ) ||
1033- file . includes ( "fonts/" ) ||
1034- file . includes ( "images/" ) ,
1035- ) ;
939+ if ( assetFiles . length > 0 ) {
1036940 filesToCopy . push ( ...assetFiles ) ;
1037941 }
1038942
1039943 // Remove duplicates and return
1040944 return [ ...new Set ( filesToCopy ) ] ;
1041945 }
1042946
1043- private notifyHMRClients ( message : any ) {
1044- // Send WebSocket notification to HMR clients
1045- try {
1046- const WebSocket = require ( "ws" ) ;
1047-
1048- // Try to connect to HMR bridge and send notification
1049- const ws = new WebSocket ( "ws://localhost:24678" ) ;
1050-
1051- ws . on ( "open" , ( ) => {
1052- if ( debugLog ) {
1053- console . log ( "🔥 Sending HMR notification to bridge:" , message . type ) ;
1054- }
1055- ws . send ( JSON . stringify ( message ) ) ;
1056- ws . close ( ) ;
1057- } ) ;
1058-
1059- ws . on ( "error" , ( ) => {
1060- // HMR bridge not available, which is fine
1061- if ( debugLog ) {
1062- console . log (
1063- "🔥 HMR bridge not available (this is normal without HMR)" ,
1064- ) ;
1065- }
1066- } ) ;
1067- } catch ( error ) {
1068- // WebSocket not available, which is fine
1069- if ( debugLog ) {
1070- console . log ( "🔥 WebSocket not available for HMR notifications" ) ;
1071- }
1072- }
1073- }
1074-
1075- private copyRecursiveSync ( src : string , dest : string , fs : any ) {
1076- for ( const entry of fs . readdirSync ( src , { withFileTypes : true } ) ) {
947+ private copyRecursiveSync ( src : string , dest : string ) {
948+ for ( const entry of readdirSync ( src , { withFileTypes : true } ) ) {
1077949 const srcPath = path . join ( src , entry . name ) ;
1078950 const destPath = path . join ( dest , entry . name ) ;
1079951
1080952 if ( entry . isDirectory ( ) ) {
1081- fs . mkdirSync ( destPath , { recursive : true } ) ;
1082- this . copyRecursiveSync ( srcPath , destPath , fs ) ;
953+ mkdirSync ( destPath , { recursive : true } ) ;
954+ this . copyRecursiveSync ( srcPath , destPath ) ;
1083955 } else if ( entry . isFile ( ) || entry . isSymbolicLink ( ) ) {
1084- fs . copyFileSync ( srcPath , destPath ) ;
956+ copyFileSync ( srcPath , destPath ) ;
1085957 }
1086958 }
1087959 }
0 commit comments