diff --git a/tns-xml-loader.js b/tns-xml-loader.js index 4779aa3e..f3671760 100644 --- a/tns-xml-loader.js +++ b/tns-xml-loader.js @@ -20,25 +20,59 @@ if (!global[ELEMENT_REGISTRY]) { }; } -module.exports = function (source, map) { +function parseResource(source, map) { this.cacheable(); - var loader = this; + let templateSource; + try { + templateSource = getTemplateSource(this.resourcePath, source); + } catch(e) { + this.emitWarning(e.message); + return this.callback(null, source, map); + } + + if (templateSource === "") { + return this.callback(null, source, map); + } var parser = new htmlparser.Parser({ onopentag: function (name, attribs) { // kebab-case to CamelCase var elementName = name.split("-").map(function (s) { return s[0].toUpperCase() + s.substring(1); }).join(""); + // Module path from element name var modulePath = MODULES[elementName] || UI_PATH + (elementName.toLowerCase().indexOf("layout") !== -1 ? "layouts/" : "") + elementName.split(/(?=[A-Z])/).join("-").toLowerCase(); + // Update ELEMENT_REGISTRY global[ELEMENT_REGISTRY][modulePath] = elementName; } }, { decodeEntities: true, lowerCaseTags: false }); - parser.write(source); + + parser.write(templateSource); parser.end(); - this.callback(null, source, map); -}; \ No newline at end of file + return this.callback(null, source, map); +} + +function getTemplateSource(path, source) { + if (isTemplate(path)) { + return source; + } else if (isComponent(path)) { + const templateMatcher = /template\s*:\s*([`'"])((.|\n)*?)\1/; + return templateMatcher.test(source) ? source.replace(templateMatcher, "$2") : ""; + } else { + throw new Error(`The NativeScript XML loader must be used with HTML, XML or TypeScript files`); + } +} + +function isComponent(resource) { + return /\.ts$/i.test(resource); +} + +function isTemplate(resource) { + return /\.html$|\.xml$/i.test(resource); +} + +module.exports = parseResource; diff --git a/webpack.common.js.angular.template b/webpack.common.js.angular.template index 61850fa7..725c4c1f 100644 --- a/webpack.common.js.angular.template +++ b/webpack.common.js.angular.template @@ -47,7 +47,7 @@ module.exports = function (platform, destinationApp) { ]), // Exclude explicitly required but never declared in XML elements. - // Loader nativescript-dev-webpack/tns-xml-loader should be added for *.xml/html files. + // Loader nativescript-dev-webpack/tns-xml-loader should be added for *.xml/html and *.ts files. new nsWebpack.ExcludeUnusedElementsPlugin(), //Angular AOT compiler @@ -109,7 +109,7 @@ module.exports = function (platform, destinationApp) { test: /\.html$|\.xml$/, loaders: [ "raw-loader", - 'nativescript-dev-webpack/tns-xml-loader' + "nativescript-dev-webpack/tns-xml-loader", ] }, // Root app.css file gets extracted with bundled dependencies @@ -133,6 +133,7 @@ module.exports = function (platform, destinationApp) { { test: /\.ts$/, loaders: [ + "nativescript-dev-webpack/tns-xml-loader", "nativescript-dev-webpack/tns-aot-loader", "@ngtools/webpack", ]