1+ const { relative, resolve, sep } = require ( "path" ) ;
2+
3+ const webpack = require ( "webpack" ) ;
4+ const CleanWebpackPlugin = require ( "clean-webpack-plugin" ) ;
5+ const CopyWebpackPlugin = require ( "copy-webpack-plugin" ) ;
6+ const { BundleAnalyzerPlugin } = require ( "webpack-bundle-analyzer" ) ;
7+ const UglifyJsPlugin = require ( "uglifyjs-webpack-plugin" ) ;
8+
9+ const VueLoaderPlugin = require ( 'vue-loader/lib/plugin' ) ;
10+ const NsVueTemplateCompiler = require ( "nativescript-vue-template-compiler" ) ;
11+
12+ const nsWebpack = require ( "nativescript-dev-webpack" ) ;
13+ const nativescriptTarget = require ( "nativescript-dev-webpack/nativescript-target" ) ;
14+ const { NativeScriptWorkerPlugin } = require ( "nativescript-worker-loader/NativeScriptWorkerPlugin" ) ;
15+
16+ module . exports = env => {
17+ // Add your custom Activities, Services and other android app components here.
18+ const appComponents = [
19+ "tns-core-modules/ui/frame" ,
20+ "tns-core-modules/ui/frame/activity" ,
21+ ] ;
22+
23+ const platform = env && ( env . android && "android" || env . ios && "ios" ) ;
24+ if ( ! platform ) {
25+ throw new Error ( "You need to provide a target platform!" ) ;
26+ }
27+
28+ const platforms = [ "ios" , "android" ] ;
29+ const projectRoot = __dirname ;
30+
31+ // Default destination inside platforms/<platform>/...
32+ const dist = resolve ( projectRoot , nsWebpack . getAppPath ( platform , projectRoot ) ) ;
33+ const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS" ;
34+
35+ const {
36+ // The 'appPath' and 'appResourcesPath' values are fetched from
37+ // the nsconfig.json configuration file
38+ // when bundling with `tns run android|ios --bundle`.
39+ appPath = "app" ,
40+ appResourcesPath = "app/App_Resources" ,
41+
42+ // You can provide the following flags when running 'tns run android|ios'
43+ snapshot, // --env.snapshot
44+ production, // --env.production
45+ report, // --env.report
46+ hmr, // --env.hmr
47+ } = env ;
48+
49+ const externals = ( env . externals || [ ] ) . map ( ( e ) => { // --env.externals
50+ return new RegExp ( e + ".*" ) ;
51+ } ) ;
52+
53+ const mode = production ? "production" : "development"
54+
55+ const appFullPath = resolve ( projectRoot , appPath ) ;
56+ const appResourcesFullPath = resolve ( projectRoot , appResourcesPath ) ;
57+
58+ const entryModule = nsWebpack . getEntryModule ( appFullPath ) ;
59+ const entryPath = `.${ sep } ${ entryModule } .js` ;
60+ console . log ( `Bundling application for entryPath ${ entryPath } ...` ) ;
61+
62+ const config = {
63+ mode : mode ,
64+ context : appFullPath ,
65+ externals,
66+ watchOptions : {
67+ ignored : [
68+ appResourcesFullPath ,
69+ // Don't watch hidden files
70+ "**/.*" ,
71+ ] ,
72+ } ,
73+ target : nativescriptTarget ,
74+ // target: nativeScriptVueTarget,
75+ entry : {
76+ bundle : entryPath ,
77+ } ,
78+ output : {
79+ pathinfo : false ,
80+ path : dist ,
81+ libraryTarget : "commonjs2" ,
82+ filename : "[name].js" ,
83+ globalObject : "global" ,
84+ } ,
85+ resolve : {
86+ extensions : [ ".vue" , ".js" , ".scss" , ".css" ] ,
87+ // Resolve {N} system modules from tns-core-modules
88+ modules : [
89+ resolve ( __dirname , "node_modules/tns-core-modules" ) ,
90+ resolve ( __dirname , "node_modules" ) ,
91+ "node_modules/tns-core-modules" ,
92+ "node_modules" ,
93+ ] ,
94+ alias : {
95+ '~' : appFullPath ,
96+ '@' : appFullPath ,
97+ 'vue' : 'nativescript-vue'
98+ } ,
99+ // don't resolve symlinks to symlinked modules
100+ symlinks : false ,
101+ } ,
102+ resolveLoader : {
103+ // don't resolve symlinks to symlinked loaders
104+ symlinks : false ,
105+ } ,
106+ node : {
107+ // Disable node shims that conflict with NativeScript
108+ "http" : false ,
109+ "timers" : false ,
110+ "setImmediate" : false ,
111+ "fs" : "empty" ,
112+ "__dirname" : false ,
113+ } ,
114+ devtool : "none" ,
115+ optimization : {
116+ splitChunks : {
117+ cacheGroups : {
118+ vendor : {
119+ name : "vendor" ,
120+ chunks : "all" ,
121+ test : ( module ) => {
122+ const moduleName = module . nameForCondition ? module . nameForCondition ( ) : '' ;
123+ return / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / . test ( moduleName ) ||
124+ appComponents . some ( comp => comp === moduleName ) ;
125+
126+ } ,
127+ enforce : true ,
128+ } ,
129+ } ,
130+ } ,
131+ minimize : Boolean ( production ) ,
132+ minimizer : [
133+ new UglifyJsPlugin ( {
134+ parallel : true ,
135+ cache : true ,
136+ uglifyOptions : {
137+ output : {
138+ comments : false ,
139+ } ,
140+ compress : {
141+ // The Android SBG has problems parsing the output
142+ // when these options are enabled
143+ 'collapse_vars' : platform !== "android" ,
144+ sequences : platform !== "android" ,
145+ } ,
146+ } ,
147+ } ) ,
148+ ] ,
149+ } ,
150+ module : {
151+ rules : [ {
152+ test : new RegExp ( entryPath ) ,
153+ use : [
154+ // Require all Android app components
155+ platform === "android" && {
156+ loader : "nativescript-dev-webpack/android-app-components-loader" ,
157+ options : { modules : appComponents } ,
158+ } ,
159+
160+ {
161+ loader : "nativescript-dev-webpack/bundle-config-loader" ,
162+ options : {
163+ registerPages : true , // applicable only for non-angular apps
164+ loadCss : ! snapshot , // load the application css if in debug mode
165+ } ,
166+ } ,
167+ ] . filter ( loader => Boolean ( loader ) ) ,
168+ } ,
169+ {
170+ test : / \. c s s $ / ,
171+ use : [
172+ 'nativescript-dev-webpack/style-hot-loader' ,
173+ 'nativescript-dev-webpack/apply-css-loader.js' ,
174+ { loader : "css-loader" , options : { minimize : false , url : false } } ,
175+ ] ,
176+ } ,
177+ {
178+ test : / \. s c s s $ / ,
179+ use : [
180+ 'nativescript-dev-webpack/style-hot-loader' ,
181+ 'nativescript-dev-webpack/apply-css-loader.js' ,
182+ { loader : "css-loader" , options : { minimize : false , url : false } } ,
183+ "sass-loader" ,
184+ ] ,
185+ } ,
186+ {
187+ test : / \. j s $ / ,
188+ loader : 'babel-loader' ,
189+ } ,
190+ {
191+ test : / \. v u e $ / ,
192+ loader : "vue-loader" ,
193+ options : {
194+ compiler : NsVueTemplateCompiler ,
195+ } ,
196+ } ,
197+ ] ,
198+ } ,
199+ plugins : [
200+ // ... Vue Loader plugin omitted
201+ // make sure to include the plugin!
202+ new VueLoaderPlugin ( ) ,
203+ // Define useful constants like TNS_WEBPACK
204+ new webpack . DefinePlugin ( {
205+ "global.TNS_WEBPACK" : "true" ,
206+ "TNS_ENV" : JSON . stringify ( mode )
207+ } ) ,
208+ // Remove all files from the out dir.
209+ new CleanWebpackPlugin ( [ `${ dist } /**/*` ] ) ,
210+ // Copy native app resources to out dir.
211+ new CopyWebpackPlugin ( [ {
212+ from : `${ appResourcesFullPath } /${ appResourcesPlatformDir } ` ,
213+ to : `${ dist } /App_Resources/${ appResourcesPlatformDir } ` ,
214+ context : projectRoot ,
215+ } ] ) ,
216+ // Copy assets to out dir. Add your own globs as needed.
217+ new CopyWebpackPlugin ( [
218+ { from : { glob : "fonts/**" } } ,
219+ { from : { glob : "**/*.+(jpg|png)" } } ,
220+ { from : { glob : "assets/**/*" } } ,
221+ ] , { ignore : [ `${ relative ( appPath , appResourcesFullPath ) } /**` ] } ) ,
222+ // Generate a bundle starter script and activate it in package.json
223+ new nsWebpack . GenerateBundleStarterPlugin ( [
224+ "./vendor" ,
225+ "./bundle" ,
226+ ] ) ,
227+ // For instructions on how to set up workers with webpack
228+ // check out https://github.com/nativescript/worker-loader
229+ new NativeScriptWorkerPlugin ( ) ,
230+ new nsWebpack . PlatformFSPlugin ( {
231+ platform,
232+ platforms,
233+ } ) ,
234+ // Does IPC communication with the {N} CLI to notify events when running in watch mode.
235+ new nsWebpack . WatchStateLoggerPlugin ( ) ,
236+ ] ,
237+ } ;
238+
239+ if ( report ) {
240+ // Generate report files for bundles content
241+ config . plugins . push ( new BundleAnalyzerPlugin ( {
242+ analyzerMode : "static" ,
243+ openAnalyzer : false ,
244+ generateStatsFile : true ,
245+ reportFilename : resolve ( projectRoot , "report" , `report.html` ) ,
246+ statsFilename : resolve ( projectRoot , "report" , `stats.json` ) ,
247+ } ) ) ;
248+ }
249+
250+ if ( snapshot ) {
251+ config . plugins . push ( new nsWebpack . NativeScriptSnapshotPlugin ( {
252+ chunk : "vendor" ,
253+ requireModules : [
254+ "tns-core-modules/bundle-entry-points" ,
255+ ] ,
256+ projectRoot,
257+ webpackConfig : config ,
258+ } ) ) ;
259+ }
260+
261+ if ( hmr ) {
262+ config . plugins . push ( new webpack . HotModuleReplacementPlugin ( ) ) ;
263+ }
264+
265+ return config ;
266+ } ;
0 commit comments