Skip to content

Commit

Permalink
feat: allow react/jsx-dev-runtime imports
Browse files Browse the repository at this point in the history
  • Loading branch information
aleclarson committed Apr 28, 2022
1 parent 274c10e commit 3a93391
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 20 deletions.
3 changes: 1 addition & 2 deletions packages/plugin-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"@babel/plugin-transform-react-jsx-self": "^7.16.7",
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
"@rollup/pluginutils": "^4.2.1",
"react-refresh": "^0.12.0",
"resolve": "^1.22.0"
"react-refresh": "^0.12.0"
}
}
49 changes: 33 additions & 16 deletions packages/plugin-react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
import * as babel from '@babel/core'
import { createFilter } from '@rollup/pluginutils'
import resolve from 'resolve'
import type { Plugin, PluginOption } from 'vite'
import {
addRefreshWrapper,
Expand Down Expand Up @@ -333,34 +332,52 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
}
}

const runtimeId = 'react/jsx-runtime'
const devEntry = 'react/cjs/react-jsx-dev-runtime.development.js'
const prodEntry = 'react/cjs/react-jsx-runtime.production.min.js'
const devRuntimeId = 'react/jsx-dev-runtime'
const prodRuntimeId = 'react/jsx-runtime'
const shimRuntimeId = prodRuntimeId + '.shim.js'

// 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']
// These must be optimized since they are CommonJS.
include: [prodEntry, devEntry]
},
resolve: {
// Ensure these are resolved relative to the project root.
dedupe: [prodEntry, devEntry]
}
}
},
resolveId(id: string) {
return id === runtimeId ? id : null
// Prevent applications from using both the dev runtime and prod runtime
// by resolving both with the same module ID.
return id === prodRuntimeId || id === devRuntimeId ? shimRuntimeId : null
},
load(id: string) {
if (id === runtimeId) {
const runtimePath = resolve.sync(runtimeId, {
basedir: projectRoot
})
const exports = ['jsx', 'jsxs', 'Fragment']
return [
async load(id: string) {
// Even though this shim is really only useful in production, we use it
// in development as well, for consistency's sake.
if (id === shimRuntimeId) {
const runtimePath = isProduction ? prodEntry : devEntry

// 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.
const lines = [
`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}`)
].join('\n')
`export const Fragment = jsxRuntime.Fragment`,
`export const jsx = jsxRuntime.${isProduction ? 'jsx' : 'jsxDEV'}`,
`export const jsxs = jsxRuntime.${isProduction ? 'jsxs' : 'jsxDEV'}`
]
if (!isProduction) {
lines.push(`export const jsxDEV = jsxRuntime.jsxDEV`)
}
return lines.join('\n')
}
}
}
Expand Down
2 changes: 0 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 3a93391

Please sign in to comment.