Skip to content

Commit

Permalink
use transform API to remove react-dom/client import
Browse files Browse the repository at this point in the history
  • Loading branch information
lmiller1990 committed Jul 14, 2022
1 parent f01cd86 commit 86653c7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
30 changes: 17 additions & 13 deletions npm/vite-dev-server/src/plugins/react18.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Plugin } from 'vite'
import path from 'path'
import debugLib from 'debug'
import { usingReactWithLegacyAPI } from '../resolveConfig'

const debug = debugLib('cypress:vite-dev-server:plugins:react18')

Expand All @@ -15,22 +15,26 @@ const debug = debugLib('cypress:vite-dev-server:plugins:react18')
* and will fail during this step if react-dom/client does not exist (React <= 17).
*
* To avoid this error and seamlessly support React 17 and 18 side by side we simply
* stub out the dynamic react-dom/client import and return a placeholder module.
* remove the react-dom/client import when using older version by rewriting the bundle using
* Rollup's transform API: https://rollupjs.org/guide/en/#transform (Vite using Rollup internally).
*/

export const React18 = (projectRoot: string): Plugin => {
return {
name: 'cypress:missing-react-dom-client',
resolveId (source: string) {
debug('source is %s', source)
if (source === 'react-dom/client') {
try {
return require.resolve('react-dom/client', { paths: [projectRoot] })
} catch (e) {
debug('error resolving %s, falling back to client/reactDomClientPlaceholder.js', source)
name: 'cypress:rewrite-react-dom-import',
enforce: 'pre',
transform (code, id) {
const isUsingLegacyApi = usingReactWithLegacyAPI(projectRoot)

if (!isUsingLegacyApi) {
return
}

const isCypressReact = id.includes('cypress-react.esm-bundler.js')

// This is not a react 18 project, need to stub out to avoid error
return path.resolve(__dirname, '..', '..', 'client', 'reactDomClientPlaceholder.js')
}
if (isCypressReact) {
// remove problematic code via transform!
return code.replace('react-dom/client', 'react-dom')
}
},
}
Expand Down
21 changes: 21 additions & 0 deletions npm/vite-dev-server/src/resolveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
import debugFn from 'debug'
import { importModule } from 'local-pkg'
import major from 'semver/functions/major'
import { relative, resolve } from 'pathe'
import type { InlineConfig } from 'vite'
import path from 'path'
Expand All @@ -16,6 +17,18 @@ import type { Vite } from './getVite'

const debug = debugFn('cypress:vite-dev-server:resolve-config')

export function usingReactWithLegacyAPI (projectRoot: string) {
try {
// using React?
const reactPath = require.resolve('react', { paths: [projectRoot] })

// is it <= 17?
return major(require(reactPath).version) <= 17
} catch (e) {
return false
}
}

export const createViteDevServerConfig = async (config: ViteDevServerConfig, vite: Vite) => {
const { specs, cypressConfig, viteConfig: viteOverrides } = config
const root = cypressConfig.projectRoot
Expand Down Expand Up @@ -46,6 +59,13 @@ export const createViteDevServerConfig = async (config: ViteDevServerConfig, vit
paths: [root],
})))

const exclude: string[] = []

if (usingReactWithLegacyAPI(cypressConfig.projectRoot)) {
debug('exclude react-dom/client for backwards compat')
exclude.push('react-dom/client')
}

const viteBaseConfig: InlineConfig = {
root,
base: `${cypressConfig.devServerPublicPathRoute}/`,
Expand All @@ -69,6 +89,7 @@ export const createViteDevServerConfig = async (config: ViteDevServerConfig, vit
},
],
},
exclude,
entries: [
...specs.map((s) => relative(root, s.relative)),
...(cypressConfig.supportFile ? [resolve(root, cypressConfig.supportFile)] : []),
Expand Down

3 comments on commit 86653c7

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 86653c7 Jul 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.3.1/linux-x64/lmiller/21381-react-18-with-ignore-86653c734b9c5694f23f19e53b5dd8689b7119e3/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 86653c7 Jul 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.3.1/darwin-arm64/lmiller/21381-react-18-with-ignore-86653c734b9c5694f23f19e53b5dd8689b7119e3/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 86653c7 Jul 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.3.1/darwin-x64/lmiller/21381-react-18-with-ignore-86653c734b9c5694f23f19e53b5dd8689b7119e3/cypress.tgz

Please sign in to comment.