1
- const { join, relative, resolve, sep } = require ( "path" ) ;
1
+ const { join, relative, resolve, sep, dirname } = require ( "path" ) ;
2
2
3
3
const webpack = require ( "webpack" ) ;
4
4
const nsWebpack = require ( "nativescript-dev-webpack" ) ;
5
5
const 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" ) ;
6
10
const CleanWebpackPlugin = require ( "clean-webpack-plugin" ) ;
7
11
const CopyWebpackPlugin = require ( "copy-webpack-plugin" ) ;
8
12
const { BundleAnalyzerPlugin } = require ( "webpack-bundle-analyzer" ) ;
9
13
const { NativeScriptWorkerPlugin } = require ( "nativescript-worker-loader/NativeScriptWorkerPlugin" ) ;
10
14
const UglifyJsPlugin = require ( "uglifyjs-webpack-plugin" ) ;
15
+ const { AngularCompilerPlugin } = require ( "@ngtools/webpack" ) ;
11
16
12
17
module . exports = env => {
13
18
// Add your custom Activities, Services and other Android app components here.
@@ -21,9 +26,7 @@ module.exports = env => {
21
26
throw new Error ( "You need to provide a target platform!" ) ;
22
27
}
23
28
24
- const platforms = [ "ios" , "android" ] ;
25
29
const projectRoot = __dirname ;
26
- nsWebpack . loadAdditionalPlugins ( { projectDir : projectRoot } ) ;
27
30
28
31
// Default destination inside platforms/<platform>/...
29
32
const dist = resolve ( projectRoot , nsWebpack . getAppPath ( platform , projectRoot ) ) ;
@@ -33,27 +36,62 @@ module.exports = env => {
33
36
// The 'appPath' and 'appResourcesPath' values are fetched from
34
37
// the nsconfig.json configuration file
35
38
// when bundling with `tns run android|ios --bundle`.
36
- appPath = "app " ,
37
- appResourcesPath = "app/ App_Resources" ,
39
+ appPath = "src " ,
40
+ appResourcesPath = "App_Resources" ,
38
41
39
42
// You can provide the following flags when running 'tns run android|ios'
40
43
aot, // --env.aot
41
44
snapshot, // --env.snapshot
42
45
uglify, // --env.uglify
43
46
report, // --env.report
47
+ sourceMap, // --env.sourceMap
48
+ hmr, // --env.hmr,
44
49
} = env ;
45
50
51
+ const externals = nsWebpack . getConvertedExternals ( env . externals ) ;
46
52
const appFullPath = resolve ( projectRoot , appPath ) ;
47
53
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` ;
52
56
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
+ } ) ;
53
90
54
91
const config = {
55
92
mode : uglify ? "production" : "development" ,
56
93
context : appFullPath ,
94
+ externals,
57
95
watchOptions : {
58
96
ignored : [
59
97
appResourcesFullPath ,
@@ -97,7 +135,7 @@ module.exports = env => {
97
135
"fs" : "empty" ,
98
136
"__dirname" : false ,
99
137
} ,
100
- devtool : "none" ,
138
+ devtool : sourceMap ? "inline-source-map" : "none" ,
101
139
optimization : {
102
140
splitChunks : {
103
141
cacheGroups : {
@@ -107,7 +145,7 @@ module.exports = env => {
107
145
test : ( module , chunks ) => {
108
146
const moduleName = module . nameForCondition ? module . nameForCondition ( ) : '' ;
109
147
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 ) ;
111
149
} ,
112
150
enforce : true ,
113
151
} ,
@@ -116,9 +154,9 @@ module.exports = env => {
116
154
minimize : ! ! uglify ,
117
155
minimizer : [
118
156
new UglifyJsPlugin ( {
157
+ parallel : true ,
158
+ cache : true ,
119
159
uglifyOptions : {
120
- parallel : true ,
121
- cache : true ,
122
160
output : {
123
161
comments : false ,
124
162
} ,
@@ -146,7 +184,7 @@ module.exports = env => {
146
184
{
147
185
loader : "nativescript-dev-webpack/bundle-config-loader" ,
148
186
options : {
149
- registerPages : false ,
187
+ angular : true ,
150
188
loadCss : ! snapshot , // load the application css if in debug mode
151
189
}
152
190
} ,
@@ -158,14 +196,15 @@ module.exports = env => {
158
196
// tns-core-modules reads the app.css and its imports using css-loader
159
197
{
160
198
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
+ ]
165
203
} ,
166
204
{
167
205
test : / [ \/ | \\ ] a p p \. s c s s $ / ,
168
206
use : [
207
+ "nativescript-dev-webpack/style-hot-loader" ,
169
208
{ loader : "css-loader" , options : { minimize : false , url : false } } ,
170
209
"sass-loader"
171
210
]
@@ -175,10 +214,11 @@ module.exports = env => {
175
214
{ test : / \. c s s $ / , exclude : / [ \/ | \\ ] a p p \. c s s $ / , use : "raw-loader" } ,
176
215
{ test : / \. s c s s $ / , exclude : / [ \/ | \\ ] a p p \. s c s s $ / , use : [ "raw-loader" , "resolve-url-loader" , "sass-loader" ] } ,
177
216
178
- // Compile TypeScript files with ahead-of-time compiler.
179
217
{
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 : [
181
220
"nativescript-dev-webpack/moduleid-compat-loader" ,
221
+ "nativescript-dev-webpack/lazy-ngmodule-hot-loader" ,
182
222
"@ngtools/webpack" ,
183
223
]
184
224
} ,
@@ -195,9 +235,10 @@ module.exports = env => {
195
235
// Define useful constants like TNS_WEBPACK
196
236
new webpack . DefinePlugin ( {
197
237
"global.TNS_WEBPACK" : "true" ,
238
+ "process" : undefined ,
198
239
} ) ,
199
240
// Remove all files from the out dir.
200
- new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
241
+ new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
201
242
// Copy native app resources to out dir.
202
243
new CopyWebpackPlugin ( [
203
244
{
@@ -208,9 +249,9 @@ module.exports = env => {
208
249
] ) ,
209
250
// Copy assets to out dir. Add your own globs as needed.
210
251
new CopyWebpackPlugin ( [
211
- { from : "fonts/**" } ,
212
- { from : "**/*.jpg" } ,
213
- { from : "**/*.png" } ,
252
+ { from : { glob : "fonts/**" } } ,
253
+ { from : { glob : "**/*.jpg" } } ,
254
+ { from : { glob : "**/*.png" } } ,
214
255
] , { ignore : [ `${ relative ( appPath , appResourcesFullPath ) } /**` ] } ) ,
215
256
// Generate a bundle starter script and activate it in package.json
216
257
new nsWebpack . GenerateBundleStarterPlugin ( [
@@ -220,21 +261,13 @@ module.exports = env => {
220
261
// For instructions on how to set up workers with webpack
221
262
// check out https://github.com/nativescript/worker-loader
222
263
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 ,
233
265
// Does IPC communication with the {N} CLI to notify events when running in watch mode.
234
266
new nsWebpack . WatchStateLoggerPlugin ( ) ,
235
267
] ,
236
268
} ;
237
269
270
+
238
271
if ( report ) {
239
272
// Generate report files for bundles content
240
273
config . plugins . push ( new BundleAnalyzerPlugin ( {
@@ -249,6 +282,7 @@ module.exports = env => {
249
282
if ( snapshot ) {
250
283
config . plugins . push ( new nsWebpack . NativeScriptSnapshotPlugin ( {
251
284
chunk : "vendor" ,
285
+ angular : true ,
252
286
requireModules : [
253
287
"reflect-metadata" ,
254
288
"@angular/platform-browser" ,
@@ -263,5 +297,9 @@ module.exports = env => {
263
297
} ) ) ;
264
298
}
265
299
300
+ if ( hmr ) {
301
+ config . plugins . push ( new webpack . HotModuleReplacementPlugin ( ) ) ;
302
+ }
303
+
266
304
return config ;
267
305
} ;
0 commit comments