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

Feat: add plugin to support android/ios styleUrls #47

Merged
merged 2 commits into from
Jan 5, 2017
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: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ var sources = require("webpack-sources");
var fs = require("fs");
var path = require("path");

exports.StyleUrlResolvePlugin = require('./resource-resolver-plugins/StyleUrlResolvePlugin');

//HACK: changes the JSONP chunk eval function to `global["nativescriptJsonp"]`
// applied to tns-java-classes.js only
exports.NativeScriptJsonpPlugin = function(options) {
Expand Down
96 changes: 96 additions & 0 deletions resource-resolver-plugins/StyleUrlResolvePlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const ts = require("typescript");
const fs = require("fs");
const path = require("path");

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

this.platform = options.platform;
}

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

callback();
})
};

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

return maybeAotPlugin;
}

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

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

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

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

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

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

function isStyleUrls(property) {
return property.name.text === "styleUrls";
}

StyleUrlResolvePlugin.prototype.traversePropertyElements = function(property) {
property.initializer.elements
.filter(el => this.notPlatformUrl(el.text))
.filter(el => this.noMultiplatformFile(el.text))
.forEach(el => this.replaceStyleUrlsValue(el));
}

StyleUrlResolvePlugin.prototype.notPlatformUrl = function(styleUrl) {
let extensionStartIndex = styleUrl.lastIndexOf(".");
let extension = styleUrl.slice(extensionStartIndex);

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

StyleUrlResolvePlugin.prototype.noMultiplatformFile = function(styleUrl) {
let stylePath = path.resolve(this.currentDirectory, styleUrl);

return !fs.existsSync(stylePath);
}

StyleUrlResolvePlugin.prototype.replaceStyleUrlsValue = function(element) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use a regex here 😁

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 StyleUrlResolvePlugin;
})();

module.exports = StyleUrlResolvePlugin;
1 change: 1 addition & 0 deletions webpack.common.js.angular.template
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ module.exports = function (platform, destinationApp) {
entryModule: path.resolve(__dirname, "app/app.module#AppModule"),
typeChecking: false
}),
new nsWebpack.StyleUrlResolvePlugin({platform}),
];

if (process.env.npm_config_uglify) {
Expand Down