main
js 106 lines 3.27 KB
Raw
1 'use strict';
2
3 const fs = require('fs');
4 const ClosureCompiler = require('google-closure-compiler').compiler;
5 const prettier = require('prettier');
6
7 const instructionDir =
8 './packages/react-dom-bindings/src/server/fizz-instruction-set';
9
10 // This is the name of the generated file that exports the inline instruction
11 // set as strings.
12 const inlineCodeStringsFilename =
13 instructionDir + '/ReactDOMFizzInstructionSetInlineCodeStrings.js';
14
15 const config = [
16 {
17 entry: 'ReactDOMFizzInlineShellTime.js',
18 exportName: 'markShellTime',
19 },
20 {
21 entry: 'ReactDOMFizzInlineClientRenderBoundary.js',
22 exportName: 'clientRenderBoundary',
23 },
24 {
25 entry: 'ReactDOMFizzInlineCompleteBoundary.js',
26 exportName: 'completeBoundary',
27 },
28 {
29 entry: 'ReactDOMFizzInlineCompleteBoundaryUpgradeToViewTransitions.js',
30 exportName: 'completeBoundaryUpgradeToViewTransitions',
31 },
32 {
33 entry: 'ReactDOMFizzInlineCompleteBoundaryWithStyles.js',
34 exportName: 'completeBoundaryWithStyles',
35 },
36 {
37 entry: 'ReactDOMFizzInlineCompleteSegment.js',
38 exportName: 'completeSegment',
39 },
40 {
41 entry: 'ReactDOMFizzInlineFormReplaying.js',
42 exportName: 'formReplaying',
43 },
44 ];
45
46 const prettierConfig = require('../../.prettierrc.js');
47
48 async function main() {
49 const exportStatements = await Promise.all(
50 config.map(async ({entry, exportName}) => {
51 const fullEntryPath = instructionDir + '/' + entry;
52 const compiler = new ClosureCompiler({
53 entry_point: fullEntryPath,
54 js: [
55 require.resolve('./externs/closure-externs.js'),
56 fullEntryPath,
57 instructionDir + '/ReactDOMFizzInstructionSetShared.js',
58 ],
59 compilation_level: 'ADVANCED',
60 language_in: 'ECMASCRIPT_2020',
61 language_out: 'ECMASCRIPT5_STRICT',
62 module_resolution: 'NODE',
63 // This is necessary to prevent Closure from inlining a Promise polyfill
64 rewrite_polyfills: false,
65 });
66
67 const code = await new Promise((resolve, reject) => {
68 compiler.run((exitCode, stdOut, stdErr) => {
69 if (exitCode !== 0) {
70 reject(new Error(stdErr));
71 } else {
72 resolve(stdOut);
73 }
74 });
75 });
76
77 return `export const ${exportName} = ${JSON.stringify(code.trim().replace('\n', ''))};`;
78 })
79 );
80
81 let outputCode = [
82 '// This is a generated file. The source files are in react-dom-bindings/src/server/fizz-instruction-set.',
83 '// The build script is at scripts/rollup/generate-inline-fizz-runtime.js.',
84 '// Run `yarn generate-inline-fizz-runtime` to generate.',
85 ...exportStatements,
86 ].join('\n');
87
88 // This replaces "window.$globalVar" with "$globalVar". There's probably a
89 // better way to do this with Closure, with externs or something, but I
90 // couldn't figure it out. Good enough for now. This only affects the inline
91 // Fizz runtime, and should break immediately if there were a mistake, so I'm
92 // not too worried about it.
93 outputCode = outputCode.replace(
94 /window\.(\$[A-z0-9_]*|matchMedia)/g,
95 (_, variableName) => variableName
96 );
97
98 const prettyOutputCode = await prettier.format(outputCode, prettierConfig);
99
100 fs.writeFileSync(inlineCodeStringsFilename, prettyOutputCode, 'utf8');
101 }
102
103 main().catch(err => {
104 console.error(err);
105 process.exit(1);
106 });