From 160b4a5bef0cf884a3719616407ac9bf236fa2cd Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 28 Mar 2019 16:25:24 +0200 Subject: [PATCH 1/2] fix: support platform specific files that are not directly imported anywhere in the app (e.g. when main.ts is platform specific). --- package.json | 2 ++ plugins/NativeScriptAngularCompilerPlugin.ts | 28 ++++++++++++++++++++ plugins/index.js | 3 ++- templates/webpack.angular.js | 12 ++++----- templates/webpack.config.spec.ts | 3 ++- 5 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 plugins/NativeScriptAngularCompilerPlugin.ts diff --git a/package.json b/package.json index 92e0e09e..6423ff34 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,8 @@ }, "devDependencies": { "@ngtools/webpack": "~7.2.0", + "@angular/compiler": "~7.2.0", + "@angular/compiler-cli": "~7.2.0", "@types/jasmine": "^3.3.7", "@types/node": "^10.12.12", "@types/proxyquire": "1.3.28", diff --git a/plugins/NativeScriptAngularCompilerPlugin.ts b/plugins/NativeScriptAngularCompilerPlugin.ts new file mode 100644 index 00000000..3a88d4c5 --- /dev/null +++ b/plugins/NativeScriptAngularCompilerPlugin.ts @@ -0,0 +1,28 @@ +import { parse, sep } from "path"; +import { AngularCompilerPlugin } from "@ngtools/webpack"; + +export function getAngularCompilerPlugin(platform: string): any { + class NativeScriptAngularCompilerPlugin extends AngularCompilerPlugin { + // This is the bridge between the @ngtols/webpack loader and the AngularCompilerPlugin plugin itself: + // https://github.com/angular/angular-cli/blob/bf52b26219ffc16bed2dd55716e21773b415fd2a/packages/ngtools/webpack/src/loader.ts#L49 + // The problem is that the loader does not call the `hostReplacementPaths` method when asking for the compiledFile. + // By overriding this method, we workaround this issue and support platform specific files from the loader + // that are not compiled by the AngularCompilerPlugin plugin. e.g. main.ts is the webpack entry point and + // it's loaded by the @ngtools/webpack loader but its not compiled by the plugin because the TypeScript Compiler + // knowns only about main.android.ts and main.ios.ts (main.ts is not imported/required anywhere in the app). + getCompiledFile(file) { + try { + if (platform) { + const parsed = parse(file); + const platformFile = parsed.dir + sep + parsed.name + "." + platform + parsed.ext; + return super.getCompiledFile(platformFile);; + } + } + catch (e) { } + + return super.getCompiledFile(file); + } + } + + return NativeScriptAngularCompilerPlugin; +} \ No newline at end of file diff --git a/plugins/index.js b/plugins/index.js index 9f363929..6ef7d7a2 100644 --- a/plugins/index.js +++ b/plugins/index.js @@ -3,5 +3,6 @@ module.exports = Object.assign({}, require("./NativeScriptSnapshotPlugin"), require("./PlatformSuffixPlugin"), require("./PlatformFSPlugin"), - require("./WatchStateLoggerPlugin") + require("./WatchStateLoggerPlugin"), + require("./NativeScriptAngularCompilerPlugin") ); diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 2f196cb2..61e7e477 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -12,8 +12,7 @@ const CopyWebpackPlugin = require("copy-webpack-plugin"); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); -const { AngularCompilerPlugin } = require("@ngtools/webpack"); -const hashSalt = Date.now().toString(); +const hashSalt = Date.now().toString(); module.exports = env => { // Add your custom Activities, Services and other Android app components here. @@ -27,6 +26,7 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } + const AngularCompilerPlugin = nsWebpack.getAngularCompilerPlugin(platform); const projectRoot = __dirname; // Default destination inside platforms//... @@ -261,10 +261,10 @@ module.exports = env => { // configures the WebPack runtime to be generated inside the snapshot // module and no `runtime.js` module exist. (snapshot ? [] : ["./runtime"]) - .concat([ - "./vendor", - "./bundle", - ]) + .concat([ + "./vendor", + "./bundle", + ]) ), // For instructions on how to set up workers with webpack // check out https://github.com/nativescript/worker-loader diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts index 8a17cb6f..e050c2b5 100644 --- a/templates/webpack.config.spec.ts +++ b/templates/webpack.config.spec.ts @@ -22,7 +22,8 @@ const nativeScriptDevWebpack = { getEntryModule: () => 'EntryModule', getResolver: () => null, getEntryPathRegExp: () => null, - getConvertedExternals: nsWebpackIndex.getConvertedExternals + getConvertedExternals: nsWebpackIndex.getConvertedExternals, + getAngularCompilerPlugin: () => AngularCompilerStub }; const emptyObject = {}; From ba1e4c527e13cc0f01bdb84d649d7709d753a6e3 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 28 Mar 2019 16:34:37 +0200 Subject: [PATCH 2/2] fix: support platform specific entry modules --- index.js | 11 +++++++++-- plugins/NativeScriptAngularCompilerPlugin.ts | 10 +++++----- plugins/index.js | 3 +-- templates/webpack.angular.js | 5 +++-- templates/webpack.config.spec.ts | 4 ++-- templates/webpack.javascript.js | 2 +- templates/webpack.typescript.js | 2 +- templates/webpack.vue.js | 2 +- 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 39e3bb96..f9a92f11 100644 --- a/index.js +++ b/index.js @@ -25,14 +25,21 @@ exports.getAotEntryModule = function (appDirectory) { return aotEntry; } -exports.getEntryModule = function (appDirectory) { +exports.getEntryModule = function (appDirectory, platform) { verifyEntryModuleDirectory(appDirectory); const entry = getPackageJsonEntry(appDirectory); const tsEntryPath = path.resolve(appDirectory, `${entry}.ts`); const jsEntryPath = path.resolve(appDirectory, `${entry}.js`); - if (!existsSync(tsEntryPath) && !existsSync(jsEntryPath)) { + let entryExists = existsSync(tsEntryPath) || existsSync(jsEntryPath); + if (!entryExists && platform) { + const platformTsEntryPath = path.resolve(appDirectory, `${entry}.${platform}.ts`); + const platformJsEntryPath = path.resolve(appDirectory, `${entry}.${platform}.js`); + entryExists = existsSync(platformTsEntryPath) || existsSync(platformJsEntryPath); + } + + if (!entryExists) { throw new Error(`The entry module ${entry} specified in ` + `${appDirectory}/package.json doesn't exist!`) } diff --git a/plugins/NativeScriptAngularCompilerPlugin.ts b/plugins/NativeScriptAngularCompilerPlugin.ts index 3a88d4c5..299b97d6 100644 --- a/plugins/NativeScriptAngularCompilerPlugin.ts +++ b/plugins/NativeScriptAngularCompilerPlugin.ts @@ -1,4 +1,4 @@ -import { parse, sep } from "path"; +import { parse, join } from "path"; import { AngularCompilerPlugin } from "@ngtools/webpack"; export function getAngularCompilerPlugin(platform: string): any { @@ -6,7 +6,7 @@ export function getAngularCompilerPlugin(platform: string): any { // This is the bridge between the @ngtols/webpack loader and the AngularCompilerPlugin plugin itself: // https://github.com/angular/angular-cli/blob/bf52b26219ffc16bed2dd55716e21773b415fd2a/packages/ngtools/webpack/src/loader.ts#L49 // The problem is that the loader does not call the `hostReplacementPaths` method when asking for the compiledFile. - // By overriding this method, we workaround this issue and support platform specific files from the loader + // By overriding this method, we work around this issue and support platform specific files from the loader // that are not compiled by the AngularCompilerPlugin plugin. e.g. main.ts is the webpack entry point and // it's loaded by the @ngtools/webpack loader but its not compiled by the plugin because the TypeScript Compiler // knowns only about main.android.ts and main.ios.ts (main.ts is not imported/required anywhere in the app). @@ -14,8 +14,8 @@ export function getAngularCompilerPlugin(platform: string): any { try { if (platform) { const parsed = parse(file); - const platformFile = parsed.dir + sep + parsed.name + "." + platform + parsed.ext; - return super.getCompiledFile(platformFile);; + const platformFile = join(parsed.dir, `${parsed.name}.${platform}${parsed.ext}`); + return super.getCompiledFile(platformFile); } } catch (e) { } @@ -25,4 +25,4 @@ export function getAngularCompilerPlugin(platform: string): any { } return NativeScriptAngularCompilerPlugin; -} \ No newline at end of file +} diff --git a/plugins/index.js b/plugins/index.js index 6ef7d7a2..9f363929 100644 --- a/plugins/index.js +++ b/plugins/index.js @@ -3,6 +3,5 @@ module.exports = Object.assign({}, require("./NativeScriptSnapshotPlugin"), require("./PlatformSuffixPlugin"), require("./PlatformFSPlugin"), - require("./WatchStateLoggerPlugin"), - require("./NativeScriptAngularCompilerPlugin") + require("./WatchStateLoggerPlugin") ); diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 61e7e477..ed384adb 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -12,6 +12,7 @@ const CopyWebpackPlugin = require("copy-webpack-plugin"); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); +const { getAngularCompilerPlugin } = require("nativescript-dev-webpack/plugins/NativeScriptAngularCompilerPlugin"); const hashSalt = Date.now().toString(); module.exports = env => { @@ -26,7 +27,7 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } - const AngularCompilerPlugin = nsWebpack.getAngularCompilerPlugin(platform); + const AngularCompilerPlugin = getAngularCompilerPlugin(platform); const projectRoot = __dirname; // Default destination inside platforms//... @@ -54,7 +55,7 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const tsConfigName = "tsconfig.tns.json"; - const entryModule = `${nsWebpack.getEntryModule(appFullPath)}.ts`; + const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`; const entryPath = `.${sep}${entryModule}`; const entries = { bundle: entryPath }; if (platform === "ios") { diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts index e050c2b5..35db7d4b 100644 --- a/templates/webpack.config.spec.ts +++ b/templates/webpack.config.spec.ts @@ -22,8 +22,7 @@ const nativeScriptDevWebpack = { getEntryModule: () => 'EntryModule', getResolver: () => null, getEntryPathRegExp: () => null, - getConvertedExternals: nsWebpackIndex.getConvertedExternals, - getAngularCompilerPlugin: () => AngularCompilerStub + getConvertedExternals: nsWebpackIndex.getConvertedExternals }; const emptyObject = {}; @@ -37,6 +36,7 @@ const webpackConfigAngular = proxyquire('./webpack.angular', { 'nativescript-dev-webpack/transformers/ns-replace-lazy-loader': { nsReplaceLazyLoader: () => { return FakeLazyTransformerFlag } }, 'nativescript-dev-webpack/transformers/ns-support-hmr-ng': { nsSupportHmrNg: () => { return FakeHmrTransformerFlag } }, 'nativescript-dev-webpack/utils/ast-utils': { getMainModulePath: () => { return "fakePath"; } }, + 'nativescript-dev-webpack/plugins/NativeScriptAngularCompilerPlugin': { getAngularCompilerPlugin: () => { return AngularCompilerStub; } }, '@ngtools/webpack': { AngularCompilerPlugin: AngularCompilerStub } diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index a927d9bf..626df1c3 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -49,7 +49,7 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - const entryModule = nsWebpack.getEntryModule(appFullPath); + const entryModule = nsWebpack.getEntryModule(appFullPath, platform); const entryPath = `.${sep}${entryModule}.js`; const entries = { bundle: entryPath }; if (platform === "ios") { diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 730c38ee..5e7903ba 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -49,7 +49,7 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - const entryModule = nsWebpack.getEntryModule(appFullPath); + const entryModule = nsWebpack.getEntryModule(appFullPath, platform); const entryPath = `.${sep}${entryModule}.ts`; const entries = { bundle: entryPath }; if (platform === "ios") { diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 3361cc3d..298917e6 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -56,7 +56,7 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - const entryModule = nsWebpack.getEntryModule(appFullPath); + const entryModule = nsWebpack.getEntryModule(appFullPath, platform); const entryPath = `.${sep}${entryModule}`; const entries = { bundle: entryPath }; if (platform === "ios") {