Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a window var for CWV Tech Report to look for #11222

Merged
merged 7 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/cwv-report-id.md
@@ -0,0 +1,6 @@
---
"react-router-dom-v5-compat": minor
"react-router-dom": minor
---

Include a window tag for CWV Report detection
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -125,10 +125,10 @@
"none": "17.1 kB"
},
"packages/react-router-dom/dist/react-router-dom.production.min.js": {
"none": "16.9 kB"
"none": "17.0 kB"
},
"packages/react-router-dom/dist/umd/react-router-dom.production.min.js": {
"none": "23.1 kB"
"none": "23.2 kB"
}
}
}
20 changes: 17 additions & 3 deletions packages/react-router-dom-v5-compat/rollup.config.js
Expand Up @@ -7,8 +7,10 @@ const replace = require("@rollup/plugin-replace");
const { terser } = require("rollup-plugin-terser");
const typescript = require("@rollup/plugin-typescript");
const {
babelPluginReplaceVersionPlaceholder,
createBanner,
getBuildDirectories,
validateReplacedVersion,
PRETTY,
} = require("../../rollup.utils");
const { name, version } = require("./package.json");
Expand Down Expand Up @@ -57,7 +59,10 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
typescript({
Expand All @@ -71,6 +76,7 @@ module.exports = function rollup() {
],
verbose: true,
}),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
];
Expand Down Expand Up @@ -110,13 +116,17 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
replace({
preventAssignment: true,
values: { "process.env.NODE_ENV": JSON.stringify("development") },
}),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
{
Expand Down Expand Up @@ -152,14 +162,18 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
replace({
preventAssignment: true,
values: { "process.env.NODE_ENV": JSON.stringify("production") },
}),
terser(),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
];
Expand Down
17 changes: 17 additions & 0 deletions packages/react-router-dom/index.tsx
Expand Up @@ -218,11 +218,28 @@ export {

declare global {
var __staticRouterHydrationData: HydrationState | undefined;
var __reactRouterVersion: string;
interface Document {
startViewTransition(cb: () => Promise<void> | void): ViewTransition;
}
}

// HEY YOU! DON'T TOUCH THIS VARIABLE!
//
// It is replaced with the proper version at build time via a babel plugin in
// the rollup config.
//
// Export a global property onto the window for React Router detection by the
// Core Web Vitals Technology Report. This way they can configure the `wappalyzer`
// to detect and properly classify live websites as being built with React Router:
// https://github.com/HTTPArchive/wappalyzer/blob/main/src/technologies/r.json
const REACT_ROUTER_VERSION = "0";
try {
window.__reactRouterVersion = REACT_ROUTER_VERSION;
} catch (e) {
// no-op
}

////////////////////////////////////////////////////////////////////////////////
//#region Routers
////////////////////////////////////////////////////////////////////////////////
Expand Down
48 changes: 37 additions & 11 deletions packages/react-router-dom/rollup.config.js
Expand Up @@ -7,8 +7,10 @@ const replace = require("@rollup/plugin-replace");
const { terser } = require("rollup-plugin-terser");
const typescript = require("@rollup/plugin-typescript");
const {
babelPluginReplaceVersionPlaceholder,
createBanner,
getBuildDirectories,
validateReplacedVersion,
PRETTY,
} = require("../../rollup.utils");
const { name, version } = require("./package.json");
Expand Down Expand Up @@ -37,7 +39,10 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
typescript({
Expand All @@ -51,6 +56,7 @@ module.exports = function rollup() {
],
verbose: true,
}),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
];
Expand Down Expand Up @@ -78,13 +84,17 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
replace({
preventAssignment: true,
values: { "process.env.NODE_ENV": JSON.stringify("development") },
}),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
{
Expand Down Expand Up @@ -118,14 +128,17 @@ module.exports = function rollup() {
],
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
replace({
preventAssignment: true,
values: { "process.env.NODE_ENV": JSON.stringify("production") },
}),
// compiler(),
validateReplacedVersion(),
terser({ ecma: 8, safari10: true }),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
Expand Down Expand Up @@ -158,13 +171,17 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
replace({
preventAssignment: true,
values: { "process.env.NODE_ENV": JSON.stringify("development") },
}),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
{
Expand Down Expand Up @@ -192,15 +209,18 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
replace({
preventAssignment: true,
values: { "process.env.NODE_ENV": JSON.stringify("production") },
}),
// compiler(),
terser(),
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
];
Expand Down Expand Up @@ -247,7 +267,10 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
typescript({
Expand All @@ -256,7 +279,7 @@ module.exports = function rollup() {
exclude: ["__tests__"],
noEmitOnError: true,
}),
// compiler()
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
{
Expand Down Expand Up @@ -296,10 +319,13 @@ module.exports = function rollup() {
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: ["babel-plugin-dev-expression"],
plugins: [
"babel-plugin-dev-expression",
babelPluginReplaceVersionPlaceholder(),
],
extensions: [".ts", ".tsx"],
}),
// compiler()
validateReplacedVersion(),
].concat(PRETTY ? prettier({ parser: "babel" }) : []),
},
];
Expand Down
77 changes: 77 additions & 0 deletions rollup.utils.js
@@ -1,5 +1,7 @@
const path = require("path");
const fse = require("fs-extra");
const { version } = require("./packages/react-router/package.json");
const majorVersion = version.split(".").shift();

const PRETTY = !!process.env.PRETTY;

Expand Down Expand Up @@ -62,8 +64,83 @@ function createBanner(packageName, version) {
*/`;
}

// Babel plugin to replace `const REACT_ROUTER_VERSION = "0.0.0";` with the
// current version at build time, so we can set it on `window.__reactRouterVersion`
// for consumption by the Core Web Vitals Technology Report
function babelPluginReplaceVersionPlaceholder() {
return function (babel) {
var t = babel.types;

const KIND = "const";
const NAME = "REACT_ROUTER_VERSION";
const PLACEHOLDER = "0";

return {
visitor: {
VariableDeclaration: {
enter: function (path) {
// Only operate on top-level variables
if (!path.parentPath.isProgram()) {
return;
}

let { kind, declarations } = path.node;
if (
kind === KIND &&
declarations.length === 1 &&
declarations[0].id.name === NAME &&
declarations[0].init?.value === PLACEHOLDER
) {
path.replaceWith(
t.variableDeclaration(KIND, [
t.variableDeclarator(
t.identifier(NAME),
t.stringLiteral(majorVersion)
),
])
);
}
},
},
},
};
};
}

// Post-build plugin to validate that the version placeholder was replaced
function validateReplacedVersion() {
return {
name: "validate-replaced-version",
writeBundle(_, bundle) {
Object.entries(bundle).forEach(([filename, contents]) => {
if (!filename.endsWith(".js") || filename === "server.js") {
return;
}

let requiredStrs = filename.endsWith(".min.js")
? [`{window.__reactRouterVersion="${majorVersion}"}`]
: [
`const REACT_ROUTER_VERSION = "${majorVersion}";`,
`window.__reactRouterVersion = REACT_ROUTER_VERSION;`,
];

requiredStrs.forEach((str) => {
if (!contents.code.includes(str)) {
throw new Error(
`Expected ${filename} to include \`${str}\` but it did not`
);
}
});
});
},
};
}

// rollup.config.js
module.exports = {
getBuildDirectories,
createBanner,
babelPluginReplaceVersionPlaceholder,
validateReplacedVersion,
PRETTY,
};