-
Notifications
You must be signed in to change notification settings - Fork 403
/
Copy pathdynamic-imports.ts
83 lines (73 loc) · 2.64 KB
/
dynamic-imports.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import { NodePath } from '@babel/traverse';
import { types, Visitor } from '@babel/core';
import { addNamed } from '@babel/helper-module-imports';
import { CompilerMetrics, LWCClassErrors } from '@lwc/errors';
import { generateError, incrementMetricCounter } from './utils';
import { LwcBabelPluginPass } from './types';
function getImportSource(path: NodePath<types.Import>): NodePath<types.Node> {
return path.parentPath.get('arguments.0') as NodePath<types.Node>;
}
function validateImport(sourcePath: NodePath<types.Node>, state: LwcBabelPluginPass) {
if (!sourcePath.isStringLiteral()) {
throw generateError(
sourcePath,
{
errorInfo: LWCClassErrors.INVALID_DYNAMIC_IMPORT_SOURCE_STRICT,
messageArgs: [String(sourcePath)],
},
state
);
}
}
/**
* Expected API for this plugin:
* { dynamicImports: { loader: string, strictSpecifier: boolean } }
*/
export default function (): Visitor<LwcBabelPluginPass> {
function getLoaderRef(
path: NodePath<types.Import>,
loaderName: string,
state: LwcBabelPluginPass
): types.Identifier {
if (!state.loaderRef) {
state.loaderRef = addNamed(path, 'load', loaderName);
}
return state.loaderRef;
}
function addDynamicImportDependency(dependency: string, state: LwcBabelPluginPass) {
// TODO [#3444]: state.dynamicImports seems unused and can probably be deleted
if (!state.dynamicImports) {
state.dynamicImports = [];
}
if (!state.dynamicImports.includes(dependency)) {
state.dynamicImports.push(dependency);
}
}
return {
Import(path, state) {
const { dynamicImports } = state.opts;
if (!dynamicImports) {
return;
}
const { loader, strictSpecifier } = dynamicImports;
const sourcePath = getImportSource(path);
if (strictSpecifier) {
validateImport(sourcePath, state);
}
if (loader) {
const loaderId = getLoaderRef(path, loader, state);
path.replaceWith(loaderId);
incrementMetricCounter(CompilerMetrics.DynamicImportTransform, state);
}
if (sourcePath.isStringLiteral()) {
addDynamicImportDependency(sourcePath.node.value, state);
}
},
};
}