Reputation: 1520
Vite does not allow usage of JSX syntax within .js files by default.
I have already renamed my files to .jsx
(or .tsx
), but I have external dependencies that I cannot rename.
Example error from Vite:
✘ [ERROR] The JSX syntax extension is not currently enabled
node_modules/somelib/src/someFile.js:122:11:
122 │ return <div/>
How can I configure Vite to support JSX expressions in all .js files?
Upvotes: 30
Views: 57426
Reputation: 1698
The vite.config.js
below makes Vite/Vitest treat *.js
files as JSX to avoid errors like:
Error: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension.
vite.config.js
import { defineConfig, transformWithEsbuild } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
{
name: 'treat-js-files-as-jsx',
async transform(code, id) {
if (!id.match(/src\/.*\.js$/)) return null
// Use the exposed transform from vite, instead of directly
// transforming with esbuild
return transformWithEsbuild(code, id, {
loader: 'jsx',
jsx: 'automatic',
})
},
},
react(),
],
optimizeDeps: {
force: true,
esbuildOptions: {
loader: {
'.js': 'jsx',
},
},
},
})
And don't forget to run npm i @vitejs/plugin-react
.
Upvotes: 26
Reputation: 2723
simply just updated the vite.config.js file, added allow file types in react plugin.
export default defineConfig({ plugins: [react({ include: /\.(mdx|js|jsx|ts|tsx)$/ })], });
Upvotes: 0
Reputation: 11
Thanks to - @Maksim Shamihulau This answer worked for me for latest versions of Vite & React and used Tailwind Css also and it started working https://stackoverflow.com/a/76726872/23205457 :-
import { defineConfig, transformWithEsbuild } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
{
name: 'treat-js-files-as-jsx',
async transform(code, id) {
if (!id.match(/src\/.*\.js$/)) return null
// Use the exposed transform from vite, instead of directly
// transforming with esbuild
return transformWithEsbuild(code, id, {
loader: 'jsx',
jsx: 'automatic',
})
},
},
react(),
],
optimizeDeps: {
force: true,
esbuildOptions: {
loader: {
'.js': 'jsx',
},
},
},
})
Upvotes: 1
Reputation: 1105
I had the same problem when migrating from CRA to Vite. Based on the example in this comment on Github I was able to treat all .js
files as jsx
:
export default defineConfig({
// rest of configuration
esbuild: {
include: /\.js$/,
exclude: [],
loader: 'jsx',
},
})
If you want to treat all combinations of .js
, .jsx
, .ts
, and .tsx
files as jsx
, you might want to use the following include
pattern:
esbuild: {
include: /\.[jt]sx?$/,
exclude: [],
loader: 'jsx',
},
Upvotes: 10
Reputation: 1520
You can change esbuild configuration to treat all js files as jsx with the loader
option:
// vite.config.ts
import {defineConfig} from 'vite'
// https://vitejs.dev/config/
export default defineConfig(() => ({
esbuild: {
loader: "tsx", // OR "jsx"
include: [
// Add this for business-as-usual behaviour for .jsx and .tsx files
"src/**/*.jsx",
"src/**/*.tsx",
"node_modules/**/*.jsx",
"node_modules/**/*.tsx",
// Add the specific files you want to allow JSX syntax in
"src/LocalJsxInJsComponent.js",
"node_modules/bad-jsx-in-js-component/index.js",
"node_modules/bad-jsx-in-js-component/js/BadJSXinJS.js",
"node_modules/bad-jsx-in-js-component/ts/index.ts",
"node_modules/bad-jsx-in-js-component/ts/BadTSXinTS.ts",
// --- OR ---
// Add these lines to allow all .js files to contain JSX
"src/**/*.js",
"node_modules/**/*.js",
// Add these lines to allow all .ts files to contain JSX
"src/**/*.ts",
"node_modules/**/*.ts",
],
},
}));
Note: there is a performance penalty for loading .js files with the .jsx loader.
Answer taken from this discussion in Vite's GitHub, Which marks the incorrect (and older) answer as the "correct" one.
The original answer did not work correctly for vite build
, only for vite dev
. The current version works for both with vite@^4.0.0
Here is an example repo you can clone and test the solution.
Vite 5.0 was released, this might not be relevant anymore, edits + corrections welcome.
Upvotes: 13
Reputation: 1716
I wasn't able to get the config in this answer to work as-is. I needed to add include
and exclude
keys to the esbuild
config for some reason.
Building on this comment on the Vite discussion board, I was able to get this config file working for both vite serve
and vite build
. (Well, "working" as in not complaining about JSX in .js
files anymore. Vite is still complaining about some CJS modules...)
// vite.config.js
import fs from "node:fs";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import * as esbuild from "esbuild";
const sourceJSPattern = /\/src\/.*\.js$/;
const rollupPlugin = (matchers) => ({
name: "js-in-jsx",
load(id) {
if (matchers.some(matcher => matcher.test(id))) {
const file = fs.readFileSync(id, { encoding: "utf-8" });
return esbuild.transformSync(file, { loader: "jsx" });
}
}
});
export default defineConfig({
plugins: [
react()
],
build: {
rollupOptions: {
plugins: [
rollupPlugin([sourceJSPattern])
],
},
commonjsOptions: {
transformMixedEsModules: true,
},
},
optimizeDeps: {
esbuildOptions: {
loader: {
".js": "jsx",
},
},
},
esbuild: {
loader: "jsx",
include: [sourceJSPattern],
exclude: [],
},
});
Upvotes: 4