Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,920 changes: 2,481 additions & 1,439 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
"npm": ">=7"
},
"devDependencies": {
"@babel/core": "^7.29.0",
"@babel/eslint-parser": "7.28.6",
"@babel/core": "^8.0.1",
"@babel/eslint-parser": "8.0.1",
"@changesets/changelog-github": "0.5.1",
"@changesets/cli": "^2.29.6",
"@eslint-react/eslint-plugin": "^1.52.6",
Expand Down Expand Up @@ -80,10 +80,10 @@
"eslint-plugin-react": "^7.35.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.3",
"eslint-plugin-react-you-might-not-need-an-effect": "1.0.1",
"eslint-plugin-ssr-friendly": "1.3.0",
"eslint-plugin-storybook": "^10.4.6",
"eslint-plugin-testing-library": "^7.16.2",
"eslint-plugin-react-you-might-not-need-an-effect": "1.0.1",
"fast-glob": "^3.3.3",
"globals": "^16.2.0",
"markdownlint-cli2": "^0.19.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/react-compiler-check/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
"@babel/core": "7.29.6",
"@babel/preset-react": "7.28.5",
"@babel/preset-typescript": "7.28.5",
"@babel/core": "8.0.1",
"@babel/preset-react": "8.0.1",
"@babel/preset-typescript": "8.0.1",
"babel-plugin-react-compiler": "^1.0.0"
},
"devDependencies": {
Expand Down
32 changes: 27 additions & 5 deletions packages/react-compiler-check/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import {type TransformOptions, transformSync} from '@babel/core'
import {createRequire} from 'node:module'
import {type InputOptions, transformSync} from '@babel/core'
import {CompilerError} from 'babel-plugin-react-compiler'
import type {Logger, SourceLocation} from 'babel-plugin-react-compiler'

const require = createRequire(import.meta.url)
const presetTypescript = require.resolve('@babel/preset-typescript')
const presetReact = require.resolve('@babel/preset-react')
const reactCompilerPlugin = require.resolve('babel-plugin-react-compiler')

type CheckError = {
location: SourceLocation | null
reason: string
Expand All @@ -15,34 +21,42 @@ function checkFile(filename: string, contents: string): CheckResult {
logEvent(_filename, event) {
// https://react.dev/reference/react-compiler/logger#event-types
if (event.kind === 'CompileError') {
if (isRecoverableCompileSkip(event.detail.reason)) {
return
}

addCheckError(errors, {
location: event.detail.primaryLocation(),
reason: event.detail.reason,
})
} else if (event.kind === 'CompileSkip') {
if (isRecoverableCompileSkip(event.reason)) {
return
}

addCheckError(errors, {
location: event.loc ?? event.fnLoc,
reason: event.reason,
})
}
},
}
const inputOptions: TransformOptions = {
const inputOptions: InputOptions = {
babelrc: false,
configFile: false,
filename,
presets: [
'@babel/preset-typescript',
presetTypescript,
[
'@babel/preset-react',
presetReact,
{
runtime: 'automatic',
},
],
],
plugins: [
[
'babel-plugin-react-compiler',
reactCompilerPlugin,
{
target: '18',
logger,
Expand All @@ -60,6 +74,10 @@ function checkFile(filename: string, contents: string): CheckResult {
}

for (const detail of error.details) {
if (isRecoverableCompileSkip(detail.reason)) {
continue
}

addCheckError(errors, {
location: detail.primaryLocation(),
reason: detail.reason,
Expand Down Expand Up @@ -92,6 +110,10 @@ function addCheckError(errors: Array<CheckError>, error: CheckError): void {
}
}

function isRecoverableCompileSkip(reason: string): boolean {
return reason === '(BuildHIR::lowerAssignment) Expected object property value to be an LVal, got: AssignmentPattern'
}

function getLocationLine(location: CheckError['location']): number | null {
if (location === null || typeof location !== 'object' || !('start' in location)) {
return null
Expand Down
19 changes: 10 additions & 9 deletions packages/react/babel.config.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const defines = require('./babel-defines.cjs')
const {isSupported} = require('./script/react-compiler.mjs')
const devExpressionPlugin = require.resolve('./script/babel-plugins/dev-expression.cjs')
const replaceExpressionsPlugin = require.resolve('./script/babel-plugins/replace-expressions.cjs')

function replacementPlugin(env) {
return ['babel-plugin-transform-replace-expressions', {replace: defines[env]}]
return [replaceExpressionsPlugin, {replace: defines[env]}]
}

const sharedPlugins = [
Expand All @@ -14,19 +16,18 @@ const sharedPlugins = [
},
],
'macros',
'dev-expression',
devExpressionPlugin,
'add-react-displayname',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-transform-nullish-coalescing-operator',
'@babel/plugin-transform-optional-chaining',
]

function makePresets(moduleValue) {
function makePresets() {
return [
'@babel/preset-typescript',
[
'@babel/preset-react',
{
modules: moduleValue,
runtime: 'automatic',
},
],
Expand All @@ -36,15 +37,15 @@ function makePresets(moduleValue) {
module.exports = {
env: {
development: {
presets: makePresets(process.env.BABEL_MODULE || false),
presets: makePresets(),
plugins: [...sharedPlugins, replacementPlugin('development')],
},
production: {
presets: makePresets(false),
presets: makePresets(),
plugins: [...sharedPlugins, replacementPlugin('production')],
},
test: {
presets: makePresets('commonjs'),
presets: makePresets(),
plugins: [...sharedPlugins, ['@babel/plugin-transform-modules-commonjs'], replacementPlugin('test')],
},
},
Expand Down
21 changes: 8 additions & 13 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@
},
"devDependencies": {
"@actions/core": "1.11.1",
"@babel/cli": "7.28.6",
"@babel/core": "7.29.6",
"@babel/parser": "7.29.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
"@babel/plugin-proposal-optional-chaining": "7.21.0",
"@babel/plugin-transform-modules-commonjs": "7.28.6",
"@babel/preset-react": "7.28.5",
"@babel/preset-typescript": "7.28.5",
"@babel/cli": "8.0.1",
"@babel/core": "8.0.1",
"@babel/parser": "8.0.0",
"@babel/plugin-transform-modules-commonjs": "8.0.1",
"@babel/plugin-transform-nullish-coalescing-operator": "8.0.1",
"@babel/plugin-transform-optional-chaining": "8.0.1",
"@babel/preset-react": "8.0.1",
"@babel/preset-typescript": "8.0.1",
"@figma/code-connect": "1.3.2",
"@primer/css": "^21.5.1",
"@primer/doc-gen": "^0.0.1",
Expand All @@ -122,7 +122,6 @@
"@testing-library/react": "^16.3.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/babel__core": "^7.20.5",
"@types/lodash.groupby": "4.6.9",
"@types/lodash.isempty": "4.4.9",
"@types/lodash.isobject": "3.0.9",
Expand All @@ -135,14 +134,10 @@
"afterframe": "^1.0.2",
"ajv": "8.18.0",
"axe-core": "4.9.1",
"babel-core": "7.0.0-bridge.0",
"babel-plugin-add-react-displayname": "0.0.5",
"babel-plugin-dev-expression": "0.2.3",
"babel-plugin-macros": "3.1.0",
"babel-plugin-open-source": "1.3.4",
"babel-plugin-react-compiler": "^1.0.0",
"babel-plugin-transform-replace-expressions": "0.2.0",
"babel-polyfill": "6.26.0",
"chalk": "^5.4.1",
"change-case": "5.4.4",
"concurrently": "9.1.2",
Expand Down
14 changes: 9 additions & 5 deletions packages/react/rolldown.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from 'node:path'
import {fileURLToPath} from 'node:url'
import babel from '@rolldown/plugin-babel'
import {defineConfig} from 'rolldown'
import {preserveDirectives} from 'rolldown-plugin-preserve-directives'
Expand All @@ -15,6 +16,10 @@ interface PackageMetadata {
}

const packageMetadata: PackageMetadata = packageJson
const devExpressionPlugin = fileURLToPath(new URL('./script/babel-plugins/dev-expression.cjs', import.meta.url))
const replaceExpressionsPlugin = fileURLToPath(
new URL('./script/babel-plugins/replace-expressions.cjs', import.meta.url),
)

const entrypoints = new Set([
// "exports"
Expand Down Expand Up @@ -74,7 +79,6 @@ export default defineConfig([
[
'@babel/preset-react',
{
modules: false,
runtime: 'automatic',
},
],
Expand All @@ -89,12 +93,12 @@ export default defineConfig([
],
'macros',
'add-react-displayname',
'dev-expression',
devExpressionPlugin,
'babel-plugin-styled-components',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-transform-nullish-coalescing-operator',
'@babel/plugin-transform-optional-chaining',
[
'babel-plugin-transform-replace-expressions',
replaceExpressionsPlugin,
{
replace: {
__DEV__: "process.env.NODE_ENV !== 'production'",
Expand Down
61 changes: 61 additions & 0 deletions packages/react/script/babel-plugins/dev-expression.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module.exports = function devExpression({types: t}) {
const seen = new WeakSet()

function makeDevExpression() {
return t.binaryExpression(
'!==',
t.memberExpression(t.memberExpression(t.identifier('process'), t.identifier('env')), t.identifier('NODE_ENV')),
t.stringLiteral('production'),
)
}

return {
name: 'dev-expression',
visitor: {
Identifier(path) {
if (process.env.NODE_ENV === 'test') {
return
}

if (path.isIdentifier({name: '__DEV__'}) && path.scope.hasGlobal('__DEV__')) {
path.replaceWith(makeDevExpression())
}
},
CallExpression: {
exit(path) {
if (process.env.NODE_ENV === 'test' || seen.has(path.node)) {
return
}

const callee = path.get('callee')

if (callee.isIdentifier({name: 'invariant'})) {
const [condition, ...args] = path.node.arguments
const devInvariant = t.callExpression(t.cloneNode(path.node.callee), [t.booleanLiteral(false), ...args])
const prodInvariant = t.callExpression(t.cloneNode(path.node.callee), [t.booleanLiteral(false)])

seen.add(devInvariant)
seen.add(prodInvariant)

path.replaceWith(
t.ifStatement(
t.unaryExpression('!', condition),
t.blockStatement([
t.ifStatement(
makeDevExpression(),
t.blockStatement([t.expressionStatement(devInvariant)]),
t.blockStatement([t.expressionStatement(prodInvariant)]),
),
]),
),
)
} else if (callee.isIdentifier({name: 'warning'})) {
seen.add(path.node)

path.replaceWith(t.ifStatement(makeDevExpression(), t.blockStatement([t.expressionStatement(path.node)])))
}
},
},
},
}
}
62 changes: 62 additions & 0 deletions packages/react/script/babel-plugins/replace-expressions.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
module.exports = function replaceExpressions({template, types: t}, options = {}) {
const replace = options.replace ?? {}
const allowConflictingReplacements = options.allowConflictingReplacements === true
const candidatesByType = new Map()

for (const [key, value] of Object.entries(replace)) {
const keyNode = template.expression.ast(key)
const valueNode = template.expression.ast(value)
const candidates = candidatesByType.get(keyNode.type) ?? []

for (let i = 0; i < candidates.length; i++) {
if (!t.isNodesEquivalent(candidates[i].key, keyNode)) {
continue
}

if (!allowConflictingReplacements) {
throw new Error(`Expressions ${JSON.stringify(candidates[i].originalKey)} and ${JSON.stringify(key)} conflict`)
}

candidates.splice(i, 1)
break
}

candidates.push({key: keyNode, originalKey: key, value: valueNode})
candidatesByType.set(keyNode.type, candidates)
}

return {
name: 'replace-expressions',
visitor: {
Expression(path) {
const candidates = candidatesByType.get(path.node.type)

if (!candidates) {
return
}

for (const {key, value} of candidates) {
if (!t.isNodesEquivalent(key, path.node)) {
continue
}

const replacement = t.cloneNode(value)

try {
t.validate(path.parent, path.key, replacement)
} catch (error) {
if (!(error instanceof TypeError)) {
throw error
}

path.skip()
return
}

path.replaceWith(replacement)
return
}
},
},
}
}
1 change: 0 additions & 1 deletion packages/react/script/components-json/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-expect-error there seems to be a mismatch in the types for this package
import {generate} from '@babel/generator'
import {parse} from '@babel/parser'
import {traverse} from '@babel/core'
Expand Down
Loading
Loading