1- const { join, relative, resolve, sep } = require ( "path" ) ;
1+ const { join, relative, resolve, sep, dirname } = require ( "path" ) ;
22
33const webpack = require ( "webpack" ) ;
44const nsWebpack = require ( "nativescript-dev-webpack" ) ;
55const nativescriptTarget = require ( "nativescript-dev-webpack/nativescript-target" ) ;
6+ const { nsReplaceBootstrap } = require ( "nativescript-dev-webpack/transformers/ns-replace-bootstrap" ) ;
7+ const { nsReplaceLazyLoader } = require ( "nativescript-dev-webpack/transformers/ns-replace-lazy-loader" ) ;
8+ const { nsSupportHmrNg } = require ( "nativescript-dev-webpack/transformers/ns-support-hmr-ng" ) ;
9+ const { getMainModulePath } = require ( "nativescript-dev-webpack/utils/ast-utils" ) ;
610const CleanWebpackPlugin = require ( "clean-webpack-plugin" ) ;
711const CopyWebpackPlugin = require ( "copy-webpack-plugin" ) ;
812const { BundleAnalyzerPlugin } = require ( "webpack-bundle-analyzer" ) ;
913const { NativeScriptWorkerPlugin } = require ( "nativescript-worker-loader/NativeScriptWorkerPlugin" ) ;
1014const UglifyJsPlugin = require ( "uglifyjs-webpack-plugin" ) ;
15+ const { AngularCompilerPlugin } = require ( "@ngtools/webpack" ) ;
1116
1217module . exports = env => {
1318 // Add your custom Activities, Services and other Android app components here.
@@ -21,9 +26,7 @@ module.exports = env => {
2126 throw new Error ( "You need to provide a target platform!" ) ;
2227 }
2328
24- const platforms = [ "ios" , "android" ] ;
2529 const projectRoot = __dirname ;
26- nsWebpack . loadAdditionalPlugins ( { projectDir : projectRoot } ) ;
2730
2831 // Default destination inside platforms/<platform>/...
2932 const dist = resolve ( projectRoot , nsWebpack . getAppPath ( platform , projectRoot ) ) ;
@@ -33,27 +36,62 @@ module.exports = env => {
3336 // The 'appPath' and 'appResourcesPath' values are fetched from
3437 // the nsconfig.json configuration file
3538 // when bundling with `tns run android|ios --bundle`.
36- appPath = "app " ,
37- appResourcesPath = "app/ App_Resources" ,
39+ appPath = "src " ,
40+ appResourcesPath = "App_Resources" ,
3841
3942 // You can provide the following flags when running 'tns run android|ios'
4043 aot, // --env.aot
4144 snapshot, // --env.snapshot
4245 uglify, // --env.uglify
4346 report, // --env.report
47+ sourceMap, // --env.sourceMap
48+ hmr, // --env.hmr,
4449 } = env ;
4550
51+ const externals = nsWebpack . getConvertedExternals ( env . externals ) ;
4652 const appFullPath = resolve ( projectRoot , appPath ) ;
4753 const appResourcesFullPath = resolve ( projectRoot , appResourcesPath ) ;
48-
49- const entryModule = aot ?
50- nsWebpack . getAotEntryModule ( appFullPath ) :
51- `${ nsWebpack . getEntryModule ( appFullPath ) } .ts` ;
54+ const tsConfigName = "tsconfig.tns.json" ;
55+ const entryModule = `${ nsWebpack . getEntryModule ( appFullPath ) } .ts` ;
5256 const entryPath = `.${ sep } ${ entryModule } ` ;
57+ const ngCompilerTransformers = [ ] ;
58+ const additionalLazyModuleResources = [ ] ;
59+ if ( aot ) {
60+ ngCompilerTransformers . push ( nsReplaceBootstrap ) ;
61+ }
62+
63+ if ( hmr ) {
64+ ngCompilerTransformers . push ( nsSupportHmrNg ) ;
65+ }
66+
67+ // when "@angular/core" is external, it's not included in the bundles. In this way, it will be used
68+ // directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes
69+ // fixes https://github.com/NativeScript/nativescript-cli/issues/4024
70+ if ( env . externals && env . externals . indexOf ( "@angular/core" ) > - 1 ) {
71+ const appModuleRelativePath = getMainModulePath ( resolve ( appFullPath , entryModule ) , tsConfigName ) ;
72+ if ( appModuleRelativePath ) {
73+ const appModuleFolderPath = dirname ( resolve ( appFullPath , appModuleRelativePath ) ) ;
74+ // include the lazy loader inside app module
75+ ngCompilerTransformers . push ( nsReplaceLazyLoader ) ;
76+ // include the new lazy loader path in the allowed ones
77+ additionalLazyModuleResources . push ( appModuleFolderPath ) ;
78+ }
79+ }
80+
81+ const ngCompilerPlugin = new AngularCompilerPlugin ( {
82+ hostReplacementPaths : nsWebpack . getResolver ( [ platform , "tns" ] ) ,
83+ platformTransformers : ngCompilerTransformers . map ( t => t ( ( ) => ngCompilerPlugin , resolve ( appFullPath , entryModule ) ) ) ,
84+ mainPath : resolve ( appPath , entryModule ) ,
85+ tsConfigPath : join ( __dirname , tsConfigName ) ,
86+ skipCodeGeneration : ! aot ,
87+ sourceMap : ! ! sourceMap ,
88+ additionalLazyModuleResources : additionalLazyModuleResources
89+ } ) ;
5390
5491 const config = {
5592 mode : uglify ? "production" : "development" ,
5693 context : appFullPath ,
94+ externals,
5795 watchOptions : {
5896 ignored : [
5997 appResourcesFullPath ,
@@ -97,7 +135,7 @@ module.exports = env => {
97135 "fs" : "empty" ,
98136 "__dirname" : false ,
99137 } ,
100- devtool : "none" ,
138+ devtool : sourceMap ? "inline-source-map" : "none" ,
101139 optimization : {
102140 splitChunks : {
103141 cacheGroups : {
@@ -107,7 +145,7 @@ module.exports = env => {
107145 test : ( module , chunks ) => {
108146 const moduleName = module . nameForCondition ? module . nameForCondition ( ) : '' ;
109147 return / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / . test ( moduleName ) ||
110- appComponents . some ( comp => comp === moduleName ) ;
148+ appComponents . some ( comp => comp === moduleName ) ;
111149 } ,
112150 enforce : true ,
113151 } ,
@@ -116,9 +154,9 @@ module.exports = env => {
116154 minimize : ! ! uglify ,
117155 minimizer : [
118156 new UglifyJsPlugin ( {
157+ parallel : true ,
158+ cache : true ,
119159 uglifyOptions : {
120- parallel : true ,
121- cache : true ,
122160 output : {
123161 comments : false ,
124162 } ,
@@ -146,7 +184,7 @@ module.exports = env => {
146184 {
147185 loader : "nativescript-dev-webpack/bundle-config-loader" ,
148186 options : {
149- registerPages : false ,
187+ angular : true ,
150188 loadCss : ! snapshot , // load the application css if in debug mode
151189 }
152190 } ,
@@ -158,14 +196,15 @@ module.exports = env => {
158196 // tns-core-modules reads the app.css and its imports using css-loader
159197 {
160198 test : / [ \/ | \\ ] a p p \. c s s $ / ,
161- use : {
162- loader : "css -loader",
163- options : { minimize : false , url : false } ,
164- }
199+ use : [
200+ "nativescript-dev-webpack/style-hot -loader",
201+ { loader : "css-loader" , options : { minimize : false , url : false } }
202+ ]
165203 } ,
166204 {
167205 test : / [ \/ | \\ ] a p p \. s c s s $ / ,
168206 use : [
207+ "nativescript-dev-webpack/style-hot-loader" ,
169208 { loader : "css-loader" , options : { minimize : false , url : false } } ,
170209 "sass-loader"
171210 ]
@@ -175,10 +214,11 @@ module.exports = env => {
175214 { test : / \. c s s $ / , exclude : / [ \/ | \\ ] a p p \. c s s $ / , use : "raw-loader" } ,
176215 { test : / \. s c s s $ / , exclude : / [ \/ | \\ ] a p p \. s c s s $ / , use : [ "raw-loader" , "resolve-url-loader" , "sass-loader" ] } ,
177216
178- // Compile TypeScript files with ahead-of-time compiler.
179217 {
180- test : / .t s $ / , use : [
218+ test : / (?: \. n g f a c t o r y \. j s | \. n g s t y l e \. j s | \. t s ) $ / ,
219+ use : [
181220 "nativescript-dev-webpack/moduleid-compat-loader" ,
221+ "nativescript-dev-webpack/lazy-ngmodule-hot-loader" ,
182222 "@ngtools/webpack" ,
183223 ]
184224 } ,
@@ -195,9 +235,10 @@ module.exports = env => {
195235 // Define useful constants like TNS_WEBPACK
196236 new webpack . DefinePlugin ( {
197237 "global.TNS_WEBPACK" : "true" ,
238+ "process" : undefined ,
198239 } ) ,
199240 // Remove all files from the out dir.
200- new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
241+ new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
201242 // Copy native app resources to out dir.
202243 new CopyWebpackPlugin ( [
203244 {
@@ -208,9 +249,9 @@ module.exports = env => {
208249 ] ) ,
209250 // Copy assets to out dir. Add your own globs as needed.
210251 new CopyWebpackPlugin ( [
211- { from : "fonts/**" } ,
212- { from : "**/*.jpg" } ,
213- { from : "**/*.png" } ,
252+ { from : { glob : "fonts/**" } } ,
253+ { from : { glob : "**/*.jpg" } } ,
254+ { from : { glob : "**/*.png" } } ,
214255 ] , { ignore : [ `${ relative ( appPath , appResourcesFullPath ) } /**` ] } ) ,
215256 // Generate a bundle starter script and activate it in package.json
216257 new nsWebpack . GenerateBundleStarterPlugin ( [
@@ -220,21 +261,13 @@ module.exports = env => {
220261 // For instructions on how to set up workers with webpack
221262 // check out https://github.com/nativescript/worker-loader
222263 new NativeScriptWorkerPlugin ( ) ,
223- // AngularCompilerPlugin with augmented NativeScript filesystem to handle platform specific resource resolution.
224- new nsWebpack . NativeScriptAngularCompilerPlugin ( {
225- entryModule : resolve ( appPath , "app.module#AppModule" ) ,
226- tsConfigPath : join ( __dirname , "tsconfig.esm.json" ) ,
227- skipCodeGeneration : ! aot ,
228- platformOptions : {
229- platform,
230- platforms,
231- } ,
232- } ) ,
264+ ngCompilerPlugin ,
233265 // Does IPC communication with the {N} CLI to notify events when running in watch mode.
234266 new nsWebpack . WatchStateLoggerPlugin ( ) ,
235267 ] ,
236268 } ;
237269
270+
238271 if ( report ) {
239272 // Generate report files for bundles content
240273 config . plugins . push ( new BundleAnalyzerPlugin ( {
@@ -249,6 +282,7 @@ module.exports = env => {
249282 if ( snapshot ) {
250283 config . plugins . push ( new nsWebpack . NativeScriptSnapshotPlugin ( {
251284 chunk : "vendor" ,
285+ angular : true ,
252286 requireModules : [
253287 "reflect-metadata" ,
254288 "@angular/platform-browser" ,
@@ -263,5 +297,9 @@ module.exports = env => {
263297 } ) ) ;
264298 }
265299
300+ if ( hmr ) {
301+ config . plugins . push ( new webpack . HotModuleReplacementPlugin ( ) ) ;
302+ }
303+
266304 return config ;
267305} ;
0 commit comments