1 | /**
|
2 | * @license
|
3 | * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
|
4 | * This code may only be used under the BSD style license found at
|
5 | * http://polymer.github.io/LICENSE.txt
|
6 | * The complete set of authors may be found at
|
7 | * http://polymer.github.io/AUTHORS.txt
|
8 | * The complete set of contributors may be found at
|
9 | * http://polymer.github.io/CONTRIBUTORS.txt
|
10 | * Code distributed by Google as part of the polymer project is also
|
11 | * subject to an additional IP rights grant found at
|
12 | * http://polymer.github.io/PATENTS.txt
|
13 | */
|
14 |
|
15 | import importMetaSyntax from '@babel/plugin-syntax-import-meta';
|
16 | import template from '@babel/template';
|
17 | import {NodePath} from '@babel/traverse';
|
18 | import {Program, MetaProperty} from '@babel/types';
|
19 |
|
20 | const ast = template.ast;
|
21 |
|
22 | /**
|
23 | * Rewrites `import.meta`[1] into an import for a module named "meta". It is
|
24 | * expected this plugin runs alongside @babel/plugin-transform-modules-amd which
|
25 | * will transform this import into an AMD dependency, and is loaded using
|
26 | * @polymer/esm-amd-loader which will provide an object with a `url`[2] property
|
27 | * for the "meta" dependency.
|
28 | *
|
29 | * [1]: https://github.com/tc39/proposal-import-meta
|
30 | * [2]: https://html.spec.whatwg.org/#hostgetimportmetaproperties
|
31 | */
|
32 | export const rewriteImportMeta = {
|
33 | inherits: importMetaSyntax,
|
34 |
|
35 | visitor: {
|
36 | Program(path: NodePath<Program>) {
|
37 | const metas: NodePath<MetaProperty>[] = [];
|
38 | const identifiers = new Set<string>();
|
39 |
|
40 | path.traverse({
|
41 | MetaProperty(path: NodePath<MetaProperty>) {
|
42 | const node = path.node;
|
43 | if (node.meta && node.meta.name === 'import' &&
|
44 | node.property.name === 'meta') {
|
45 | metas.push(path);
|
46 | for (const name of Object.keys(path.scope.getAllBindings())) {
|
47 | identifiers.add(name);
|
48 | }
|
49 | }
|
50 | }
|
51 | });
|
52 |
|
53 | if (metas.length === 0) {
|
54 | return;
|
55 | }
|
56 |
|
57 | let metaId = 'meta';
|
58 | while (identifiers.has(metaId)) {
|
59 | metaId = path.scope.generateUidIdentifier('meta').name;
|
60 | }
|
61 |
|
62 | path.node.body.unshift(ast`import * as ${metaId} from 'meta';`);
|
63 | for (const meta of metas) {
|
64 | meta.replaceWith(ast`${metaId}`);
|
65 | }
|
66 | },
|
67 | }
|
68 | };
|