使用react配置esbuild(替换create-areact应用程序)



我有一堆扩展名为js而不是jsx的文件。(这是一个react项目(。

我用这样的脚本设置了我的package.json:

"build": "esbuild src/App.js --bundle --minify --sourcemap --outfile=public/bundle.js",

在运行它时,我有很多错误,都抱怨js语法,比如:

const App = () => {
return (
<>
// some code
</>
)
}

其中:

> src/App.js:16:2: error: Unexpected "<"
16 │     <>
╵     ^

对于许多将基本div作为返回的文件来说,这是一个类似的错误:<div> // content </div>声明div的乞求中的<是意外的。我想这是因为它没有将这些文件视为jsx。我能设置一些标志来解决这个问题吗?将每个文件更改为jsx将是一项任务。

看起来esbuild文档中有一条语句:(链接块的底部(

esbuild app.js --bundle --loader:.js=jsx

--loader:.js=jsx语句将在js文件上使用jsx加载程序


所以你的脚本可能看起来像:

"build": "esbuild src/App.js --bundle --minify --sourcemap --outfile=public/bundle.js --loader:.js=jsx",

文档指出,您也可以在配置脚本中执行此操作,而不是在CLI:中执行

require('esbuild').buildSync({
entryPoints: ['app.js'],
bundle: true,
loader: { '.js': 'jsx' },
outfile: 'out.js',
})

当您忘记将[用于React库]的导入指令添加到组件文件中时,也可能发生这种情况。

例如,假设您有一个React应用程序,其结构如下:

.
+-- index.html
+-- index.js
+-| src
+-- app.js
+-| components
+-- my-component.js
+-| dist
+-- bundle.js

以及以下文件内容:

<!-- index.html -->
<html>
<head>
<title>My React App</title>
</head>
<body>
<div id="root"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './src/app';
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
document.querySelector('#root')
);
// ./src/app.js
import Banner from './components/my-component';
function App() {
return (
<div className="App">
<header className="App-header">
<h1>Hello World</h1>
</header>
<main>
<Banner/>
</main>
</div>
);
}
export default App;
// .src/components/my-component.js
function MyBanner(){
return (
<h3>My Banner!</h3>
);
}
export default MyBanner;

要将React应用程序与ESBuild捆绑在一起,您可能正在运行以下程序:

npx esbuild index.js --bundle --loader:.js=jsx --out-file=./dist/bundle.js

注意:如果npm版本为5.2.0或更高版本,则可以使用npx esbuild而不是./node_modules/.bin/esbuild

构建完成后,[在浏览器中]打开index.html,应该会出现一个错误,显示React is not defined

原因是在./src/app.js./src/components/my-component.js中,没有React的导入指令。因此,当JSX在构建过程中转换为React.createElement时,当您的bundle在浏览器中执行时,没有对React的声明和可访问的引用;从而产生误差。

要解决此问题,请在两个文件的顶部添加import指令。

import React from 'react';

注意:运行带有或不带有import指令的构建可能会很有用,以查看代码如何随每次构建而变化。

我正在将create-react-app完整系统迁移到Vite。有了这个问题,我不能一次重命名数百个文件的扩展名。

关于Vite 4。可以覆盖一些esint规则。您可以在github上看到完整的讨论和解决方案的演变。https://github.com/vitejs/vite/discussions/3448

我使用的解决方案只是重新配置vite.config.js文件。解决方案设置为平等地优化所有文件,而不区分普通js和jsx。最好的解决方案是在未来将所有文件重命名为正确的扩展名,这样优化器可以产生最佳结果。

带有变通解决方案的干净文件:

import { defineConfig, transformWithEsbuild } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
// Workaround
{
name: 'load+transform-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', // 👈 this is important
});
},
},
// End workaround
],
// Workaround before renaming .js to .jsx
optimizeDeps: {
esbuildOptions: {
loader: {
'.js': 'jsx',
},
},
},
// End workaround

})

PS:如果您正在将代码添加到现有的vite.config中。有一个额外的从vite导入的解决方法。

最新更新