Issues with ESM module import syntax and endless loop during load in SSR
See original GitHub issueDescribe 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
- Create an instance of the vite-plugin-ssr vue starter app:
npm init vite-plugin-ssr
- Change the type to
module
in package.json:
{
…
"type": "module",
…
}
- Install JSDB:
npm i @small-tech/jsdb
- Add the following line to pages/_default.page.server.js:
import JSDB from '@small-tech/jsdb'
- 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:
- Created 2 years ago
- Comments:8 (5 by maintainers)
Top GitHub Comments
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.Yes and currently transpiled Node.js code is evaluated by using
new Function
, seevite/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.