question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Issues with ESM module import syntax and endless loop during load in SSR

See original GitHub issue

Describe the bug

JSDB is a 100% JavaScript database. The latest version is written in ESM. Simply importing it in the SSR server script (in vite-plugin-ssr) causes errors that do not otherwise exist in other contexts.

(I am trying to use an ESM node module that otherwise works fine during SSR with Vite.)

Reproduction

  1. Create an instance of the vite-plugin-ssr vue starter app:
npm init vite-plugin-ssr
  1. Change the type to module in package.json:
{
  …
  "type": "module",
  …
}
  1. Install JSDB:
npm i @small-tech/jsdb
  1. Add the following line to pages/_default.page.server.js:
import JSDB from '@small-tech/jsdb'
  1. Run the dev server:
npm run dev

What should happen?

There should not be any errors.

What actually happens?

Initially, you get the following error:

Error: Failed to resolve import "fs/promises" from "pages/_default/_default.page.server.js". Does the file exist?
    at formatError (/home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:43582:46)

This is because the JSTable.js file in JSDB has the following import:

import fsPromises from 'fs/promises'

I don’t know if this is an issue with vite-plugin-ssr or vite itself but I’m leaning towards the latter. The workaround is to change the import to:

import fs from 'fs'
const fsPromises = fs.promises

Needless to say, while I can do this in a module I control, this would mean I’d have to update all third-party modules that might use these sorts of imports in the future to make them compatible.

Once that error is out of the way, you get several related errors:

1:53:15 PM [vite] error while updating dependencies:
Error: Build failed with 3 errors:
node_modules/@small-tech/jsdb/lib/JSTable.js:26:9: error: No matching export in "browser-external:perf_hooks" for import "performance"
node_modules/@small-tech/jsdb/lib/Time.js:15:9: error: No matching export in "browser-external:perf_hooks" for import "performance"
node_modules/@small-tech/jsdb/lib/Util.js:15:9: error: No matching export in "browser-external:util" for import "types"
    at failureErrorWithLog (/home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/esbuild/lib/main.js:1224:15)
    at buildResponseToResult (/home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/esbuild/lib/main.js:936:32)
    at /home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/esbuild/lib/main.js:1035:20
    at /home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/esbuild/lib/main.js:568:9
    at handleIncomingPacket (/home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/esbuild/lib/main.js:657:9)
    at Socket.readFromStdout (/home/aral/small-tech/small-web/sitekit/sandbox/vite-ssr-project/node_modules/esbuild/lib/main.js:535:7)
    at Socket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9)
    at Socket.Readable.push (internal/streams/readable.js:223:10)

This time it’s clearly an esbuild error from the stack trace. The previous error did not have the same stack trace but it might also have to do with vite’s use of esbuild.

I don’t think the problem is with esbuild itself as I bundle Place using esbuild and it imports JSDB without issues. And I also just tried it with esbuild 0.9.3 – the same version used here – and it worked without issues.

Again, the fix is to rewrite the imports:

So import { performance } from 'perf_hooks' becomes:

import perfHooks from 'perf_hooks'
const performance = perfHooks.performance

etc.

Once those changes have been made, I no longer get errors but loading the index page causes the browser to enter an infinite loading loop with no warnings or errors either in the browser or on the console.

There is a chance that this is an issue with vite-plugin-ssr, so I’ve opened an issue there also also but it feels like it is more a general Vite issue to me.

System Info

Output of npx envinfo --system --npmPackages vite,@vitejs/plugin-vue --binaries --browsers:

  System:
    OS: Linux 5.4 elementary OS 5.1.7 Hera
    CPU: (12) x64 Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz
    Memory: 6.37 GB / 15.51 GB
    Container: Yes
    Shell: 5.4.2 - /usr/bin/zsh
  Binaries:
    Node: 14.16.0 - ~/.nvm/versions/node/v14.16.0/bin/node
    Yarn: 1.22.5 - /usr/bin/yarn
    npm: 7.6.0 - ~/.nvm/versions/node/v14.16.0/bin/npm
  Browsers:
    Firefox: 87.0

Additional system info

  • Vite: 2.2.4
  • Esbuild (via Vite): 0.9.3
  • vite-plugin-ssr: 0.1.0-beta.40
  • JSDB: 2.0.2

Used package manager: npm

Before submitting the issue, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the docs.
  • Check that there isn’t already an issue that reports the same bug to avoid creating a duplicate.
  • Provide a description in this issue that describes the bug.
  • Make sure this is a Vite issue and not a framework-specific issue. For example, if it’s a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/vue-next instead. (I’m pretty sure it’s a Vite-related issue.)
  • Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
aralcommented, May 5, 2021

OK, I’m going to close this. It might be worth having an issue to track support for pure ESM Node modules and using using import to load ESM externals but it looks like this is already unofficially on the radar at least.

1reaction
brilloutcommented, May 5, 2021

Yes and currently transpiled Node.js code is evaluated by using new Function, see vite/packages/vite/src/node/ssr/ssrModuleLoader.ts. So you’ll have to use CJS for the time being.

I guess we can close this ticket or replace it with a more precice one.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issues with ESM module import syntax and endless loop ...
To reproduce Create an instance of the vite-plugin-ssr vue ... Issues with ESM module import syntax and endless loop during load in SSR...
Read more >
require() of ES modules is not supported when importing node ...
node-fetch is an ESM-only module - you are not able to import it with require. We recommend you stay on v2 which is...
Read more >
How to Bypass ES Modules Errors in Next.js with Dynamic ...
The snippet above shows how you can import a module with dynamic imports and pass the ssr object as an argument to it....
Read more >
rollup.js
Importing CommonJS. Rollup can import existing CommonJS modules through a plugin. Publishing ES Modules. To make sure your ES modules are immediately usable...
Read more >
Migrating to React Query 4 - TanStack
To make the import migration easier, v4 comes with a codemod. The codemod is a best efforts attempt to help you migrate the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found