获取汇总以解决浏览器捆绑的node_modules中的无扩展导入问题

问题描述 投票:0回答:1

rollup 在尝试导入 NPM 模块时给了我这样的错误:

main.js → stdout...
[!] Error: Could not load myfolder\node_modules\three\examples\jsm\renderers\CSS2DRenderer (imported by node_modules/openbim-components/core/SimpleRenderer/index.js): ENOENT: no such file or directory, open 'myfolder\node_modules\three\examples\jsm\renderers\CSS2DRenderer'
Error: Could not load myfolder\node_modules\three\examples\jsm\renderers\CSS2DRenderer (imported by node_modules/openbim-components/core/SimpleRenderer/index.js): ENOENT: no such file or directory, open 'myfolder\node_modules\three\examples\jsm\renderers\CSS2DRenderer'

直接原因是,例如

node_modules/openbim-components/core/SimpleRenderer/index.js
包含像这样的进口
import { CSS2DRenderer } from "three/examples/jsm/renderers/CSS2DRenderer";

即Typescript风格,或者nodeJS风格,不带.js后缀。 (如果我手动编辑每个此类导入以包含 .js 后缀,错误就会消失,但事实并非如此..)

澄清一下:实际文件名为 CSS2DRenderer.js,带有后缀。

我尝试从 rollup.js 文档中找出控制后缀处理/匹配的因素。 看来commonJS模式支持省略后缀? 但据我所知,openbim-components 不是一个 commonJS 模块吗? (如果我在这里弄错了,这可能就是答案?)。

我正在使用

"@rollup/plugin-node-resolve": "^15.2.1" 
在我的 rollup.config.mjs, 这显然是使用 npm 模块与 rollup 的方式..? 但其文档没有提及任何有关默认/缺少 .js 后缀的机制。

在 rollup 内部的某个地方,有一个名为

addJsExtensionIfNecessary()
的函数,但它显然在这里没有帮助我..大概是因为它与 commonJS 绑定在一起..?

我尝试使用附加汇总插件来解决该问题 'rollup-plugin-includepaths' 和 'rollup-plugin-resolve', 听起来他们可能会帮助解决这个问题,但相反,他们只会让事情变得更糟(?)

我的目标是使用 rollup 为网页构建bundle.js 文件。 奇怪的是,工具 vite 似乎可以处理这种情况,并且 vite 内部使用了 rollup。 但我不能告诉人们改用 vite (我的正确目标是确保我们可以在我的公司中普遍使用 openbim-components 工具,因此它必须“在一般情况下工作”,而不仅仅是在特殊情况下。)

我觉得我缺少一些关于如何正确使用 rollup 的知识。

rollupjs
1个回答
0
投票

这里有两个问题。

openbim-components
仅作为 ESM 发布,但是,
package.json
文件未指定
"type": "module"
。文件应具有
*.mjs
扩展名或应指定
type: "module"
。但是,由于您使用的是捆绑器,因此不会导致此问题。仅当您打算在 Node.js 运行时运行此代码时,它才会成为问题。

现在,下一个问题是有问题的。

three
所依赖的包
openbim-components
正在使用ESM并在
"type": "module"
文件中正确指定
package.json
。但与此同时,它正在使用新的 exports 字段。这是它的指定方式:

{
  "exports": {
    ".": {
      "import": "./build/three.module.js",
      "require": "./build/three.cjs"
    },
    "./examples/fonts/*": "./examples/fonts/*",
    "./examples/jsm/*": "./examples/jsm/*",
    "./addons/*": "./examples/jsm/*",
    "./src/*": "./src/*",
    "./nodes": "./examples/jsm/nodes/Nodes.js"
  },
}

这就是问题。这些没有正确指定。根据规范,无扩展名导入应在右侧指定 extension,如下所示:

{
  "exports": {
    "./examples/jsm/*": "./examples/jsm/*.js",
    "./addons/*": "./examples/jsm/*.js",
    "./src/*": "./src/*.js",
  }
}

要么两边都应该有扩展名,要么如果库的作者希望用户使用无扩展名导入,那么只应该在右侧指定。要点是导出映射应正确映射到具有扩展名的正确文件。

WebpackVite 提供了别名解析,您可以在此处使用它。 Rollup 没有为此提供任何现成的东西,但它有一个官方插件 -

@rollup/plugin-alias
可以帮助您实现这一目标:

import alias from '@rollup/plugin-alias';

export default {
  // ...other configuration
  plugins: [
    alias({
      entries: [
        // Or something similar to this configuration
        {
          find: 'three/examples/jsm/renderers/CSS2DRenderer',
          replacement: 'three/examples/jsm/renderers/CSS2DRenderer.js'
        },
      ]
    })
  ]
};

我以前从未在 Rollup 中使用过别名;但这是目前唯一的方法。另外,请考虑向两个存储库提出问题。

© www.soinside.com 2019 - 2024. All rights reserved.