#29 We can use React without esm bundle. In that case, rollup/commonjs will make React
as a single default export.
Details: use react without this plugin
One line config, and install the latest react & react-dom. It could run!
// vite.config.ts
const config: UserConfig = { jsx: "react" };
export default config;
{ "dependencies": {
"react": "^17.0.1",
"react-dom": "^17.0.1" } }
// main.tsx
import React from "react";
import ReactDOM from "react-dom";
ReactDOM.render(<h1>Hello</h1>, document.getElementById("root"));
But there is no hot module reload. That's why react-refresh
comes.
Problem is, since rollup only exports React
, we can not do import { useState } from "react"
. You can checkout /@modules/react.js
in [ DevTools > Sources > Page ]
to verify that. I put it here:
export { r as default } from '/@modules/common/index-b0081338.js';
import React from "react";
function App() {
const [name, setName] = React.useState(""); // ok
import React, { useState } from "react";
function App() {
const [name, setName] = useState(""); // not ok
Solution is that, instead of using another package, we can modify /@modules/react.js
to export everything we need. Along with this plugin's react-refresh part, you can try this vite.config.ts:
import type { UserConfig, Plugin, ServerPlugin, Transform } from "vite";
import originalReactPlugin from "vite-plugin-react";
import { readBody } from "vite";
declare module "vite-plugin-react" {
export const configureServer: ServerPlugin;
export const transforms: Transform[];
}
const createReactPlugin: () => Plugin = () => {
// just ignore the pika resolver
return {
configureServer: originalReactPlugin.configureServer,
transforms: originalReactPlugin.transforms,
};
};
const config: UserConfig = {
jsx: "react",
plugins: [
createReactPlugin(),
{
configureServer: ({ app }) => {
app.use(async (ctx, next) => {
await next();
if (ctx.path === "/@modules/react.js") {
let js = (await readBody(ctx.body))!;
js = js.replace("export { r as default", "import { r as React");
js += `
const { useState, useEffect } = React; // add more exports here
export { useState, useEffect }; // and here
export default React;`;
ctx.body = js;
}
});
},
},
],
};
export default config;
I'm not sure whether rollup will build stable output like that. At least this solution LGTM.
Update: just make a script to gather exported names.