1 | const ts = require('typescript');
|
2 |
|
3 | const rewritePath = (importPath, { alias, regexes }) => {
|
4 | const patterns = Object.keys(alias);
|
5 |
|
6 | for (const pattern of patterns) {
|
7 | const regex = regexes[pattern];
|
8 | if (regex.test(importPath)) {
|
9 | return importPath.replace(regex, alias[pattern]);
|
10 | }
|
11 | }
|
12 |
|
13 | return importPath;
|
14 | };
|
15 |
|
16 | const isDynamicImport = node =>
|
17 | ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword;
|
18 |
|
19 | const visitor = (ctx, sf, options) => {
|
20 | const _visitor = node => {
|
21 | let importPath;
|
22 | if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier) {
|
23 | const importPathWithQuotes = node.moduleSpecifier.getText(sf);
|
24 | importPath = importPathWithQuotes.substr(1, importPathWithQuotes.length - 2);
|
25 | } else if (isDynamicImport(node)) {
|
26 | const importPathWithQuotes = node.arguments[0].getText(sf);
|
27 | importPath = importPathWithQuotes.substr(1, importPathWithQuotes.length - 2);
|
28 | } else if (ts.isImportTypeNode(node) &&
|
29 | ts.isLiteralTypeNode(node.argument) &&
|
30 | ts.isStringLiteral(node.argument.literal)) {
|
31 | importPath = node.argument.literal.text;
|
32 | }
|
33 | if (importPath) {
|
34 | const rewrittenPath = rewritePath(importPath, options);
|
35 | const newNode = ts.getMutableClone(node);
|
36 | if (rewrittenPath !== importPath) {
|
37 | if (ts.isImportDeclaration(newNode) || ts.isExportDeclaration(newNode)) {
|
38 | newNode.moduleSpecifier = ts.createLiteral(rewrittenPath);
|
39 | } else if (isDynamicImport(newNode)) {
|
40 | newNode.arguments = ts.createNodeArray([ts.createStringLiteral(rewrittenPath)]);
|
41 | } else if (ts.isImportTypeNode(newNode)) {
|
42 | newNode.argument = ts.createLiteralTypeNode(ts.createStringLiteral(rewrittenPath));
|
43 | }
|
44 | return newNode;
|
45 | }
|
46 | }
|
47 | return ts.visitEachChild(node, _visitor, ctx);
|
48 | };
|
49 | return _visitor;
|
50 | };
|
51 |
|
52 | const rewrite = options => {
|
53 | const { alias = {} } = options;
|
54 |
|
55 | options.regexes = Object.keys(alias).reduce((stored, pattern) => ({
|
56 | ...stored, ...{ [pattern]: new RegExp(pattern) }
|
57 | }), {});
|
58 |
|
59 | return ctx => sf => ts.visitNode(sf, visitor(ctx, sf, options));
|
60 | };
|
61 |
|
62 | const snowpackImportRewriter = () =>
|
63 | rewrite({
|
64 | alias: {
|
65 | '^([a-z@][\\w\/-]+)$': '/modules/$1.js'
|
66 | }
|
67 | })
|
68 |
|
69 |
|
70 |
|
71 | module.exports = { rewrite, snowpackImportRewriter };
|