Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

Commit 89c52af

Browse files
Merge pull request #1119 from NativeScript/bundev/custom-platform-support
feat(platforms): Add support for custom platform plugins
2 parents c2e2011 + 242317b commit 89c52af

8 files changed

+68
-13
lines changed

bundle-config-loader.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const loader: loader.Loader = function (source, map) {
1010
let {
1111
angular = false,
1212
loadCss = true,
13+
platform,
1314
unitTesting,
1415
projectRoot,
1516
appFullPath,
@@ -53,8 +54,14 @@ const loader: loader.Loader = function (source, map) {
5354
}
5455
`;
5556

57+
let sourceModule = "tns-core-modules";
58+
59+
if (platform && platform !== "ios" && platform !== "android") {
60+
sourceModule = `nativescript-platform-${platform}`;
61+
}
62+
5663
source = `
57-
require("tns-core-modules/bundle-entry-points");
64+
require("${sourceModule}/bundle-entry-points");
5865
${source}
5966
`;
6067

index.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ exports.getAppPath = (platform, projectDir) => {
103103
return `platforms/ios/${sanitizedName}/app`;
104104
} else if (isAndroid(platform)) {
105105
return ANDROID_APP_PATH;
106+
} else if (hasPlatformPlugin(projectDir, platform)) {
107+
return `platforms/${platform}/app`;
106108
} else {
107109
throw new Error(`Invalid platform: ${platform}`);
108110
}
@@ -191,6 +193,13 @@ const sanitize = name => name
191193
.filter(char => /[a-zA-Z0-9]/.test(char))
192194
.join("");
193195

196+
function hasPlatformPlugin(appDirectory, platform) {
197+
const packageJsonSource = getPackageJson(appDirectory);
198+
const { dependencies } = packageJsonSource;
199+
200+
return !!dependencies[`nativescript-platform-${platform}`];
201+
}
202+
194203
function getPackageJsonEntry(appDirectory) {
195204
const packageJsonSource = getPackageJson(appDirectory);
196205
const entry = packageJsonSource.main;
@@ -252,4 +261,4 @@ function ensurePathInCompilerOptions({ compilerOptions, sourcePath, destinationP
252261
} else {
253262
paths[sourcePath] = [destinationPath];
254263
}
255-
}
264+
}

plugins/PlatformFSPlugin.ts

+29-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface PlatformFSPluginOptions {
88
platform?: string;
99

1010
/**
11-
* A list of all platforms. By default it is `["ios", "android"]`.
11+
* A list of all platforms. By default it is `["ios", "android", "desktop"]`.
1212
*/
1313
platforms?: string[];
1414

@@ -18,6 +18,8 @@ export interface PlatformFSPluginOptions {
1818
ignore?: string[];
1919
}
2020

21+
const internalPlatforms = ["ios", "android"];
22+
2123
export class PlatformFSPlugin {
2224
protected readonly platform: string;
2325
protected readonly platforms: ReadonlyArray<string>;
@@ -26,7 +28,7 @@ export class PlatformFSPlugin {
2628

2729
constructor({ platform, platforms, ignore }: PlatformFSPluginOptions) {
2830
this.platform = platform || "";
29-
this.platforms = platforms || ["ios", "android"];
31+
this.platforms = platforms || internalPlatforms;
3032
this.ignore = ignore || [];
3133
}
3234

@@ -58,6 +60,8 @@ export function mapFileSystem(args: MapFileSystemArgs): any {
5860
const fs = compiler.inputFileSystem;
5961
ignore = args.ignore || [];
6062

63+
const isExternal = internalPlatforms.indexOf(platform) === -1;
64+
6165
const minimatchFileFilters = ignore.map(pattern => {
6266
const minimatchFilter = minimatch.filter(pattern);
6367
return file => minimatchFilter(relative(context, file));
@@ -80,7 +84,7 @@ export function mapFileSystem(args: MapFileSystemArgs): any {
8084
return join(dir, name.substr(0, name.length - currentPlatformExt.length) + ext);
8185
}
8286
return file;
83-
}
87+
};
8488

8589
const isNotIgnored = file => !isIgnored(file);
8690

@@ -95,7 +99,28 @@ export function mapFileSystem(args: MapFileSystemArgs): any {
9599

96100
function platformSpecificFile(file: string): string {
97101
const {dir, name, ext} = parseFile(file);
98-
const platformFilePath = join(dir, `${name}.${platform}${ext}`);
102+
let platformFilePath = join(dir, `${name}.${platform}${ext}`);
103+
104+
if (isExternal && dir.indexOf("/@nativescript/core/") !== -1) {
105+
let replacedPath;
106+
try {
107+
replacedPath = dir.replace(
108+
/node_modules(\/[^/]+)?\/@nativescript\/core/,
109+
`node_modules/nativescript-platform-${platform}`
110+
);
111+
112+
platformFilePath = require.resolve(join(replacedPath, `${name}.${platform}${ext}`));
113+
} catch (e) {
114+
if (replacedPath) {
115+
if (ext === ".d") {
116+
platformFilePath = undefined;
117+
} else {
118+
platformFilePath = join(replacedPath, `${name}${ext}`);
119+
}
120+
}
121+
}
122+
}
123+
99124
return platformFilePath;
100125
}
101126

templates/webpack.angular.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = env => {
2424
"tns-core-modules/ui/frame/activity",
2525
]);
2626

27-
const platform = env && (env.android && "android" || env.ios && "ios");
27+
const platform = env && (env.android && "android" || env.ios && "ios" || env.platform);
2828
if (!platform) {
2929
throw new Error("You need to provide a target platform!");
3030
}

templates/webpack.javascript.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ module.exports = env => {
1818
"tns-core-modules/ui/frame/activity",
1919
]);
2020

21-
const platform = env && (env.android && "android" || env.ios && "ios");
21+
const platform = env && (env.android && "android" || env.ios && "ios" || env.platform);
2222
if (!platform) {
2323
throw new Error("You need to provide a target platform!");
2424
}
2525

2626
const platforms = ["ios", "android"];
2727
const projectRoot = __dirname;
2828

29+
if (env.platform) {
30+
platforms.push(env.platform);
31+
}
32+
2933
// Default destination inside platforms/<platform>/...
3034
const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));
3135

templates/webpack.typescript.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,18 @@ module.exports = env => {
2020
"tns-core-modules/ui/frame/activity",
2121
]);
2222

23-
const platform = env && (env.android && "android" || env.ios && "ios");
23+
const platform = env && (env.android && "android" || env.ios && "ios" || env.platform);
2424
if (!platform) {
2525
throw new Error("You need to provide a target platform!");
2626
}
2727

2828
const platforms = ["ios", "android"];
2929
const projectRoot = __dirname;
3030

31+
if (env.platform) {
32+
platforms.push(env.platform);
33+
}
34+
3135
// Default destination inside platforms/<platform>/...
3236
const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));
3337

templates/webpack.vue.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ module.exports = env => {
2222
"tns-core-modules/ui/frame/activity",
2323
]);
2424

25-
const platform = env && (env.android && "android" || env.ios && "ios");
25+
const platform = env && (env.android && "android" || env.ios && "ios" || env.platform);
2626
if (!platform) {
2727
throw new Error("You need to provide a target platform!");
2828
}
2929

3030
const platforms = ["ios", "android"];
3131
const projectRoot = __dirname;
3232

33+
if (env.platform) {
34+
platforms.push(env.platform);
35+
}
36+
3337
// Default destination inside platforms/<platform>/...
3438
const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));
3539

xml-namespace-loader.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,15 @@ const loader: loader.Loader = function (source: string, map) {
100100
// Register ios and android prefixes as namespaces to avoid "unbound xml namespace" errors
101101
(<any>saxParser).ns["ios"] = "http://schemas.nativescript.org/tns.xsd";
102102
(<any>saxParser).ns["android"] = "http://schemas.nativescript.org/tns.xsd";
103+
(<any>saxParser).ns["desktop"] = "http://schemas.nativescript.org/tns.xsd";
104+
(<any>saxParser).ns["web"] = "http://schemas.nativescript.org/tns.xsd";
103105

104106
saxParser.onopentag = (node: QualifiedTag) => { handleOpenTag(node.uri, node.local); };
105107
saxParser.onerror = (err) => {
106108
// Do only warning about invalid character "&"" for back-compatibility
107109
// as it is common to use it in a binding expression
108-
if (err &&
109-
err.message.indexOf("Invalid character") >= 0 &&
110+
if (err &&
111+
err.message.indexOf("Invalid character") >= 0 &&
110112
err.message.indexOf("Char: &") >= 0) {
111113
this.emitWarning(err)
112114
} else {
@@ -140,4 +142,4 @@ const loader: loader.Loader = function (source: string, map) {
140142
})
141143
}
142144

143-
export default loader;
145+
export default loader;

0 commit comments

Comments
 (0)