语法错误:无法在模块外部使用导入语句(来自依赖项)

12

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


我想在Svelte/kit中使用validator来验证电子邮件。但是,当导入ESM版本时,我会收到“无法在模块外部使用import语句”的错误。我使用的是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 

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

调试步骤

  • package.json有"type": "module"
  • 升级到最新版本的node
  • 尝试使用validator的非ESM版本 'validator/lib/isEmail',但会导致其他与此主题无关的错误。

相关内容

元数据

  • Node: v16.2.0
  • Sveltekit: v1.0.0-next.115
  • Validator: 13.6.0

在将package.json中的"type": "module"属性设置后,您是否重新启动了编辑器?如果您不重新加载项目,则智能感知无法识别它,因此可能会出现一些工作正常但智能感知无法使用的情况,这会导致看起来好像您做错了什么,实际上并非如此。 - JΛYDΞV
刚刚尝试了一下,似乎没有帮助。这也不像是智能感知的问题。在尝试启动Sveltekit时出现了错误。 - Nick
你看过这个类似的帖子吗? - Jeevan HS
6个回答

5

你是否尝试过像这样进行导入?

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'

我从你的问题中得到了一个错误(无法在模块外使用import语句)。

导入validator/es/lib/isEmail,据说只导入库的子集。我不确定这会有多大的区别;它可能没有任何区别。一个稍微大一点的构建比一个不能工作的构建更好。我建议先让它工作,然后如果你真的需要,再优化构建大小。


1
可以。有趣的是,当我使用更新版本的Svelte/kit时,也能够使用validator/lib/isEmail - Nick
@Nick 你能在使用适配器构建时使用它吗?我可以在运行 Svelte-Kit 开发服务器时使用此导入,但是当我尝试使用 node 适配器将其构建为生产环境时,会出现“错误[ERR_MODULE_NOT_FOUND]:找不到模块”的问题。 - Tom Böttger

1

如果您在使用typescript部署nodejs时遇到了同样的问题,以下内容可能会对您有所帮助。

在主项目中,我的package.json文件中已经设置了"type":"module"。我将通过npm run build创建的构建目录放置在服务器上。

working-dir
  |--build
       |--index.js
       |--...

我本来以为只需要运行node build/index.js,因为我认为所有的东西都已经被打包好了。结果发现我需要在工作目录中添加一个package.json文件 (我觉得把它放到构建目录中也可以)
server
+ |--package.json 
  |--build
       |--index.js
       |--...

// package.json
{
  "type": "module"
}

0

0

尝试像这样导入

import { isEmail } from "validator"

似乎这并没有帮助,因为我的代码已经是一个ESM模块了。 - Nick
非 ESM 版本会出现哪些错误? - AngelNext

0

如果您的问题仅仅是与依赖代码有关,考虑短期使用类似 patch-package 的工具进行必要的调整,长期来看,可以在 validator.js repo 上开放一个 PR!

对于 patch-package,只需在 node_modules/validator 的 package.json 中添加 "type": "module",然后运行 npx patch-package validator。然后您可以将输出的差异文件进行版本控制,并且假设 patch-package 是 (dev) 依赖项,则更改会自动进行 npm 钩子。

这里库的行为或缺陷可能更多地考虑了像 webpack 这样按照自己的规则进行 esm 导入的事情,而不是 svelte 使用的节点模块解析模式,或者至少问题已经到了这个程度。(可能是错误的!)


-2

尝试像下面这样导入

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

1
不错的想法,但是SvelteKit没有访问require的权限。 - Leftium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接