Skip to content

Commit 0452994

Browse files
[ts-plugins] append extension to dynamic imports (#14)
1 parent ef50bfb commit 0452994

File tree

3 files changed

+44
-19
lines changed

3 files changed

+44
-19
lines changed

modules/ts-plugins/src/ts-transform-append-extension/index.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,24 @@ export default function (
3939
extMappings.set(base, addition);
4040
}
4141

42-
function shouldMutateModuleSpecifier(node: Node): string | false {
43-
if (!ts.isImportDeclaration(node) && !ts.isExportDeclaration(node)) return false;
44-
if (node.moduleSpecifier === undefined) return false;
45-
// only when module specifier is valid
46-
if (!ts.isStringLiteral(node.moduleSpecifier)) return false;
42+
function shouldMutateImportSource(node: Node | undefined): string | false {
43+
if (!node || !ts.isStringLiteral(node)) return false;
4744
// only when path is relative
48-
if (!node.moduleSpecifier.text.startsWith('./') && !node.moduleSpecifier.text.startsWith('../'))
49-
return false;
45+
if (!node.text.startsWith('./') && !node.text.startsWith('../')) return false;
5046
// only when module specifier has accepted extension
51-
const ext = path.extname(node.moduleSpecifier.text);
47+
const ext = path.extname(node.text);
5248
if (!extMappings.has(ext)) return false;
53-
return node.moduleSpecifier.text + extMappings.get(ext);
49+
return node.text + extMappings.get(ext);
5450
}
5551

5652
return (ctx: TransformationContext) => {
5753
const {factory} = ctx;
5854

5955
return (sourceFile: SourceFile) => {
6056
function visit(node: Node): Node {
61-
const newImportSource = shouldMutateModuleSpecifier(node);
62-
if (newImportSource) {
63-
if (ts.isImportDeclaration(node)) {
57+
if (ts.isImportDeclaration(node)) {
58+
const newImportSource = shouldMutateImportSource(node.moduleSpecifier);
59+
if (newImportSource) {
6460
const newModuleSpecifier = factory.createStringLiteral(newImportSource);
6561
node = factory.updateImportDeclaration(
6662
node,
@@ -69,7 +65,10 @@ export default function (
6965
newModuleSpecifier,
7066
node.assertClause
7167
);
72-
} else if (ts.isExportDeclaration(node)) {
68+
}
69+
} else if (ts.isExportDeclaration(node)) {
70+
const newImportSource = shouldMutateImportSource(node.moduleSpecifier);
71+
if (newImportSource) {
7372
const newModuleSpecifier = factory.createStringLiteral(newImportSource);
7473
node = factory.updateExportDeclaration(
7574
node,
@@ -80,6 +79,16 @@ export default function (
8079
node.assertClause
8180
);
8281
}
82+
} else if (
83+
ts.isCallExpression(node) &&
84+
node.expression.kind === ts.SyntaxKind.ImportKeyword
85+
) {
86+
const newImportSource = shouldMutateImportSource(node.arguments[0]);
87+
if (newImportSource) {
88+
const newArgs = node.arguments.slice();
89+
newArgs[0] = factory.createStringLiteral(newImportSource);
90+
node = factory.updateCallExpression(node, node.expression, node.typeArguments, newArgs);
91+
}
8392
}
8493

8594
return ts.visitEachChild(node, visit, ctx);

modules/ts-plugins/test/test-transformer.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export function assertSourceEqual(
6868
*/
6969
ignoreEmptyLines?: boolean;
7070
} = {}
71-
): true | Error {
71+
): true | string {
7272
const {ignoreIndent = true, ignoreEmptyLines = true} = options;
7373
const actualLines = actual.split('\n');
7474
const expectedLines = expected.split('\n');
@@ -90,10 +90,9 @@ export function assertSourceEqual(
9090
} else if (ignoreEmptyLines && !t2) {
9191
i2++;
9292
} else {
93-
return new Error(`Mismatch at line ${i1}
93+
return `Mismatch at line ${i1}
9494
Actual: ${t1}
95-
Expected: ${t2}
96-
`);
95+
Expected: ${t2}`;
9796
}
9897
}
9998
return true;

modules/ts-plugins/test/ts-transform-append-extension.spec.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@ import {transpile, assertSourceEqual} from './test-transformer.js';
33
// @ts-expect-error Aliased import, remapped to valid path in esm-loader
44
import appendExtension from '@vis.gl/ts-plugins/ts-transform-append-extension';
55

6-
const input = `\
6+
const input1 = `\
77
export type { TypedArray } from "./types";
88
export { add } from "./math/add";
99
import vs from "../shaders/vs.glsl";
1010
import { Shader } from "@luma.gl/core";
1111
export { vs, Shader };`;
1212

13+
const input2 = `\
14+
const throttle = await import("lodash.throttle");
15+
const Matrix4 = import("./math/matrix4");
16+
import("./shaders").then((modules) => { });`;
17+
1318
const testCases = [
1419
{
1520
title: 'add default extension to js imports',
1621
config: {after: true},
22+
input: input1,
1723
output: `\
1824
export { add } from "./math/add.js";
1925
import vs from "../shaders/vs.glsl";
@@ -23,6 +29,7 @@ export { vs, Shader };`
2329
{
2430
title: 'add default extension to d.ts imports',
2531
config: {afterDeclarations: true},
32+
input: input1,
2633
output: `\
2734
export type { TypedArray } from "./types.js";
2835
export { add } from "./math/add.js";
@@ -33,18 +40,28 @@ export { vs, Shader };`
3340
{
3441
title: 'add custom extension to js imports',
3542
config: {after: true, extensions: ['.mjs', '.glsl.mjs']},
43+
input: input1,
3644
output: `\
3745
export { add } from "./math/add.mjs";
3846
import vs from "../shaders/vs.glsl.mjs";
3947
import { Shader } from "@luma.gl/core";
4048
export { vs, Shader };`
49+
},
50+
{
51+
title: 'dynamic imports',
52+
config: {after: true},
53+
input: input2,
54+
output: `\
55+
const throttle = await import("lodash.throttle");
56+
const Matrix4 = import("./math/matrix4.js");
57+
import("./shaders.js").then((modules) => { });`
4158
}
4259
];
4360

4461
test('ts-transform-append-extension', (t) => {
4562
for (const testCase of testCases) {
4663
const result = transpile({
47-
source: input,
64+
source: testCase.input,
4865
transformer: appendExtension,
4966
config: testCase.config,
5067
outputType: testCase.config.afterDeclarations ? 'd.ts' : 'js'

0 commit comments

Comments
 (0)