From 94a65d05254dc1ad13aeb4e3b0a424952ae61124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Veyret?= Date: Wed, 2 Sep 2020 15:01:34 +0200 Subject: [PATCH] Try to use node resolution for module path This will allow assets to be in external modules. Issue #3 --- .gitignore | 1 + __test__/node_modules/dummy/picture.svg | 8 +++++ __test__/package/success.ts | 22 ++++++++++++ __test__/success.ts | 2 +- src/context/AssetModuleManager.ts | 23 +++++++++--- src/index.spec.ts | 48 ++++++++++++++----------- 6 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 __test__/node_modules/dummy/picture.svg create mode 100644 __test__/package/success.ts diff --git a/.gitignore b/.gitignore index 587bba5..8d540ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Binaries node_modules/ dist/ +!__test__/node_modules # Coverage .nyc_output/ diff --git a/__test__/node_modules/dummy/picture.svg b/__test__/node_modules/dummy/picture.svg new file mode 100644 index 0000000..e7b9664 --- /dev/null +++ b/__test__/node_modules/dummy/picture.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/__test__/package/success.ts b/__test__/package/success.ts new file mode 100644 index 0000000..453ed1a --- /dev/null +++ b/__test__/package/success.ts @@ -0,0 +1,22 @@ +import * as pngImage from '../sub/folder/image.png' +import svgImage from '../image.svg' +import moduleImage from 'dummy/picture.svg' +import defaultImage from '../reexport' +import { image } from '../reexport' + +export default function getPath( + type: 'fullImport' | 'defaultImport' | 'moduleImport' | 'defaultExport' | 'namedExport' +): string { + switch (type) { + case 'fullImport': + return pngImage + case 'defaultImport': + return svgImage + case 'moduleImport': + return moduleImage + case 'defaultExport': + return defaultImage + case 'namedExport': + return image + } +} diff --git a/__test__/success.ts b/__test__/success.ts index e1b936f..c179732 100644 --- a/__test__/success.ts +++ b/__test__/success.ts @@ -1,6 +1,6 @@ import * as pngImage from './sub/folder/image.png' import svgImage from './image.svg' -import moduleImage from 'module/image.svg' +import moduleImage from 'dummy/picture.svg' import defaultImage from './reexport' import { image } from './reexport' diff --git a/src/context/AssetModuleManager.ts b/src/context/AssetModuleManager.ts index 27983c8..3146798 100644 --- a/src/context/AssetModuleManager.ts +++ b/src/context/AssetModuleManager.ts @@ -40,7 +40,7 @@ export default class AssetModuleManager { // Check if matching assets pattern if (this.assetsMatch.test(moduleName)) { - return this.interpolateName(moduleName) + return this.interpolateName(this.findModulePath(moduleName)) } } return undefined @@ -49,11 +49,10 @@ export default class AssetModuleManager { /** * Create the asset name using `targetName` template and given module name. * - * @param moduleName - The name of module to use as interpolation source. + * @param modulePath - The path of module to use as interpolation source. * @returns The asset name. */ - private interpolateName(moduleName: string): string { - const modulePath = join(this.currentPath, moduleName) + private interpolateName(modulePath: string): string { const parsed = parse(modulePath) /* istanbul ignore next */ const ext = parsed.ext ? parsed.ext.substr(1) : 'bin' @@ -91,4 +90,20 @@ export default class AssetModuleManager { .replace(/\[folder\]/gi, folder) return url } + + /** + * Find the module path, using default node resolution, or simply searching relative to current file. + * + * @param moduleName - The name of the module to find. + * @returns The module path. + */ + private findModulePath(moduleName: string): string { + try { + return require.resolve(moduleName, { + paths: [this.basePath], + }) + } catch { + return join(this.currentPath, moduleName) + } + } } diff --git a/src/index.spec.ts b/src/index.spec.ts index 4acbbe6..c55f55e 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -15,7 +15,7 @@ describe('ts-transform-asset', function () { result: { fullImport: string defaultImport: string - moduleImport: string + moduleImport: string | undefined defaultExport: string namedExport: string } @@ -26,7 +26,7 @@ describe('ts-transform-asset', function () { result: { fullImport: 'image.png', defaultImport: 'image.svg', - moduleImport: 'image.svg', + moduleImport: 'picture.svg', defaultExport: 'image.svg', namedExport: 'image.svg', }, @@ -36,16 +36,17 @@ describe('ts-transform-asset', function () { result: { fullImport: 'assets/image.png', defaultImport: 'assets/image.svg', - moduleImport: 'assets/image.svg', + moduleImport: 'assets/picture.svg', defaultExport: 'assets/image.svg', namedExport: 'assets/image.svg', }, }, default: { + rootDir: '__test__', result: { fullImport: '[hash].png', defaultImport: 'b05767c238cb9f989cf3cd8180594878.svg', - moduleImport: '[hash].svg', + moduleImport: 'bee0f4fbbfd53e62289432b4a070cd03.svg', defaultExport: 'b05767c238cb9f989cf3cd8180594878.svg', namedExport: 'b05767c238cb9f989cf3cd8180594878.svg', }, @@ -56,7 +57,8 @@ describe('ts-transform-asset', function () { result: { fullImport: 'sub/folder/folder_[hash]-[contenthash].png', defaultImport: '_b05767c238cb9f989cf3cd8180594878-b05767c238cb9f989cf3cd8180594878.svg', - moduleImport: 'module/module_[hash]-[contenthash].svg', + moduleImport: + 'node_modules/dummy/dummy_bee0f4fbbfd53e62289432b4a070cd03-bee0f4fbbfd53e62289432b4a070cd03.svg', defaultExport: '_b05767c238cb9f989cf3cd8180594878-b05767c238cb9f989cf3cd8180594878.svg', namedExport: '_b05767c238cb9f989cf3cd8180594878-b05767c238cb9f989cf3cd8180594878.svg', }, @@ -67,7 +69,7 @@ describe('ts-transform-asset', function () { fullImport: '__test__/sub/folder/folder_[hash]-[contenthash].png', defaultImport: '__test__/__test___b05767c238cb9f989cf3cd8180594878-b05767c238cb9f989cf3cd8180594878.svg', - moduleImport: '__test__/module/module_[hash]-[contenthash].svg', + moduleImport: undefined, defaultExport: '__test__/__test___b05767c238cb9f989cf3cd8180594878-b05767c238cb9f989cf3cd8180594878.svg', namedExport: @@ -109,24 +111,30 @@ describe('ts-transform-asset', function () { result.print() }) - it('should find full module import file', function () { - expect(result.requireContent('success')('fullImport')).to.equal(testCase.result.fullImport) - }) + Array.of('success', 'package/success').forEach(file => { + describe(`...in file ${file}`, function () { + it('should find full module import file', function () { + expect(result.requireContent(file)('fullImport')).to.equal(testCase.result.fullImport) + }) - it('should find default module import file', function () { - expect(result.requireContent('success')('defaultImport')).to.equal(testCase.result.defaultImport) - }) + it('should find default module import file', function () { + expect(result.requireContent(file)('defaultImport')).to.equal(testCase.result.defaultImport) + }) - it('should find external module file', function () { - expect(result.requireContent('success')('moduleImport')).to.equal(testCase.result.moduleImport) - }) + if (testCase.result.moduleImport) { + it('should find external module file', function () { + expect(result.requireContent(file)('moduleImport')).to.equal(testCase.result.moduleImport) + }) + } - it('should find default re-exported file', function () { - expect(result.requireContent('success')('defaultExport')).to.equal(testCase.result.defaultExport) - }) + it('should find default re-exported file', function () { + expect(result.requireContent(file)('defaultExport')).to.equal(testCase.result.defaultExport) + }) - it('should find named re-exported file', function () { - expect(result.requireContent('success')('namedExport')).to.equal(testCase.result.namedExport) + it('should find named re-exported file', function () { + expect(result.requireContent(file)('namedExport')).to.equal(testCase.result.namedExport) + }) + }) }) it('should fail to require bad module', function () {