Skip to content

Commit

Permalink
fix(plugin-react): apply manual runtime interop (#8546)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Jun 12, 2022
1 parent d641860 commit f09299c
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 25 deletions.
3 changes: 1 addition & 2 deletions packages/plugin-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@
"@babel/plugin-transform-react-jsx-self": "^7.17.12",
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
"@rollup/pluginutils": "^4.2.1",
"react-refresh": "^0.13.0",
"resolve": "^1.22.0"
"react-refresh": "^0.13.0"
},
"peerDependencies": {
"vite": "^3.0.0-alpha"
Expand Down
55 changes: 34 additions & 21 deletions packages/plugin-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,40 +361,53 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
}
}

// const runtimeId = 'react/jsx-runtime'
const reactJsxRuntimeId = 'react/jsx-runtime'
const reactJsxDevRuntimeId = 'react/jsx-dev-runtime'
const virtualReactJsxRuntimeId = '\0' + reactJsxRuntimeId
const virtualReactJsxDevRuntimeId = '\0' + reactJsxDevRuntimeId
// Adapted from https://github.com/alloc/vite-react-jsx
const viteReactJsx: Plugin = {
name: 'vite:react-jsx',
enforce: 'pre',
config() {
return {
optimizeDeps: {
include: ['react/jsx-dev-runtime']
include: [reactJsxRuntimeId, reactJsxDevRuntimeId]
}
}
}
// TODO: this optimization may not be necesary and it is breacking esbuild+rollup compat,
// see https://github.com/vitejs/vite/pull/7246#discussion_r861552185
// We could still do the same trick and resolve to the optimized dependency here
/*
resolveId(id: string) {
return id === runtimeId ? id : null
},
load(id: string) {
if (id === runtimeId) {
const runtimePath = resolve.sync(runtimeId, {
basedir: projectRoot
})
const exports = ['jsx', 'jsxs', 'Fragment']
resolveId(id, importer) {
// Resolve runtime to a virtual path to be interoped.
// Since the interop code re-imports `id`, we need to prevent re-resolving
// to the virtual id if the importer is already the virtual id.
if (id === reactJsxRuntimeId && importer !== virtualReactJsxRuntimeId) {
return virtualReactJsxRuntimeId
}
if (
id === reactJsxDevRuntimeId &&
importer !== virtualReactJsxDevRuntimeId
) {
return virtualReactJsxDevRuntimeId
}
},
load(id) {
// Apply manual interop
if (id === virtualReactJsxRuntimeId) {
return [
`import * as jsxRuntime from ${JSON.stringify(runtimePath)}`,
// We can't use `export * from` or else any callsite that uses
// this module will be compiled to `jsxRuntime.exports.jsx`
// instead of the more concise `jsx` alias.
...exports.map((name) => `export const ${name} = jsxRuntime.${name}`)
`import * as jsxRuntime from ${JSON.stringify(reactJsxRuntimeId)}`,
`export const Fragment = jsxRuntime.Fragment`,
`export const jsx = jsxRuntime.jsx`,
`export const jsxs = jsxRuntime.jsxs`
].join('\n')
}
} */
if (id === virtualReactJsxDevRuntimeId) {
return [
`import * as jsxRuntime from ${JSON.stringify(reactJsxDevRuntimeId)}`,
`export const Fragment = jsxRuntime.Fragment`,
`export const jsxDEV = jsxRuntime.jsxDEV`
].join('\n')
}
}
}

return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx]
Expand Down
2 changes: 2 additions & 0 deletions playground/react/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from 'react'
import Dummy from './components/Dummy?qs-should-not-break-plugin-react'
import Button from 'jsx-entry'

function App() {
const [count, setCount] = useState(0)
Expand All @@ -26,6 +27,7 @@ function App() {
</header>

<Dummy />
<Button>button</Button>
</div>
)
}
Expand Down
5 changes: 5 additions & 0 deletions playground/react/jsx-entry/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Button = ({ children }) => {
return <button>{children}</button>
}

export default Button
6 changes: 6 additions & 0 deletions playground/react/jsx-entry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "jsx-entry",
"private": true,
"version": "0.0.0",
"main": "Button.jsx"
}
1 change: 1 addition & 0 deletions playground/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"jsx-entry": "file:./jsx-entry",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
Expand Down
1 change: 1 addition & 0 deletions playground/react/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import react from '@vitejs/plugin-react'
import type { UserConfig } from 'vite'

const config: UserConfig = {
mode: 'development',
plugins: [react()],
build: {
// to make tests faster
Expand Down
13 changes: 11 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f09299c

Please sign in to comment.