diff --git a/sdkAngular/app/app.module.ngfactory.d.ts b/sdkAngular/app/app.module.ngfactory.d.ts new file mode 100644 index 00000000..793157de --- /dev/null +++ b/sdkAngular/app/app.module.ngfactory.d.ts @@ -0,0 +1,4 @@ +/** + * A dynamically generated module when compiled with AoT. + */ +export const AppModuleNgFactory: any; \ No newline at end of file diff --git a/sdkAngular/app/vendor-platform.android.ts b/sdkAngular/app/vendor-platform.android.ts index c02e5cfd..da00f85f 100644 --- a/sdkAngular/app/vendor-platform.android.ts +++ b/sdkAngular/app/vendor-platform.android.ts @@ -1,21 +1,9 @@ -// Resolve JavaScript classes that extend a Java class, and need to resolve -// their JavaScript module from a bundled script. For example: -// NativeScriptApplication, NativeScriptActivity, etc. -// -// This module gets bundled together with the rest of the app code and the -// `require` calls get resolved to the correct bundling import call. -// -// At runtime the module gets loaded *before* the rest of the app code, so code -// placed here needs to be careful about its dependencies. - require("application"); - if (!global["__snapshot"]) { // In case snapshot generation is enabled these modules will get into the bundle // but will not be required/evaluated. // The snapshot webpack plugin will add them to the tns-java-classes.js bundle file. // This way, they will be evaluated on app start as early as possible. - require("ui/frame"); require("ui/frame/activity"); require("./main-activity.android.ts"); diff --git a/sdkAngular/app/vendor-platform.ios.ts b/sdkAngular/app/vendor-platform.ios.ts index e69de29b..5ce49d81 100644 --- a/sdkAngular/app/vendor-platform.ios.ts +++ b/sdkAngular/app/vendor-platform.ios.ts @@ -0,0 +1,3 @@ +// There is a bug in angular: https://github.com/angular/angular-cli/pull/8589/files +// Legendary stuff, its webpack plugin pretty much doesn't work with empty TypeScript files in v1.8.3 +void 0; diff --git a/sdkAngular/app/vendor.ts b/sdkAngular/app/vendor.ts index 2c0fb983..4526eca9 100644 --- a/sdkAngular/app/vendor.ts +++ b/sdkAngular/app/vendor.ts @@ -1,3 +1,10 @@ +// Snapshot the ~/app.css and the theme +const application = require("application"); +require("ui/styling/style-scope"); +const appCssContext = require.context("~/", false, /^\.\/app\.(css|scss|less|sass)$/); +global.registerWebpackModules(appCssContext); +application.loadAppCss(); + require("./vendor-platform"); require("reflect-metadata"); @@ -11,11 +18,3 @@ require("@angular/router"); require("nativescript-angular/platform-static"); require("nativescript-angular/forms"); require("nativescript-angular/router"); - -require("nativescript-pro-ui/autocomplete/angular"); -require("nativescript-pro-ui/calendar/angular"); -require("nativescript-pro-ui/chart/angular"); -require("nativescript-pro-ui/dataform/angular"); -require("nativescript-pro-ui/gauges/angular"); -require("nativescript-pro-ui/listview/angular"); -require("nativescript-pro-ui/sidedrawer/angular"); \ No newline at end of file diff --git a/sdkAngular/package.json b/sdkAngular/package.json index aa2ddc56..e5ac75c8 100644 --- a/sdkAngular/package.json +++ b/sdkAngular/package.json @@ -37,14 +37,15 @@ }, "devDependencies": { "@angular/compiler-cli": "~5.0.0", - "@ngtools/webpack": "~1.5.3", + "@ngtools/webpack": "~1.8.2", "babel-traverse": "6.24.1", "babel-types": "6.24.1", "babylon": "6.17.0", "chai": "^3.5.0", "codelyzer": "^3.0.0", "copy-webpack-plugin": "~4.0.1", - "extract-text-webpack-plugin": "3.0.0", + "css-loader": "~0.28.7", + "extract-text-webpack-plugin": "~3.0.0", "filewalker": "0.1.3", "karma": "^1.6.0", "karma-chai": "^0.1.0", @@ -55,25 +56,25 @@ "nativescript-css-loader": "~0.26.0", "nativescript-dev-typescript": "0.5.1", "nativescript-dev-webpack": "next", + "nativescript-worker-loader": "~0.8.1", "raw-loader": "~0.5.1", - "resolve-url-loader": "~2.0.2", + "resolve-url-loader": "~2.1.0", "tns-platform-declarations": "next", - "tslint": "^5.1.0", "tslib": "1.7.1", + "tslint": "^5.1.0", "typescript": "~2.4.2", - "webpack": "3.1.0", + "webpack": "~3.8.1", "webpack-bundle-analyzer": "^2.8.2", - "webpack-sources": "~1.0.1", - "nativescript-worker-loader": "~0.8.1" + "webpack-sources": "~1.0.1" }, "scripts": { - "ns-bundle": "ns-bundle", "tslint": "tslint --project tsconfig.json --config tslint.json", - "publish-ios-bundle": "npm run ns-bundle --ios --publish-app", - "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install", + "ns-bundle": "ns-bundle", "start-android-bundle": "npm run ns-bundle --android --run-app", "start-ios-bundle": "npm run ns-bundle --ios --run-app", "build-android-bundle": "npm run ns-bundle --android --build-app", - "build-ios-bundle": "npm run ns-bundle --ios --build-app" + "build-ios-bundle": "npm run ns-bundle --ios --build-app", + "publish-ios-bundle": "npm run ns-bundle --ios --publish-app", + "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install" } } diff --git a/sdkAngular/tsconfig.aot.json b/sdkAngular/tsconfig.aot.json deleted file mode 100644 index 79a82a22..00000000 --- a/sdkAngular/tsconfig.aot.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "baseUrl": ".", - "paths": { - "ui/*": ["node_modules/tns-core-modules/ui/*"], - "platform": ["node_modules/tns-core-modules/platform"], - "image-source": ["node_modules/tns-core-modules/image-source"], - "xml": ["node_modules/tns-core-modules/xml"], - "xhr": ["node_modules/tns-core-modules/xhr"], - "text": ["node_modules/tns-core-modules/text"], - "data/*": ["node_modules/tns-core-modules/data/*"], - "fetch": ["node_modules/tns-core-modules/fetch"], - "trace": ["node_modules/tns-core-modules/trace"], - "fps-meter": ["node_modules/tns-core-modules/fps-meter"], - "color": ["node_modules/tns-core-modules/color"], - "application-settings": ["node_modules/tns-core-modules/application-settings"], - "http": ["node_modules/tns-core-modules/http"], - "camera": ["node_modules/tns-core-modules/camera"], - "console": ["node_modules/tns-core-modules/console"], - "timer": ["node_modules/tns-core-modules/timer"], - "utils/*": ["node_modules/tns-core-modules/utils/*"], - "location": ["node_modules/tns-core-modules/location"], - "file-system": ["node_modules/tns-core-modules/file-system"], - "application": ["node_modules/tns-core-modules/application"], - "image-asset": ["node_modules/tns-core-modules/image-asset"], - "connectivity": ["node_modules/tns-core-modules/connectivity"], - "globals": ["node_modules/tns-core-modules/globals"] - } - }, - "exclude": [ - "node_modules", - "platforms" - ], - "angularCompilerOptions": { - "skipMetadataEmit": true, - "genDir": "./" - } -} diff --git a/sdkAngular/tsconfig.json b/sdkAngular/tsconfig.json index 9a4abccb..f096aeb7 100644 --- a/sdkAngular/tsconfig.json +++ b/sdkAngular/tsconfig.json @@ -7,6 +7,7 @@ "removeComments": false, "watch": false, "noLib": false, + "noEmitHelpers": true, "preserveConstEnums": true, "emitDecoratorMetadata": true, "suppressImplicitAnyIndexErrors": true, @@ -30,7 +31,6 @@ ], "exclude": [ "node_modules", - "platforms", - "**/*.aot.ts" + "platforms" ] -} \ No newline at end of file +} diff --git a/sdkAngular/webpack.config.js b/sdkAngular/webpack.config.js index 0a21762e..8b0e3e3a 100644 --- a/sdkAngular/webpack.config.js +++ b/sdkAngular/webpack.config.js @@ -6,31 +6,16 @@ const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target const CopyWebpackPlugin = require("copy-webpack-plugin"); const ExtractTextPlugin = require("extract-text-webpack-plugin"); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); - -const { AotPlugin } = require("@ngtools/webpack"); - -const mainSheet = `app.css`; +const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); module.exports = env => { - const platform = getPlatform(env); - - // Default destination inside platforms//... - const path = resolve(nsWebpack.getAppPath(platform)); - - const entry = { - // Discover entry module from package.json - bundle: `./${nsWebpack.getEntryModule()}`, - - // Vendor entry with third-party libraries - vendor: `./vendor`, - - // Entry for stylesheet with global application styles - [mainSheet]: `./${mainSheet}`, - }; - - const rules = getRules(); - const plugins = getPlugins(platform, env); - const extensions = getExtensions(platform); + const platform = env && (env.android && "android" || env.ios && "ios"); + if (!platform) { + throw new Error("You need to provide a target platform!"); + } + const platforms = ["ios", "android"]; + const { snapshot, uglify, report, aot } = env; + const ngToolsWebpackOptions = { tsConfigPath: "tsconfig.json" }; const nativeClassExtenders = [ join(__dirname, "app/main-activity.android.ts"), @@ -39,25 +24,33 @@ module.exports = env => { const config = { context: resolve("./app"), target: nativescriptTarget, - entry, + entry: { + bundle: aot ? "./main.aot.ts" : "./main.ts", + vendor: "./vendor", + }, output: { pathinfo: true, - path, + // Default destination inside platforms//... + path: resolve(nsWebpack.getAppPath(platform)), libraryTarget: "commonjs2", filename: "[name].js", }, resolve: { - extensions, - + extensions: [".ts", ".js", ".scss", ".css"], // Resolve {N} system modules from tns-core-modules modules: [ "node_modules/tns-core-modules", "node_modules", ], - alias: { - "~": resolve("./app") + '~': resolve("./app") }, + // don't resolve symlinks to symlinked modules + symlinks: false + }, + resolveLoader: { + // don't resolve symlinks to symlinked loaders + symlinks: false }, node: { // Disable node shims that conflict with NativeScript @@ -66,177 +59,99 @@ module.exports = env => { "setImmediate": false, "fs": "empty", }, - module: { rules }, - plugins, - }; + module: { + rules: [ + { test: /\.html$|\.xml$/, use: "raw-loader" }, - if (env.snapshot) { - plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", - projectRoot: __dirname, - webpackConfig: config, - targetArchs: ["arm", "arm64", "ia32"], - tnsJavaClassesOptions: { - packages: ["tns-core-modules"], - modules: nativeClassExtenders, - }, - useLibs: false - })); - } - - return config; -}; + // tns-core-modules reads the app.css and its imports using css-loader + { test: /\/app\.css$/, use: "css-loader?url=false" }, + { test: /\/app\.scss$/, use: ["css-loader?url=false", "sass-loader"] }, + // Angular components reference css files and their imports using raw-loader + { test: /\.css$/, exclude: /\/app\.css$/, use: "raw-loader" }, + { test: /\.scss$/, exclude: /\/app\.scss$/, use: ["raw-loader", "resolve-url-loader", "sass-loader"] }, -function getPlatform(env) { - return env.android ? "android" : - env.ios ? "ios" : - () => { throw new Error("You need to provide a target platform!") }; -} - -function getRules() { - return [ - { - test: /\.html$|\.xml$/, - use: [ - "raw-loader", - ] + // Compile TypeScript files with ahead-of-time compiler. + { test: /.ts$/, use: ["nativescript-dev-webpack/moduleid-compat-loader", "@ngtools/webpack"] }, + ], }, - // Root stylesheet gets extracted with bundled dependencies - { - test: new RegExp(mainSheet), - use: ExtractTextPlugin.extract([ - { - loader: "resolve-url-loader", - options: { silent: true }, - }, - { - loader: "nativescript-css-loader", - options: { minimize: false } - }, - "nativescript-dev-webpack/platform-css-loader", + plugins: [ + // Vendor libs go to the vendor.js chunk + new webpack.optimize.CommonsChunkPlugin({ + name: ["vendor"], + }), + // Define useful constants like TNS_WEBPACK + new webpack.DefinePlugin({ + "global.TNS_WEBPACK": "true", + }), + // Copy assets to out dir. Add your own globs as needed. + new CopyWebpackPlugin([ + { from: "App_Resources/**" }, + { from: "fonts/**" }, + { from: "**/*.jpg" }, + { from: "**/*.png" }, + { from: "**/*.xml" }, ]), - }, - // Other CSS files get bundled using the raw loader - { - test: /\.css$/, - exclude: new RegExp(mainSheet), - use: [ - "raw-loader", - ] - }, - // SASS support - { - test: /\.scss$/, - use: [ - "raw-loader", - "resolve-url-loader", - "sass-loader", - ] - }, - - - // Compile TypeScript files with ahead-of-time compiler. - { - test: /\.ts$/, - loaders: [ - "nativescript-dev-webpack/tns-aot-loader", - "@ngtools/webpack", - ] - } - - ]; -} - -function getPlugins(platform, env) { - let plugins = [ - new ExtractTextPlugin(mainSheet), - - // Vendor libs go to the vendor.js chunk - new webpack.optimize.CommonsChunkPlugin({ - name: ["vendor"], - }), - - // Define useful constants like TNS_WEBPACK - new webpack.DefinePlugin({ - "global.TNS_WEBPACK": "true", - }), - - // Copy assets to out dir. Add your own globs as needed. - new CopyWebpackPlugin([ - { from: mainSheet }, - { from: "css/**" }, - { from: "fonts/**" }, - { from: "**/*.jpg" }, - { from: "**/*.png" }, - { from: "**/*.xml" }, - { from: "**/*.json" }, - ], { ignore: ["App_Resources/**"] }), - - // Generate a bundle starter script and activate it in package.json - new nsWebpack.GenerateBundleStarterPlugin([ - "./vendor", - "./bundle", - ]), - + // Generate a bundle starter script and activate it in package.json + new nsWebpack.GenerateBundleStarterPlugin([ + "./vendor", + "./bundle", + ]), + // Support for web workers since v3.2 + new NativeScriptWorkerPlugin(), + // AngularCompilerPlugin with augmented NativeScript filesystem to handle platform specific resource resolution. + new nsWebpack.NativeScriptAngularCompilerPlugin( + Object.assign({ + entryModule: resolve(__dirname, "app/app.module#AppModule"), + skipCodeGeneration: !aot, + platformOptions: { + platform, + platforms, + // ignore: ["App_Resources"] + }, + }, ngToolsWebpackOptions) + ), + // Does IPC communication with the {N} CLI to notify events when running in watch mode. + new nsWebpack.WatchStateLoggerPlugin(), + ], + }; + if (report) { // Generate report files for bundles content - new BundleAnalyzerPlugin({ + config.plugins.push(new BundleAnalyzerPlugin({ analyzerMode: "static", openAnalyzer: false, generateStatsFile: true, reportFilename: join(__dirname, "report", `report.html`), statsFilename: join(__dirname, "report", `stats.json`), - }), - - // Angular AOT compiler - new AotPlugin({ - tsConfigPath: "tsconfig.aot.json", - entryModule: resolve(__dirname, "app/app.module#AppModule"), - typeChecking: false - }), - - // Resolve .ios.css and .android.css component stylesheets, and .ios.html and .android component views - new nsWebpack.UrlResolvePlugin({ - platform: platform, - resolveStylesUrls: true, - resolveTemplateUrl: true - }), - - ]; - - if (env.uglify) { - plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); + })); + } + if (snapshot) { + config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ + chunk: "vendor", + projectRoot: __dirname, + webpackConfig: config, + targetArchs: ["arm", "arm64", "ia32"], + tnsJavaClassesOptions: { + packages: ["tns-core-modules" ], + modules: nativeClassExtenders, + }, + useLibs: false + })); + } + if (uglify) { + config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); // Work around an Android issue by setting compress = false const compress = platform !== "android"; - - const mangle = { - except: [ + config.plugins.push(new webpack.optimize.UglifyJsPlugin({ + mangle: { except: [ ...nsWebpack.uglifyMangleExcludes, "org.nativescript.sdkAngular.MainActivity", - "MainActivity", - "AutoCompleteAdapter" - ] - }; - - plugins.push(new webpack.optimize.UglifyJsPlugin({ - mangle, + "AutoCompleteAdapter", + ]}, compress, })); } - return plugins; -} - -// Resolve platform-specific modules like module.android.js -function getExtensions(platform) { - return Object.freeze([ - `.${platform}.ts`, - `.${platform}.js`, - ".aot.ts", - ".ts", - ".js", - ".css", - `.${platform}.css`, - ]); -} + return config; +};