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

Implemented platform-specific templateUrl #155

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var isAngular = Object.keys(packageJson.dependencies).filter(function (dependenc


if (isAngular) {
exports.StyleUrlResolvePlugin = require("./resource-resolver-plugins/StyleUrlResolvePlugin");
exports.UrlResolvePlugin = require("./resource-resolver-plugins/UrlResolvePlugin");
}

//HACK: changes the JSONP chunk eval function to `global["nativescriptJsonp"]`
Expand Down
1 change: 1 addition & 0 deletions installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function install() {
let packageJson = helpers.getPackageJson(PROJECT_DIR);

projectFilesManager.addProjectFiles(PROJECT_DIR, APP_DIR);
projectFilesManager.editExistingProjectFiles(PROJECT_DIR);

let scripts = packageJson.scripts || {};
scripts = npmScriptsManager.removeDeprecatedNpmScripts(scripts);
Expand Down
8 changes: 6 additions & 2 deletions prepublish/angular/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ module.exports = `
typeChecking: false
}),
// Resolve .ios.css and .android.css component stylesheets
new nsWebpack.StyleUrlResolvePlugin({platform}),
// Resolve .ios.css and .android.css component stylesheets, and .ios.html and .android component views
new nsWebpack.UrlResolvePlugin({
platform: platform,
resolveStylesUrls: true,
resolveTemplateUrl: true
}),
`;
24 changes: 24 additions & 0 deletions projectFilesManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ function getFullTemplatesPath(projectDir, templates) {
return updatedTemplates;
}

function editExistingProjectFiles(projectDir) {
const webpackConfigPath = getFullPath(projectDir, "webpack.config.js");
const webpackCommonPath = getFullPath(projectDir, "webpack.common.js");

editWebpackConfig(webpackConfigPath, replaceStyleUrlResolvePlugin);
editWebpackConfig(webpackCommonPath, replaceStyleUrlResolvePlugin);
}

function editWebpackConfig(path, fn) {
if (!fs.existsSync(path)) {
return;
}

const config = fs.readFileSync(path, "utf8");
const newConfig = fn(config);

fs.writeFileSync(path, newConfig, "utf8");
}

function replaceStyleUrlResolvePlugin(config) {
return config.replace(/StyleUrlResolvePlugin/g, "UrlResolvePlugin");
}

function getFullPath(projectDir, filePath) {
return path.resolve(projectDir, filePath);
}
Expand All @@ -103,4 +126,5 @@ function tsOrJs(projectDir, name) {
module.exports = {
addProjectFiles,
removeProjectFiles,
editExistingProjectFiles,
};
97 changes: 0 additions & 97 deletions resource-resolver-plugins/StyleUrlResolvePlugin.js

This file was deleted.

109 changes: 109 additions & 0 deletions resource-resolver-plugins/UrlResolvePlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const ts = require("typescript");
const fs = require("fs");
const path = require("path");

const UrlResolvePlugin = (function() {
function UrlResolvePlugin(options) {
if (!options || !options.platform) {
throw new Error(`Target platform must be specified!`);
}

this.platform = options.platform;

// these are true by default
this.resolveStylesUrls = options.resolveStylesUrls === undefined || options.resolveStylesUrls;
this.resolveTemplateUrl = options.resolveTemplateUrl === undefined || options.resolveTemplateUrl;

if (!this.resolveStylesUrls && !this.resolveTemplateUrl) {
throw new Error(`resolveStylesUrls and resolveTemplateUrl mustn't both be false`);
}
}

UrlResolvePlugin.prototype.apply = function (compiler) {
compiler.plugin("make", (compilation, callback) => {
const aotPlugin = getAotPlugin(compilation);
aotPlugin._program.getSourceFiles()
.forEach(sf => this.usePlatformUrl(sf));

callback();
})
};

function getAotPlugin(compilation) {
let maybeAotPlugin = compilation._ngToolsWebpackPluginInstance;
if (!maybeAotPlugin) {
throw new Error(`This plugin must be used with the AotPlugin!`);
}

return maybeAotPlugin;
}

UrlResolvePlugin.prototype.usePlatformUrl = function(sourceFile) {
this.setCurrentDirectory(sourceFile);
ts.forEachChild(sourceFile, node => this.traverseDecorators(node));
}

UrlResolvePlugin.prototype.setCurrentDirectory = function(sourceFile) {
this.currentDirectory = path.resolve(sourceFile.path, "..");
}

UrlResolvePlugin.prototype.traverseDecorators = function(node) {
if (node.kind !== ts.SyntaxKind.ClassDeclaration || !node.decorators) {
return;
}

node.decorators.forEach(decorator => {
this.traverseDecoratorArguments(decorator.expression.arguments);
});
}

UrlResolvePlugin.prototype.traverseDecoratorArguments = function(args) {
args.forEach(arg => arg.properties && this.traverseProperties(arg.properties));
}

UrlResolvePlugin.prototype.traverseProperties = function(properties) {
properties
.filter(prop => this.isRelevantNode(prop))
.forEach(prop => this.traversePropertyElements(prop));
}

UrlResolvePlugin.prototype.isRelevantNode = function(property) {
return this.resolveStylesUrls && property.name.text === "styleUrls" ||
this.resolveTemplateUrl && property.name.text === "templateUrl"
}

UrlResolvePlugin.prototype.traversePropertyElements = function(property) {
const elements = property.initializer.elements === undefined ? [property.initializer] : property.initializer.elements;

elements
.filter(el => !!el.text)
.filter(el => this.notPlatformUrl(el.text))
.filter(el => this.noMultiplatformFile(el.text))
.forEach(el => this.replaceUrlsValue(el));
}

UrlResolvePlugin.prototype.notPlatformUrl = function(url) {
let extensionStartIndex = url.lastIndexOf(".");
let extension = url.slice(extensionStartIndex);

return !url.endsWith(`.${this.platform}${extension}`);
}

UrlResolvePlugin.prototype.noMultiplatformFile = function(url) {
let filePath = path.resolve(this.currentDirectory, url);

return !fs.existsSync(filePath);
}

UrlResolvePlugin.prototype.replaceUrlsValue = function(element) {
const extensionStartIndex = element.text.lastIndexOf(".");
const prefix = element.text.slice(0, extensionStartIndex);
const currentExtension = element.text.slice(extensionStartIndex);

element.text = `${prefix}.${this.platform}${currentExtension}`;
}

return UrlResolvePlugin;
})();

module.exports = UrlResolvePlugin;
9 changes: 6 additions & 3 deletions templates/webpack.angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,12 @@ function getPlugins(platform, env) {
typeChecking: false
}),

// Resolve .ios.css and .android.css component stylesheets
new nsWebpack.StyleUrlResolvePlugin({platform}),

// // 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) {
Expand Down