From 67a61d5bd7f731f5eb37d148dfc4ae0515a8c934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Tue, 28 Feb 2023 19:44:37 -0500 Subject: [PATCH] [Flight Fixture] Show SSR Support with CSS (#26263) Builds on #26257. To do this we need access to a manifest for which scripts and CSS are used for each "page" (entrypoint). The initial script to bootstrap the app is inserted with `bootstrapScripts`. Subsequent content are loaded using the chunks mechanism built-in. The stylesheets for each pages are prepended to each RSC payload and rendered using Float. This doesn't yet support styles imported in components that are also SSR:ed nor imported through Server Components. That's more complex and not implemented in the node loader. HMR doesn't work after reloads right now because the SSR renderer isn't hot reloaded because there's no idiomatic way to hot reload ESM modules in Node.js yet. Without killing the HMR server. This leads to hydration mismatches when reloading the page after a hot reload. Notably this doesn't show serializing the stream through the HTML like real implementations do. This will lead to possible hydration mismatches based on the data. However, manually serializing the stream as a string isn't exactly correct due to binary data. It's not the idiomatic way this is supposed to work. This will all be built-in which will make this automatic in the future. --- fixtures/flight/.gitignore | 1 - fixtures/flight/config/paths.js | 1 - fixtures/flight/config/webpack.config.js | 85 +++++------ fixtures/flight/loader/global.js | 51 +++++++ .../flight/loader/{index.js => region.js} | 0 fixtures/flight/package.json | 15 +- fixtures/flight/public/index.html | 11 -- fixtures/flight/scripts/build.js | 3 +- fixtures/flight/server/global.js | 138 +++++++++++------- fixtures/flight/server/region.js | 47 +++++- fixtures/flight/src/App.js | 41 ++++-- fixtures/flight/src/index.js | 13 +- fixtures/flight/src/style.css | 3 + fixtures/flight/yarn.lock | 47 ++++-- .../src/ReactFlightWebpackPlugin.js | 39 +++-- 15 files changed, 312 insertions(+), 183 deletions(-) create mode 100644 fixtures/flight/loader/global.js rename fixtures/flight/loader/{index.js => region.js} (100%) delete mode 100644 fixtures/flight/public/index.html create mode 100644 fixtures/flight/src/style.css diff --git a/fixtures/flight/.gitignore b/fixtures/flight/.gitignore index 0852d35565e81..4add43216aee8 100644 --- a/fixtures/flight/.gitignore +++ b/fixtures/flight/.gitignore @@ -10,7 +10,6 @@ # production /build -/dist .eslintcache # misc diff --git a/fixtures/flight/config/paths.js b/fixtures/flight/config/paths.js index 1c7df49db7dbe..85eda99c87e26 100644 --- a/fixtures/flight/config/paths.js +++ b/fixtures/flight/config/paths.js @@ -56,7 +56,6 @@ module.exports = { appPath: resolveApp('.'), appBuild: resolveApp(buildPath), appPublic: resolveApp('public'), - appHtml: resolveApp('public/index.html'), appIndexJs: resolveModule(resolveApp, 'src/index'), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), diff --git a/fixtures/flight/config/webpack.config.js b/fixtures/flight/config/webpack.config.js index 9b4b7edb09c71..fbb7ee917c3ea 100644 --- a/fixtures/flight/config/webpack.config.js +++ b/fixtures/flight/config/webpack.config.js @@ -9,13 +9,10 @@ const {createHash} = require('crypto'); const path = require('path'); const webpack = require('webpack'); const resolve = require('resolve'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); -const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const ESLintPlugin = require('eslint-webpack-plugin'); @@ -28,6 +25,7 @@ const ForkTsCheckerWebpackPlugin = ? require('react-dev-utils/ForkTsCheckerWarningWebpackPlugin') : require('react-dev-utils/ForkTsCheckerWebpackPlugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); +const {WebpackManifestPlugin} = require('webpack-manifest-plugin'); function createEnvironmentHash(env) { const hash = createHash('md5'); @@ -116,7 +114,7 @@ module.exports = function (webpackEnv) { const getStyleLoaders = (cssOptions, preProcessor) => { const loaders = [ isEnvDevelopment && require.resolve('style-loader'), - isEnvProduction && { + { loader: MiniCssExtractPlugin.loader, // css is located in `static/css`, use '../../' to locate index.html folder // in production `paths.publicUrlOrPath` can be a relative path @@ -578,44 +576,6 @@ module.exports = function (webpackEnv) { }, plugins: [ new webpack.HotModuleReplacementPlugin(), - // Generates an `index.html` file with the