From 191884d5af36f3cb9dfeef849effc62cbc5f2f66 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sat, 17 Jun 2023 15:58:41 +0300 Subject: [PATCH] support relative import --- js/bundler/bundler.js | 72 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/js/bundler/bundler.js b/js/bundler/bundler.js index 8f3de68d35..cccca6bb6b 100644 --- a/js/bundler/bundler.js +++ b/js/bundler/bundler.js @@ -451,7 +451,7 @@ class Bundler { return; } - let dep = this.#normalizeModModuleName(node.text); + let dep = this.#normalizeModModuleId(node.text); deps.push(dep); }); @@ -466,31 +466,77 @@ class Bundler { /** * @param {string} sourceFile - * @param {string} mod + * @param {string} subjectId * @return {string[]} */ - #obtainModuleDeps(sourceFile, mod) { + #obtainModuleDeps(sourceFile, subjectId) { return sourceFile.statements .filter(item => item.importClause && item.moduleSpecifier) .map(item => item.moduleSpecifier.text) - .map(/** string */item => { + .map(/** string */id => { + id = this.#normalizeIdPath(id, subjectId); - // @todo Normalize relative path. - - return this.#normalizeModModuleName(item); + return this.#normalizeModModuleId(id); }); } /** - * @param {string} module - * @return {string} + * @param {string} id + * @param {string} subjectId + * @private */ - #normalizeModModuleName(module) { - if (!module.includes(':')) { - return module; + #normalizeIdPath(id, subjectId) { + if (id.at(0) !== '.') { + return id; } - let [mod, part] = module.split(':'); + if (id.slice(0, 2) !== './' && id.slice(0, 3) !== '../') { + return id; + } + + let outputPath = id; + + let dirParts = subjectId.split('/').slice(0, -1); + + if (id.slice(0, 2) === './') { + outputPath = dirParts.join('/') + '/' + id.slice(2); + } + + let parts = outputPath.split('/'); + + let up = 0; + + for (let part of parts) { + if (part === '..') { + up++; + + continue; + } + + break; + } + + if (!up) { + return outputPath; + } + + if (up) { + outputPath = dirParts.slice(0, -up).join('/') + '/' + outputPath.slice(3 * up); + } + + return outputPath; + } + + /** + * @param {string} id + * @return {string} + */ + #normalizeModModuleId(id) { + if (!id.includes(':')) { + return id; + } + + let [mod, part] = id.split(':'); return `modules/${mod}/` + part; }