mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
* Move Fizz inline instructions to unified module Instead of a separate module per instruction, this exports all of them from a unified module. In the next step, I'll add a script to generate this new module. * Add script to generate inline Fizz runtime This adds a script to generate the inline Fizz runtime. Previously, the runtime source was in an inline comment, and a compiled version of the instructions were hardcoded as strings into the Fizz implementation, where they are injected into the HTML stream. I've moved the source for the instructions to a regular JavaScript module. A script compiles the instructions with Closure, then generates another module that exports the compiled instructions as strings. Then the Fizz runtime imports the instructions from the generated module. To build the instructions, run: yarn generate-inline-fizz-runtime In the next step, I'll add a CI check to verify that the generated files are up to date. * Check in CI if generated Fizz runtime is in sync The generated Fizz runtime is checked into source. In CI, we'll ensure it stays in sync by running the script and confirming nothing changed.
89 lines
2.8 KiB
JavaScript
89 lines
2.8 KiB
JavaScript
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const ClosureCompiler = require('google-closure-compiler').compiler;
|
|
const prettier = require('prettier');
|
|
|
|
const instructionDir =
|
|
'./packages/react-dom-bindings/src/server/fizz-instruction-set';
|
|
|
|
// This is the name of the generated file that exports the inline instruction
|
|
// set as strings.
|
|
const inlineCodeStringsFilename =
|
|
instructionDir + '/ReactDOMFizzInstructionSetInlineCodeStrings.js';
|
|
|
|
const config = [
|
|
{
|
|
entry: 'ReactDOMFizzInlineClientRenderBoundary.js',
|
|
exportName: 'clientRenderBoundary',
|
|
},
|
|
{
|
|
entry: 'ReactDOMFizzInlineCompleteBoundary.js',
|
|
exportName: 'completeBoundary',
|
|
},
|
|
{
|
|
entry: 'ReactDOMFizzInlineCompleteBoundaryWithStyles.js',
|
|
exportName: 'completeBoundaryWithStyles',
|
|
},
|
|
{
|
|
entry: 'ReactDOMFizzInlineCompleteSegment.js',
|
|
exportName: 'completeSegment',
|
|
},
|
|
];
|
|
|
|
const prettierConfig = require('../../.prettierrc.js');
|
|
|
|
async function main() {
|
|
const exportStatements = await Promise.all(
|
|
config.map(async ({entry, exportName}) => {
|
|
const fullEntryPath = instructionDir + '/' + entry;
|
|
const compiler = new ClosureCompiler({
|
|
entry_point: fullEntryPath,
|
|
js: [fullEntryPath, instructionDir + '/ReactDOMFizzInstructionSet.js'],
|
|
compilation_level: 'ADVANCED',
|
|
module_resolution: 'NODE',
|
|
// This is necessary to prevent Closure from inlining a Promise polyfill
|
|
rewrite_polyfills: false,
|
|
});
|
|
|
|
const code = await new Promise((resolve, reject) => {
|
|
compiler.run((exitCode, stdOut, stdErr) => {
|
|
if (exitCode !== 0) {
|
|
reject(new Error(stdErr));
|
|
} else {
|
|
resolve(stdOut);
|
|
}
|
|
});
|
|
});
|
|
|
|
return `export const ${exportName} = ${JSON.stringify(code.trim())};`;
|
|
})
|
|
);
|
|
|
|
let outputCode = [
|
|
'// This is a generated file. The source files are in react-dom-bindings/src/server/fizz-instruction-set.',
|
|
'// The build script is at scripts/rollup/generate-inline-fizz-runtime.js.',
|
|
'// Run `yarn generate-inline-fizz-runtime` to generate.',
|
|
...exportStatements,
|
|
].join('\n');
|
|
|
|
// This replaces "window.$globalVar" with "$globalVar". There's probably a
|
|
// better way to do this with Closure, with externs or something, but I
|
|
// couldn't figure it out. Good enough for now. This only affects the inline
|
|
// Fizz runtime, and should break immediately if there were a mistake, so I'm
|
|
// not too worried about it.
|
|
outputCode = outputCode.replaceAll(
|
|
/window\.(\$[A-z0-9_]*)/g,
|
|
(_, variableName) => variableName
|
|
);
|
|
|
|
const prettyOutputCode = prettier.format(outputCode, prettierConfig);
|
|
|
|
fs.writeFileSync(inlineCodeStringsFilename, prettyOutputCode, 'utf8');
|
|
}
|
|
|
|
main().catch(err => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|