1
- const { relative, resolve, join } = require ( "path" ) ;
1
+ const { join , relative, resolve, sep } = 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" ) ;
6
7
const CleanWebpackPlugin = require ( "clean-webpack-plugin" ) ;
7
8
const CopyWebpackPlugin = require ( "copy-webpack-plugin" ) ;
8
9
const { BundleAnalyzerPlugin } = require ( "webpack-bundle-analyzer" ) ;
9
10
const { NativeScriptWorkerPlugin } = require ( "nativescript-worker-loader/NativeScriptWorkerPlugin" ) ;
10
11
const UglifyJsPlugin = require ( "uglifyjs-webpack-plugin" ) ;
12
+ const { AngularCompilerPlugin } = require ( "@ngtools/webpack" ) ;
11
13
12
14
module . exports = env => {
15
+ // Add your custom Activities, Services and other Android app components here.
16
+ const appComponents = [
17
+ "tns-core-modules/ui/frame" ,
18
+ "tns-core-modules/ui/frame/activity" ,
19
+ ] ;
20
+
13
21
const platform = env && ( env . android && "android" || env . ios && "ios" ) ;
14
22
if ( ! platform ) {
15
23
throw new Error ( "You need to provide a target platform!" ) ;
16
24
}
17
25
18
- const platforms = [ "ios" , "android" ] ;
19
26
const projectRoot = __dirname ;
20
- nsWebpack . loadAdditionalPlugins ( { projectDir : projectRoot } ) ;
21
27
22
28
// Default destination inside platforms/<platform>/...
23
29
const dist = resolve ( projectRoot , nsWebpack . getAppPath ( platform , projectRoot ) ) ;
@@ -30,21 +36,37 @@ module.exports = env => {
30
36
appPath = "app" ,
31
37
appResourcesPath = "app/App_Resources" ,
32
38
33
- // Aot, snapshot, uglify and report can be enabled by providing
34
- // the ` --env.snapshot`, `--env.uglify` or `--env.report` flags
35
- // when running 'tns run android|ios'
36
- aot ,
37
- snapshot ,
38
- uglify ,
39
- report ,
39
+ // You can provide the following flags when running 'tns run android|ios'
40
+ aot , // --env.aot
41
+ snapshot , // --env.snapshot
42
+ uglify , // --env.uglify
43
+ report , // --env.report
44
+ sourceMap , // --env.sourceMap
45
+ hmr , // --env.hmr ,
40
46
} = env ;
41
- const ngToolsWebpackOptions = { tsConfigPath : join ( __dirname , "tsconfig.json" ) } ;
47
+ const externals = ( env . externals || [ ] ) . map ( ( e ) => { // --env.externals
48
+ return new RegExp ( e + ".*" ) ;
49
+ } ) ;
42
50
43
51
const appFullPath = resolve ( projectRoot , appPath ) ;
44
52
const appResourcesFullPath = resolve ( projectRoot , appResourcesPath ) ;
45
53
54
+ const entryModule = `${ nsWebpack . getEntryModule ( appFullPath ) } .ts` ;
55
+ const entryPath = `.${ sep } ${ entryModule } ` ;
56
+
57
+ const ngCompilerPlugin = new AngularCompilerPlugin ( {
58
+ hostReplacementPaths : nsWebpack . getResolver ( [ platform , "tns" ] ) ,
59
+ platformTransformers : aot ? [ nsReplaceBootstrap ( ( ) => ngCompilerPlugin ) ] : null ,
60
+ mainPath : resolve ( appPath , entryModule ) ,
61
+ tsConfigPath : join ( __dirname , "tsconfig.tns.json" ) ,
62
+ skipCodeGeneration : ! aot ,
63
+ sourceMap : ! ! sourceMap ,
64
+ } ) ;
65
+
46
66
const config = {
67
+ mode : uglify ? "production" : "development" ,
47
68
context : appFullPath ,
69
+ externals,
48
70
watchOptions : {
49
71
ignored : [
50
72
appResourcesFullPath ,
@@ -54,16 +76,14 @@ module.exports = env => {
54
76
} ,
55
77
target : nativescriptTarget ,
56
78
entry : {
57
- bundle : aot ?
58
- `./${ nsWebpack . getAotEntryModule ( appFullPath ) } ` :
59
- `./${ nsWebpack . getEntryModule ( appFullPath ) } ` ,
60
- vendor : "./vendor" ,
79
+ bundle : entryPath ,
61
80
} ,
62
81
output : {
63
- pathinfo : true ,
82
+ pathinfo : false ,
64
83
path : dist ,
65
84
libraryTarget : "commonjs2" ,
66
85
filename : "[name].js" ,
86
+ globalObject : "global" ,
67
87
} ,
68
88
resolve : {
69
89
extensions : [ ".ts" , ".js" , ".scss" , ".css" ] ,
@@ -88,9 +108,64 @@ module.exports = env => {
88
108
"timers" : false ,
89
109
"setImmediate" : false ,
90
110
"fs" : "empty" ,
111
+ "__dirname" : false ,
112
+ } ,
113
+ devtool : sourceMap ? "inline-source-map" : "none" ,
114
+ optimization : {
115
+ splitChunks : {
116
+ cacheGroups : {
117
+ vendor : {
118
+ name : "vendor" ,
119
+ chunks : "all" ,
120
+ test : ( module , chunks ) => {
121
+ const moduleName = module . nameForCondition ? module . nameForCondition ( ) : '' ;
122
+ return / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / . test ( moduleName ) ||
123
+ appComponents . some ( comp => comp === moduleName ) ;
124
+ } ,
125
+ enforce : true ,
126
+ } ,
127
+ }
128
+ } ,
129
+ minimize : ! ! uglify ,
130
+ minimizer : [
131
+ new UglifyJsPlugin ( {
132
+ parallel : true ,
133
+ cache : true ,
134
+ uglifyOptions : {
135
+ output : {
136
+ comments : false ,
137
+ } ,
138
+ compress : {
139
+ // The Android SBG has problems parsing the output
140
+ // when these options are enabled
141
+ 'collapse_vars' : platform !== "android" ,
142
+ sequences : platform !== "android" ,
143
+ }
144
+ }
145
+ } )
146
+ ] ,
91
147
} ,
92
148
module : {
93
149
rules : [
150
+ {
151
+ test : new RegExp ( entryPath ) ,
152
+ use : [
153
+ // Require all Android app components
154
+ platform === "android" && {
155
+ loader : "nativescript-dev-webpack/android-app-components-loader" ,
156
+ options : { modules : appComponents }
157
+ } ,
158
+
159
+ {
160
+ loader : "nativescript-dev-webpack/bundle-config-loader" ,
161
+ options : {
162
+ angular : true ,
163
+ loadCss : ! snapshot , // load the application css if in debug mode
164
+ }
165
+ } ,
166
+ ] . filter ( loader => ! ! loader )
167
+ } ,
168
+
94
169
{ test : / \. h t m l $ | \. x m l $ / , use : "raw-loader" } ,
95
170
96
171
// tns-core-modules reads the app.css and its imports using css-loader
@@ -113,62 +188,59 @@ module.exports = env => {
113
188
{ test : / \. c s s $ / , exclude : / [ \/ | \\ ] a p p \. c s s $ / , use : "raw-loader" } ,
114
189
{ test : / \. s c s s $ / , exclude : / [ \/ | \\ ] a p p \. s c s s $ / , use : [ "raw-loader" , "resolve-url-loader" , "sass-loader" ] } ,
115
190
116
- // Compile TypeScript files with ahead-of-time compiler.
117
- { test : / .t s $ / , use : [
118
- "nativescript-dev-webpack/moduleid-compat-loader" ,
119
- { loader : "@ngtools/webpack" , options : ngToolsWebpackOptions } ,
120
- ] } ,
191
+ {
192
+ test : / (?: \. n g f a c t o r y \. j s | \. n g s t y l e \. j s | \. t s ) $ / ,
193
+ use : [
194
+ "nativescript-dev-webpack/moduleid-compat-loader" ,
195
+ "@ngtools/webpack" ,
196
+ ]
197
+ } ,
198
+
199
+ // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
200
+ // Removing this will cause deprecation warnings to appear.
201
+ {
202
+ test : / [ \/ \\ ] @ a n g u l a r [ \/ \\ ] c o r e [ \/ \\ ] .+ \. j s $ / ,
203
+ parser : { system : true } ,
204
+ } ,
121
205
] ,
122
206
} ,
123
207
plugins : [
124
- // Vendor libs go to the vendor.js chunk
125
- new webpack . optimize . CommonsChunkPlugin ( {
126
- name : [ "vendor" ] ,
127
- } ) ,
128
208
// Define useful constants like TNS_WEBPACK
129
209
new webpack . DefinePlugin ( {
130
210
"global.TNS_WEBPACK" : "true" ,
211
+ "process" : undefined ,
131
212
} ) ,
132
213
// Remove all files from the out dir.
133
- new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
214
+ new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
134
215
// Copy native app resources to out dir.
135
216
new CopyWebpackPlugin ( [
136
- {
137
- from : `${ appResourcesFullPath } /${ appResourcesPlatformDir } ` ,
138
- to : `${ dist } /App_Resources/${ appResourcesPlatformDir } ` ,
139
- context : projectRoot
140
- } ,
217
+ {
218
+ from : `${ appResourcesFullPath } /${ appResourcesPlatformDir } ` ,
219
+ to : `${ dist } /App_Resources/${ appResourcesPlatformDir } ` ,
220
+ context : projectRoot
221
+ } ,
141
222
] ) ,
142
223
// Copy assets to out dir. Add your own globs as needed.
143
224
new CopyWebpackPlugin ( [
144
- { from : "fonts/**" } ,
145
- { from : "**/*.jpg" } ,
146
- { from : "**/*.png" } ,
147
- { from : "**/*.xml" } ,
225
+ { from : { glob : "fonts/**" } } ,
226
+ { from : { glob : "**/*.jpg" } } ,
227
+ { from : { glob : "**/*.png" } } ,
148
228
] , { ignore : [ `${ relative ( appPath , appResourcesFullPath ) } /**` ] } ) ,
149
229
// Generate a bundle starter script and activate it in package.json
150
230
new nsWebpack . GenerateBundleStarterPlugin ( [
151
231
"./vendor" ,
152
232
"./bundle" ,
153
233
] ) ,
154
- // Support for web workers since v3.2
234
+ // For instructions on how to set up workers with webpack
235
+ // check out https://github.com/nativescript/worker-loader
155
236
new NativeScriptWorkerPlugin ( ) ,
156
- // AngularCompilerPlugin with augmented NativeScript filesystem to handle platform specific resource resolution.
157
- new nsWebpack . NativeScriptAngularCompilerPlugin (
158
- Object . assign ( {
159
- entryModule : resolve ( appPath , "app.module#AppModule" ) ,
160
- skipCodeGeneration : ! aot ,
161
- platformOptions : {
162
- platform,
163
- platforms,
164
- // ignore: ["App_Resources"]
165
- } ,
166
- } , ngToolsWebpackOptions )
167
- ) ,
237
+ ngCompilerPlugin ,
168
238
// Does IPC communication with the {N} CLI to notify events when running in watch mode.
169
239
new nsWebpack . WatchStateLoggerPlugin ( ) ,
170
240
] ,
171
241
} ;
242
+
243
+
172
244
if ( report ) {
173
245
// Generate report files for bundles content
174
246
config . plugins . push ( new BundleAnalyzerPlugin ( {
@@ -179,26 +251,28 @@ module.exports = env => {
179
251
statsFilename : resolve ( projectRoot , "report" , `stats.json` ) ,
180
252
} ) ) ;
181
253
}
254
+
182
255
if ( snapshot ) {
183
256
config . plugins . push ( new nsWebpack . NativeScriptSnapshotPlugin ( {
184
257
chunk : "vendor" ,
258
+ angular : true ,
259
+ requireModules : [
260
+ "reflect-metadata" ,
261
+ "@angular/platform-browser" ,
262
+ "@angular/core" ,
263
+ "@angular/common" ,
264
+ "@angular/router" ,
265
+ "nativescript-angular/platform-static" ,
266
+ "nativescript-angular/router" ,
267
+ ] ,
185
268
projectRoot,
186
269
webpackConfig : config ,
187
- targetArchs : [ "arm" , "arm64" , "ia32" ] ,
188
- tnsJavaClassesOptions : { packages : [ "tns-core-modules" ] } ,
189
- useLibs : false
190
270
} ) ) ;
191
271
}
192
- if ( uglify ) {
193
- config . plugins . push ( new webpack . LoaderOptionsPlugin ( { minimize : true } ) ) ;
194
-
195
- // Work around an Android issue by setting compress = false
196
- const compress = platform !== "android" ;
197
- config . plugins . push ( new UglifyJsPlugin ( {
198
- uglifyOptions : {
199
- compress,
200
- }
201
- } ) ) ;
272
+
273
+ if ( hmr ) {
274
+ config . plugins . push ( new webpack . HotModuleReplacementPlugin ( ) ) ;
202
275
}
276
+
203
277
return config ;
204
278
} ;
0 commit comments