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

6

12

How do you resolve "Cannot use import statement outside a module" from a dependency when the dependency isn't declared as a module?


I want to use the validator in Svelte/kit to validate emails. However, when importing the ESM version, I get the "Cannot use import statement outside a module" error. I'm using pnpm instead of npm or yarn.

import isEmail from 'validator/es/lib/isEmail'
/node_modules/.pnpm/[email protected]/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 

It appears that validator is attempting to use the import statement, but it's package.json does not specify "type": "module". My guess is that this is the root cause of the error.

Debug steps

  • package.json has "type": "module"
  • Upgraded to latest version of node
  • Tried using the non-esm version of validator 'validator/lib/isEmail', but that causes other errors not related to this thread.

Related

Metadata

  • Node: v16.2.0
  • Sveltekit: v1.0.0-next.115
  • Validator: 13.6.0
Fairspoken answered 18/6, 2021 at 18:19 Comment(3)
Did you restart your editor after setting the type property to "type": "module" in your package.json? If you don't reload the project, intellisense doesn't pickup on it, so things can be working, but intellisense won't be, so it appears as if your doing something wrong, when in fact you are not.Corina
Just tried, and that doesn't seem to help. This also doesn't seem to be an intellisense issue either. The error occurs when trying to start Sveltekit.Fairspoken
Have you looked at this similar post ?Edger
M
5

Have you tried importing like this?

import validator from 'validator'

I tried reproducing your issue with latest SvelteKit. This works fine:

// index.svelte
<script>
    import validator from 'validator';
    let result = validator.isEmail('[email protected]');
    console.log(result);
</script>

When I changed the import statement to:

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

I got the error from your question (Cannot use import statement outside a module).

Importing validator/es/lib/isEmail supposedly only imports a subset of the library. I'm not sure how much difference it will make; it might not make any difference. A slightly larger build beats a build that doesn't work. I suggest getting it working first, then optimize the build size if you really need to.

Mama answered 23/6, 2021 at 15:26 Comment(2)
That works. Interestingly, using a newer version of Svelte/kit, I was able to use validator/lib/isEmail as well.Fairspoken
@Fairspoken Were you able to use it even when building with an adapter? I can use this import when running the svelte-kit development server but when I try to build it for production with the node adapter, I get Error [ERR_MODULE_NOT_FOUND]: Cannot find moduleMoen
B
1

For those that happen to have the same problem while deploying with nodejs using typescript.

"type":"module" was already set in my package.json in the main project. I put the build directory on the server (created by npm run build).

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

I thought i had to just run node build/index.js, as I thought everything was packaged. Turns out I need to add a package.json into the working directory (I think it also works by putting it into the build directory).

server
+ |--package.json 
  |--build
       |--index.js
       |--...

// package.json
{
  "type": "module"
}
Burglar answered 28/6, 2022 at 19:1 Comment(0)
I
0

Try importing like this

import { isEmail } from "validator"
Inbreathe answered 18/6, 2021 at 19:9 Comment(2)
That doesn't seem to be helping since my code is an ESM module already.Fairspoken
What errors does the non-esm version give?Inbreathe
P
0

Without more information, if your problem solely lies in a problem with code you are dependent on, consider short term using something like patch-package to make the necessary adjustment, and long term, open up a PR over at the validator.js repo!

for patch-package, just go add the "type": "module" to the package.json at node_modules/validator, and then run npx patch-package validator. You can then version control the outputted diff file, and the changes are made automatically with npm hooks assuming patch-package is a (dev) dependency.

The behavior or defect of the library here is probably from the devs more keeping in mind things like webpack that do esm imports on their own terms, and not with the node module resolution patterns that it appears svelte is using. or at least how the problem has gotten this far.(might be wrong about this!).

Peruzzi answered 22/6, 2021 at 2:10 Comment(0)
A
0

After reading their docs: https://github.com/validatorjs/validator.js#es6, it looks like the es part in the import is, so it can be treeshakable. You can fix this error, by just importing it normally:

import isURL from 'validator/lib/isURL';
Aluino answered 14/9, 2021 at 17:27 Comment(0)
R
-2

Try to import like below

const {isEmail} = require('validator');
Rogozen answered 23/6, 2021 at 10:22 Comment(1)
Nice idea, but SvelteKit doesn't have access to requireMama

© 2022 - 2024 — McMap. All rights reserved.