SyntaxError: Cannot use import statement outside a module (from dependency)

SyntaxError: Cannot use import statement outside a module (from dependency)

当依赖项未声明为模块时,如何解决依赖项中的“无法在模块外使用导入语句”?


我想使用 Svelte/kit 中的 validator 来验证电子邮件。但是,在导入 ESM 版本时,出现“无法在模块外使用导入语句”错误。我正在使用 pnpm 而不是 npm 或 yarn。

import isEmail from 'validator/es/lib/isEmail'
/node_modules/.pnpm/validator@13.6.0/node_modules/validator/es/lib/isEmail.js:1
import assertString from './util/assertString';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:355:18)
    at wrapSafe (node:internal/modules/cjs/loader:1039:15)
    at Module._compile (node:internal/modules/cjs/loader:1073:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)
    at Module.load (node:internal/modules/cjs/loader:989:32)
    at Function.Module._load (node:internal/modules/cjs/loader:829:14)
    at Module.require (node:internal/modules/cjs/loader:1013:19)
    at require (node:internal/modules/cjs/helpers:93:18)
    at nodeRequire 

似乎验证器正在尝试使用导入语句,但它 package.json 没有指定 "type": "module"。我的猜测是这是错误的根本原因。

调试步骤

相关

元数据

尝试像这样导入

import { isEmail } from "validator"

在没有更多信息的情况下,如果您的问题完全在于您所依赖的代码的问题,请考虑短期使用 patch-package to make the necessary adjustment, and long term, open up a PR over at the validator.js repo!

对于补丁包,只需将"type": "module"添加到node_modules/validator处的package.json,然后运行 npx patch-package validator。然后,您可以对输出的 diff 文件进行版本控制,假设补丁包是 (dev) 依赖项,则使用 npm hooks 自动进行更改。

此处库的行为或缺陷可能来自开发人员,他们更多地牢记诸如 webpack 之类的东西,它们按照自己的方式执行 esm 导入,而不是 svelte 正在使用的节点模块解析模式。或者至少问题是如何发展到这一步的。(这可能是错误的!)。

尝试像下面这样导入

const {isEmail} = require('validator');

你试过这样导入吗?

import validator from 'validator'

我尝试用最新的 SvelteKit 重现你的问题。这很好用:

// index.svelte
<script>
    import validator from 'validator';
    let result = validator.isEmail('foo@bar.com');
    console.log(result);
</script>

当我将导入语句更改为:

import validator from 'validator/es/lib/isEmail'

我从你的问题中得到了错误(不能在模块外使用导入语句)。

导入 validator/es/lib/isEmail 据说只会导入库的一个子集。我不确定它会带来多大的不同;它可能没有任何区别。稍大的构建胜过不起作用的构建。我建议先让它工作,然后在确实需要时优化构建大小。

阅读他们的文档后:https://github.com/validatorjs/validator.js#es6,看起来导入中的 es 部分是,所以它可以是 treeshakable。您可以通过正常导入来修复此错误:

import isURL from 'validator/lib/isURL';