当将 esbuild 与外部反应一起使用时,我得到 Dynamic require of "react" is not support

yig*_*gal 12 esbuild

我正在尝试将 esbuild 与外部反应一起使用。

这是我的 package.json 文件中的 esbuild 命令

  "scripts": {
    "esbuild": "esbuild ./src/index.js --bundle --outfile=dist/esmain.js --loader:.js=jsx --external:react-dom --external:react "
  }
Run Code Online (Sandbox Code Playgroud)

运行命令时,我没有收到任何错误:

npm run esbuild

> @1.0.0 esbuild C:\prog
> esbuild ./src/index.js --bundle --outfile=dist/esmain.js --loader:.js=jsx --external:react-dom --external:react


  dist\esmain.js  32.7kb

Done in 13ms
Run Code Online (Sandbox Code Playgroud)

问题是,当我在浏览器(chrome)中运行程序时,我在控制台中收到此错误

Uncaught Error: Dynamic require of "react" is not supported
    at __require (esmain.js:12)
    at esmain.js:27
    at esmain.js:899
Run Code Online (Sandbox Code Playgroud)

任何想法如何解决这一问题?

Sin*_*pcs 12

问题

当您收到此错误时,这意味着您require("react")的构建结果中有某个地方esm

解决方案

  1. require("react")在您的构建目录中搜索例如your-package/dist
  2. 检查哪个依赖项导致了此问题。对我来说,其中之一是@emotion/styled
var require_emotion_styled_base_cjs_prod = __commonJS({
  "../../node_modules/@emotion/styled/base/dist/emotion-styled-base.cjs.prod.js"(exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var _extends3 = require_extends();
    var React27 = __require("react");
Run Code Online (Sandbox Code Playgroud)
  1. 通过任一方式修复它
  • 将包添加到 esbuild 的外部选项中,tsup.config.ts以将其从构建中排除。

https://esbuild.github.io/api/#external

tsup.config.ts:

import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.ts'],
  dts: true,
  format: ['esm', 'cjs'],
  outExtension({ format }) {
    return {
      js: `.${format}.js`,
    };
  },

  // Add this
  esbuildOptions(options) {
    options.external = ['@emotion/*'];
  },
});
Run Code Online (Sandbox Code Playgroud)
  • 或者,通过安装依赖项。就我而言,将其添加到我的依赖项后,我的构建结果中不再@emotion/styled有。require("react")

  • 我导入的包处于依赖关系中,但 myfile.mjs 中的动态 require 仍然存在问题( (2认同)

zit*_*hir 5

如果您尝试做的是从全局窗口范围(如and )访问reactand ,那么这不是 esbuil选项的作用。react-domwindow.Reactwindow.ReactDOMexternal

根据文件

导入不会被捆绑,而是会被保留(对 iife 和 cjs 格式使用 require,对 esm 格式使用 import),并将在运行时进行评估。

最重要的是,我认为 esbuild 添加了一些检查require目标环境是否支持的检查,而在浏览器中默认情况下是不支持的。因此出现了错误。

您将需要esbuild-plugin-external-global并按如下方式配置插件:

esbuild.build({
  ...
  plugins: [
    externalGlobalPlugin({
      'react': 'window.React',
      'react-dom': 'window.ReactDOM',
    })
  ]
  ...
});
Run Code Online (Sandbox Code Playgroud)

此时,您可能需要一个构建脚本,而不是esbuild通过命令行使用选项进行调用。


Mar*_*nek -4

您想通过将 React 标记为外部来实现什么目的?根据我在文档中读到的内容,我能想到的唯一用例是一个加载了 React common js 的网站,并且您想在脚本中重用此代码。但我的问题是 - 为什么在同一页面上有 2 个应用程序,并且在此基础上构建不同。

不知道这是否有帮助,但我写了一篇关于构建使用 esbuild 生成的 create-react-app 的文章- 构建 React 代码似乎非常顺利,特别是与其他一些框架相比。