source: imaps-frontend/node_modules/@babel/helpers/scripts/generate-helpers.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[d565449]1/* eslint-disable import/no-extraneous-dependencies */
2import fs from "fs";
3import { join } from "path";
4import { URL, fileURLToPath } from "url";
5import { minify } from "terser";
6import { babel, presetTypescript } from "$repo-utils/babel-top-level";
7import { IS_BABEL_8 } from "$repo-utils";
8import { gzipSync } from "zlib";
9
10import {
11 getHelperMetadata,
12 stringifyMetadata,
13} from "./build-helper-metadata.js";
14
15const HELPERS_FOLDER = new URL("../src/helpers", import.meta.url);
16const IGNORED_FILES = new Set(["package.json", "tsconfig.json"]);
17
18export default async function generateHelpers() {
19 let output = `/*
20 * This file is auto-generated! Do not modify it directly.
21 * To re-generate run 'yarn gulp generate-runtime-helpers'
22 */
23
24import template from "@babel/template";
25import type * as t from "@babel/types";
26
27interface Helper {
28 minVersion: string;
29 ast: () => t.Program;
30 metadata: HelperMetadata;
31}
32
33export interface HelperMetadata {
34 globals: string[];
35 locals: { [name: string]: string[] };
36 dependencies: { [name: string]: string[] };
37 exportBindingAssignments: string[];
38 exportName: string;
39}
40
41function helper(minVersion: string, source: string, metadata: HelperMetadata): Helper {
42 return Object.freeze({
43 minVersion,
44 ast: () => template.program.ast(source, { preserveComments: true }),
45 metadata,
46 })
47}
48
49export { helpers as default };
50const helpers: Record<string, Helper> = {
51 __proto__: null,
52`;
53
54 let babel7extraOutput = "";
55
56 for (const file of (await fs.promises.readdir(HELPERS_FOLDER)).sort()) {
57 if (IGNORED_FILES.has(file)) continue;
58 if (file.startsWith(".")) continue; // ignore e.g. vim swap files
59
60 const [helperName] = file.split(".");
61
62 const isTs = file.endsWith(".ts");
63
64 const filePath = join(fileURLToPath(HELPERS_FOLDER), file);
65 if (!file.endsWith(".js") && !isTs) {
66 console.error("ignoring", filePath);
67 continue;
68 }
69
70 let code = await fs.promises.readFile(filePath, "utf8");
71 const minVersionMatch = code.match(
72 /^\s*\/\*\s*@minVersion\s+(?<minVersion>\S+)\s*\*\/\s*$/m
73 );
74 if (!minVersionMatch) {
75 throw new Error(`@minVersion number missing in ${filePath}`);
76 }
77 const { minVersion } = minVersionMatch.groups;
78
79 const onlyBabel7 = code.includes("@onlyBabel7");
80 const mangleFns = code.includes("@mangleFns");
81 const noMangleFns = [];
82
83 code = babel.transformSync(code, {
84 configFile: false,
85 babelrc: false,
86 filename: filePath,
87 presets: [
88 [
89 presetTypescript,
90 {
91 onlyRemoveTypeImports: true,
92 optimizeConstEnums: true,
93 },
94 ],
95 ],
96 plugins: [
97 /**
98 * @type {import("@babel/core").PluginObj}
99 */
100 ({ types: t }) => ({
101 // These pre/post hooks are needed because the TS transform is,
102 // when building in the old Babel e2e test, removing the
103 // `export { OverloadYield as default }` in the OverloadYield helper.
104 // TODO: Remove in Babel 8.
105 pre(file) {
106 if (!process.env.IS_BABEL_OLD_E2E) return;
107 file.metadata.exportName = null;
108 file.path.traverse({
109 ExportSpecifier(path) {
110 if (path.node.exported.name === "default") {
111 file.metadata.exportName = path.node.local.name;
112 }
113 },
114 });
115 },
116 post(file) {
117 if (!process.env.IS_BABEL_OLD_E2E) return;
118 if (!file.metadata.exportName) return;
119 file.path.traverse({
120 ExportNamedDeclaration(path) {
121 if (
122 !path.node.declaration &&
123 path.node.specifiers.length === 0
124 ) {
125 path.node.specifiers.push(
126 t.exportSpecifier(
127 t.identifier(file.metadata.exportName),
128 t.identifier("default")
129 )
130 );
131 }
132 },
133 });
134 },
135 visitor: {
136 ImportDeclaration(path) {
137 const source = path.node.source;
138 source.value = source.value
139 .replace(/\.ts$/, "")
140 .replace(/^\.\//, "");
141 },
142 FunctionDeclaration(path) {
143 if (
144 mangleFns &&
145 path.node.leadingComments?.find(c =>
146 c.value.includes("@no-mangle")
147 )
148 ) {
149 const name = path.node.id.name;
150 if (name) noMangleFns.push(name);
151 }
152 },
153 },
154 }),
155 ],
156 }).code;
157 code = (
158 await minify(code, {
159 ecma: 5,
160 mangle: {
161 keep_fnames: mangleFns ? new RegExp(noMangleFns.join("|")) : true,
162 },
163 // The _typeof helper has a custom directive that we must keep
164 compress: {
165 directives: false,
166 passes: 10,
167 unsafe: true,
168 unsafe_proto: true,
169 },
170 })
171 ).code;
172
173 let metadata;
174 // eslint-disable-next-line prefer-const
175 [code, metadata] = getHelperMetadata(babel, code, helperName);
176
177 const helperStr = `\
178 // size: ${code.length}, gzip size: ${gzipSync(code).length}
179 ${JSON.stringify(helperName)}: helper(
180 ${JSON.stringify(minVersion)},
181 ${JSON.stringify(code)},
182 ${stringifyMetadata(metadata)}
183 ),
184`;
185
186 if (onlyBabel7) {
187 if (!IS_BABEL_8()) babel7extraOutput += helperStr;
188 } else {
189 output += helperStr;
190 }
191 }
192
193 output += "};";
194
195 if (babel7extraOutput) {
196 output += `
197
198if (!process.env.BABEL_8_BREAKING) {
199 Object.assign(helpers, {
200 ${babel7extraOutput}
201 });
202}
203`;
204 }
205
206 return output;
207}
Note: See TracBrowser for help on using the repository browser.