-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
88 lines (72 loc) · 2.44 KB
/
index.js
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
84
85
86
87
88
'use strict';
const path = require('path');
const template = require('@babel/template').default;
const inherits = require('@babel/plugin-syntax-import-meta').default;
const importStyles = {
amd: 'new URL(module.uri).href',
cjs: 'new URL(__filename, document.baseURI).href',
esm: 'import.meta.url',
iife: 'document.currentScript && document.currentScript.src || document.baseURI',
umd: 'document.currentScript && document.currentScript.src || document.baseURI',
system: 'module.meta.url',
baseURI: 'document.baseURI'
};
module.exports = () => ({
inherits,
visitor: {
Program(progPath, {opts, file}) {
const metas = [];
const identifiers = new Set();
const {sourceFileName} = file.opts.parserOpts;
progPath.traverse({
MetaProperty(path) {
const {node, scope} = path;
/* istanbul ignore else */
if (node.meta && node.meta.name === 'import' && node.property.name === 'meta') {
metas.push(path);
}
for (const name of Object.keys(scope.getAllBindings())) {
identifiers.add(name);
}
}
});
if (metas.length === 0) {
return;
}
let metaId = 'importMeta';
while (identifiers.has(metaId)) {
metaId = progPath.scope.generateUidIdentifier('importMeta').name;
}
/* Check longest basePaths first. */
const mappings = Object.entries(opts.mappings || {}).reduce((acc, [filePath, baseURL]) => {
acc[path.resolve(filePath)] = baseURL;
return acc;
}, {});
const basePaths = Object.keys(mappings).sort((a, b) => b.length - a.length);
let relativeURL;
for (const basePath of basePaths) {
if (sourceFileName.startsWith(basePath)) {
relativeURL = sourceFileName.replace(basePath, mappings[basePath]);
break;
}
}
if (typeof relativeURL === 'undefined') {
const bundleDir = opts.bundleDir ? path.resolve(opts.bundleDir) : process.cwd();
if (!sourceFileName.startsWith(bundleDir)) {
throw new Error('Does not match any mappings or bundleDir.');
}
relativeURL = sourceFileName.replace(bundleDir, '.');
}
/* istanbul ignore next */
if (path.sep === path.win32.sep) {
relativeURL = relativeURL.split(path.sep).join(path.posix.sep);
}
progPath.node.body.unshift(template.ast(`const ${metaId} = {
url: new URL('${relativeURL}', ${importStyles[opts.importStyle] || importStyles.esm}).href
};`, {plugins: ['importMeta']}));
for (const meta of metas) {
meta.replaceWith(template.ast`${metaId}`);
}
}
}
});