React Vite:找不到本地模块的导出(从 CRA 迁移)

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

我正在尝试从本地 Nodejs 包导入导出的成员。在使用 Vite(标准 CRA webpack 设置)之前这些工作正常,但自从切换到 Vite 后,我收到以下错误:

Uncaught SyntaxError:
The requested module '/@fs/Users/...{long_path}.../lib/shared/countries/build/index.js' 
does not provide an export named 'countryListAllIsoData'

Vite 项目是使用

npm create vite@latest
使用 typescript、react、swc 预设进行设置的。
这些失败的导入仅发生在本地软件包上(没有从 npm 注册表安装的软件包),所以我确信问题出在我这边,但我无法找到导致它的原因。

问题 1:如何使这些导入工作?

虽然他们确实使用 Webpack 工作,但我不太清楚为什么他们不能使用 Vite 工作? Vite 要求我的项目将项目设置为模块(在

package.json
-
"type": "module"
中)。模块中导入的工作方式是否会破坏我当前的代码?

问题 2:如何让我的 linter 显示这些错误?

我正在使用 VS Code,它似乎对模块的导入方式非常满意。没有显示任何错误,我可以毫无问题地转到导入的定义(让我相信所有内容都已正确导出)。

相关代码片段

我导入如下:

import { countryListAllIsoData } from "countries";

tsconfig.json
文件未受影响(与
npm create vite@latest
创建时完全相同)。这同样适用于
package.json
文件,除了安装了一些模块(例如导致此问题的模块)。

导致此问题的本地包名为

countries
,相当小且简单。它有以下
package.json
文件:

/// package.json
{
  "name": "countries",
  "version": "1.0.0",
  "description": "",
  "main": "./build/index.js",
  "exports": {
    ".": "./build/index.js"
  },
  "scripts": {
    "build": "tsc",
    "prepare": "npm run build"
  },
  "keywords": [],
  "author": "Bram Vanbilsen",
  "license": "UNLICENSED",
  "devDependencies": {
    "typescript": "^4.8.4"
  }
}

tsconfig.json
文件:

{
  "compilerOptions": {
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

    "module": "commonjs",                                /* Specify what module code is generated. */
    "moduleResolution": "nodenext",                       /* Specify how TypeScript looks up a file from a given module specifier. */

    "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
    "outDir": "./build",                                   /* Specify an output folder for all emitted files. */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    
    "strict": true,                                      /* Enable all strict type-checking options. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

index.ts
文件:

export const countryListAllIsoData = [...] as const;
node.js typescript node-modules vite es6-modules
2个回答
0
投票

我遇到了这个问题,并使用 Vite 别名修复了它。

在Vite配置中,为包名添加别名,并带有本地文件夹的绝对路径:

resolve: {
    alias: {"countries":"/Users/...{long_path}.../lib/shared/countries"}
}

0
投票

问题

我也遇到过同样的问题并且能够解决它。

问题是 vite 与 e.g. 相比webpack 需要 ESM 模块才能工作,因为这是 Vite 与其他捆绑器相比如此快的主要原因。由于这个原因以及其他一些原因,Vite 将预先捆绑依赖项并执行从 UMD 或 CommonJS 模块到 ESM 模块的转换。

引自Vite文档-依赖预捆绑

CommonJS 和 UMD 兼容性:在开发过程中,Vite 的开发人员将所有代码作为原生 ESM 提供服务。因此,Vite 必须首先将作为 CommonJS 或 UMD 提供的依赖项转换为 ESM。

但是,Vite 不会对链接(本地)依赖项执行此转换。因此,您必须确保仅使用 ESM 模块。

解决方案#1

要解决此问题,您需要更改库语法的

tsconfig.json
以使用 ESM 模块,因此
"module"
不得为
commonjs
,但应该例如是
ES6
ESNext
等。您还需要将
"moduleResolution"
调整为
ES6
ESNext
或 TypeScript >= 5.x.x
Bundler

所以你的

tsconfig.json
应该看起来像这样:

{
  "compilerOptions": {
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

    "module": "ESNext",                                /* Specify what module code is generated. */
    "moduleResolution": "Bundler",                       /* Specify how TypeScript looks up a file from a given module specifier. */

    "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
    "outDir": "./build",                                   /* Specify an output folder for all emitted files. */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    
    "strict": true,                                      /* Enable all strict type-checking options. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

解决方案#2:

引自Vite文档-Monorepos和链接依赖


在 monorepo 设置中,依赖项可能是来自同一存储库的链接包。 Vite 会自动检测未从“node_modules”解析的依赖项,并将链接的 dep 视为源代码。它不会尝试捆绑链接的 dep,而是会分析链接的 dep 的依赖项列表。

但是,这需要将链接的 dep 导出为 ESM。如果没有,您可以在配置中将依赖项添加到

optimizeDeps.include
build.commonjsOptions.include

export default defineConfig({
  optimizeDeps: {
    include: ['linked-dep'],
  },
  build: {
    commonjsOptions: {
      include: [/linked-dep/, /node_modules/],
    },
  },
})

对链接的 dep 进行更改时,请使用

--force
命令行选项重新启动开发服务器以使更改生效。


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