diff --git a/bundle-config-loader.ts b/bundle-config-loader.ts index c60a163c..a3e3cdb8 100644 --- a/bundle-config-loader.ts +++ b/bundle-config-loader.ts @@ -10,6 +10,7 @@ const loader: loader.Loader = function (source, map) { let { angular = false, loadCss = true, + platform, unitTesting, projectRoot, appFullPath, @@ -53,8 +54,14 @@ const loader: loader.Loader = function (source, map) { } `; + let sourceModule = "tns-core-modules"; + + if (platform && platform !== "ios" && platform !== "android") { + sourceModule = `nativescript-platform-${platform}`; + } + source = ` - require("tns-core-modules/bundle-entry-points"); + require("${sourceModule}/bundle-entry-points"); ${source} `; diff --git a/index.js b/index.js index 0840f7dc..766d4af4 100644 --- a/index.js +++ b/index.js @@ -103,6 +103,8 @@ exports.getAppPath = (platform, projectDir) => { return `platforms/ios/${sanitizedName}/app`; } else if (isAndroid(platform)) { return ANDROID_APP_PATH; + } else if (hasPlatformPlugin(projectDir, platform)) { + return `platforms/${platform}/app`; } else { throw new Error(`Invalid platform: ${platform}`); } @@ -191,6 +193,13 @@ const sanitize = name => name .filter(char => /[a-zA-Z0-9]/.test(char)) .join(""); +function hasPlatformPlugin(appDirectory, platform) { + const packageJsonSource = getPackageJson(appDirectory); + const { dependencies } = packageJsonSource; + + return !!dependencies[`nativescript-platform-${platform}`]; +} + function getPackageJsonEntry(appDirectory) { const packageJsonSource = getPackageJson(appDirectory); const entry = packageJsonSource.main; @@ -252,4 +261,4 @@ function ensurePathInCompilerOptions({ compilerOptions, sourcePath, destinationP } else { paths[sourcePath] = [destinationPath]; } -} \ No newline at end of file +} diff --git a/plugins/PlatformFSPlugin.ts b/plugins/PlatformFSPlugin.ts index 5619ea4e..91daccac 100644 --- a/plugins/PlatformFSPlugin.ts +++ b/plugins/PlatformFSPlugin.ts @@ -8,7 +8,7 @@ export interface PlatformFSPluginOptions { platform?: string; /** - * A list of all platforms. By default it is `["ios", "android"]`. + * A list of all platforms. By default it is `["ios", "android", "desktop"]`. */ platforms?: string[]; @@ -18,6 +18,8 @@ export interface PlatformFSPluginOptions { ignore?: string[]; } +const internalPlatforms = ["ios", "android"]; + export class PlatformFSPlugin { protected readonly platform: string; protected readonly platforms: ReadonlyArray; @@ -26,7 +28,7 @@ export class PlatformFSPlugin { constructor({ platform, platforms, ignore }: PlatformFSPluginOptions) { this.platform = platform || ""; - this.platforms = platforms || ["ios", "android"]; + this.platforms = platforms || internalPlatforms; this.ignore = ignore || []; } @@ -58,6 +60,8 @@ export function mapFileSystem(args: MapFileSystemArgs): any { const fs = compiler.inputFileSystem; ignore = args.ignore || []; + const isExternal = internalPlatforms.indexOf(platform) === -1; + const minimatchFileFilters = ignore.map(pattern => { const minimatchFilter = minimatch.filter(pattern); return file => minimatchFilter(relative(context, file)); @@ -80,7 +84,7 @@ export function mapFileSystem(args: MapFileSystemArgs): any { return join(dir, name.substr(0, name.length - currentPlatformExt.length) + ext); } return file; - } + }; const isNotIgnored = file => !isIgnored(file); @@ -95,7 +99,28 @@ export function mapFileSystem(args: MapFileSystemArgs): any { function platformSpecificFile(file: string): string { const {dir, name, ext} = parseFile(file); - const platformFilePath = join(dir, `${name}.${platform}${ext}`); + let platformFilePath = join(dir, `${name}.${platform}${ext}`); + + if (isExternal && dir.indexOf("/@nativescript/core/") !== -1) { + let replacedPath; + try { + replacedPath = dir.replace( + /node_modules(\/[^/]+)?\/@nativescript\/core/, + `node_modules/nativescript-platform-${platform}` + ); + + platformFilePath = require.resolve(join(replacedPath, `${name}.${platform}${ext}`)); + } catch (e) { + if (replacedPath) { + if (ext === ".d") { + platformFilePath = undefined; + } else { + platformFilePath = join(replacedPath, `${name}${ext}`); + } + } + } + } + return platformFilePath; } diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 64d67979..f0b43bbe 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -24,7 +24,7 @@ module.exports = env => { "tns-core-modules/ui/frame/activity", ]); - const platform = env && (env.android && "android" || env.ios && "ios"); + const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); if (!platform) { throw new Error("You need to provide a target platform!"); } diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index e91c6e0a..59360c38 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -18,7 +18,7 @@ module.exports = env => { "tns-core-modules/ui/frame/activity", ]); - const platform = env && (env.android && "android" || env.ios && "ios"); + const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); if (!platform) { throw new Error("You need to provide a target platform!"); } @@ -26,6 +26,10 @@ module.exports = env => { const platforms = ["ios", "android"]; const projectRoot = __dirname; + if (env.platform) { + platforms.push(env.platform); + } + // Default destination inside platforms//... const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 4d1c3ad6..35c4fe65 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -20,7 +20,7 @@ module.exports = env => { "tns-core-modules/ui/frame/activity", ]); - const platform = env && (env.android && "android" || env.ios && "ios"); + const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); if (!platform) { throw new Error("You need to provide a target platform!"); } @@ -28,6 +28,10 @@ module.exports = env => { const platforms = ["ios", "android"]; const projectRoot = __dirname; + if (env.platform) { + platforms.push(env.platform); + } + // Default destination inside platforms//... const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 6cb3697f..16339117 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -22,7 +22,7 @@ module.exports = env => { "tns-core-modules/ui/frame/activity", ]); - const platform = env && (env.android && "android" || env.ios && "ios"); + const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); if (!platform) { throw new Error("You need to provide a target platform!"); } @@ -30,6 +30,10 @@ module.exports = env => { const platforms = ["ios", "android"]; const projectRoot = __dirname; + if (env.platform) { + platforms.push(env.platform); + } + // Default destination inside platforms//... const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); diff --git a/xml-namespace-loader.ts b/xml-namespace-loader.ts index 5c211537..f3a16404 100644 --- a/xml-namespace-loader.ts +++ b/xml-namespace-loader.ts @@ -100,13 +100,15 @@ const loader: loader.Loader = function (source: string, map) { // Register ios and android prefixes as namespaces to avoid "unbound xml namespace" errors (saxParser).ns["ios"] = "http://schemas.nativescript.org/tns.xsd"; (saxParser).ns["android"] = "http://schemas.nativescript.org/tns.xsd"; + (saxParser).ns["desktop"] = "http://schemas.nativescript.org/tns.xsd"; + (saxParser).ns["web"] = "http://schemas.nativescript.org/tns.xsd"; saxParser.onopentag = (node: QualifiedTag) => { handleOpenTag(node.uri, node.local); }; saxParser.onerror = (err) => { // Do only warning about invalid character "&"" for back-compatibility // as it is common to use it in a binding expression - if (err && - err.message.indexOf("Invalid character") >= 0 && + if (err && + err.message.indexOf("Invalid character") >= 0 && err.message.indexOf("Char: &") >= 0) { this.emitWarning(err) } else { @@ -140,4 +142,4 @@ const loader: loader.Loader = function (source: string, map) { }) } -export default loader; \ No newline at end of file +export default loader;