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

fix(JS/TS): use webpack resolver instead of Node.js resolver #681

Merged
merged 6 commits into from
Dec 13, 2018
Merged
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
147 changes: 80 additions & 67 deletions xml-namespace-loader.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
const { parse, relative, join, basename, extname } = require("path");
const { promisify } = require('util');
const { convertSlashesInPath } = require("./projectHelpers");

module.exports = function (source) {
this.value = source;
const { ignore } = this.query;
const callback = this.async();

const { XmlParser } = require("tns-core-modules/xml");

let namespaces = [];
const resolvePromise = promisify(this.resolve);
const promises = [];

const namespaces = [];
const parser = new XmlParser((event) => {
const { namespace, elementName } = event;
const moduleName = `${namespace}/${elementName}`;
Expand All @@ -20,83 +25,91 @@ module.exports = function (source) {
) {
const localNamespacePath = join(this.rootContext, namespace);
const localModulePath = join(localNamespacePath, elementName);
const resolvedPath = tryResolve(localNamespacePath) ||
tryResolve(localModulePath);

if (!resolvedPath) {
const xml = tryResolve(`${localModulePath}.xml`);
if (!xml) {
namespaces.push({ name: namespace, path: namespace });
namespaces.push({ name: moduleName, path: namespace });

return;
} else {
namespaces.push({ name: `${moduleName}.xml`, path: xml });
namespaces.push({ name: moduleName, path: xml });
this.addDependency(xml);
}

const css = tryResolve(`${localModulePath}.css`);
if (css) {
namespaces.push({ name: `${moduleName}.css`, path: css });
this.addDependency(css);
}

return;
}

this.addDependency(resolvedPath);

namespaces.push({ name: namespace, path: resolvedPath });
namespaces.push({ name: moduleName, path: resolvedPath });

const { dir, name } = parse(resolvedPath);
const noExtFilename = join(dir, name);

const xml = tryResolve(`${noExtFilename}.xml`);
if (xml) {
this.addDependency(xml);
namespaces.push({ name: `${moduleName}.xml`, path: xml });
}

const css = tryResolve(`${noExtFilename}.css`);
if (css) {
this.addDependency(css);
namespaces.push({ name: `${moduleName}.css`, path: css });
}

const pathResolved = (resolvedPath) => {
this.addDependency(resolvedPath);

namespaces.push({ name: namespace, path: resolvedPath });
namespaces.push({ name: moduleName, path: resolvedPath });

const { dir, name } = parse(resolvedPath);
const noExtFilename = join(dir, name);

return Promise.all([
resolvePromise(this.context, `${noExtFilename}.xml`)
.then((xml) => {
this.addDependency(xml);
namespaces.push({ name: `${moduleName}.xml`, path: xml });
})
.catch((err) => {}),

resolvePromise(this.context, `${noExtFilename}.css`)
.then((xml) => {
this.addDependency(xml);
namespaces.push({ name: `${moduleName}.css`, path: css });
})
.catch((err) => {})
]);
};

promises.push(resolvePromise(this.context, localNamespacePath)
.then(path => pathResolved(path))
.catch(() => {
return promise = resolvePromise(this.context, localModulePath)
.then(path => pathResolved(path))
.catch(() => {
return Promise.all([
resolvePromise(this.context, `${localModulePath}.xml`)
.then((xml) => {
namespaces.push({ name: `${moduleName}.xml`, path: xml });
namespaces.push({ name: moduleName, path: xml });
this.addDependency(xml);
})
.catch(() => {
namespaces.push({ name: namespace, path: namespace });
namespaces.push({ name: moduleName, path: namespace });
}),

resolvePromise(this.context, `${localModulePath}.css`)
.then((css) => {
namespaces.push({ name: `${moduleName}.css`, path: css });
this.addDependency(css);
})
.catch(() => {})
]);

});
})
);
}
}, undefined, true);

parser.parse(source);

const moduleRegisters = namespaces
.map(convertPath)
.map(n =>
`global.registerModule("${n.name}", function() { return require("${n.path}"); });`
)
.join("");
Promise.all(promises).then(() => {
const moduleRegisters = namespaces
.map(convertPath)
.map(n =>
`global.registerModule("${n.name}", function() { return require("${n.path}"); });`
)
.join("");

// escape special whitespace characters
// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Issue_with_plain_JSON.stringify_for_use_as_JavaScript
const json = JSON.stringify(source)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');

// escape special whitespace characters
// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Issue_with_plain_JSON.stringify_for_use_as_JavaScript
const json = JSON.stringify(source)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
const wrapped = `${moduleRegisters}\nmodule.exports = ${json}`;

const wrapped = `${moduleRegisters}\nmodule.exports = ${json};`;
callback(null, wrapped);
}).catch((err) => {
callback(err);
})

this.callback(null, wrapped);
}

function convertPath(obj) {
obj.path = convertSlashesInPath(obj.path);
return obj;
}

function tryResolve(path) {
try {
return require.resolve(path);
} catch (e) {
// The path couldn't be resolved
return;
}
}