Description
Describe the bug
I found this issue when upgrading a project that was using jsdom
in server pages when upgrading from @sveltejs/kit@1.0.0-next.401
to @sveltejs/kit@1.0.0-next.491
but I have also seen this in newer versions like @sveltejs/kit@1.0.0-next.501
.
When loading a page where the +page.server.ts
includes jsdom
, it throws an error in the console about an optional dependency for canvas
ENOENT: no such file or directory, open '__vite-optional-peer-dep:canvas:jsdom'
Error: ENOENT: no such file or directory, open '__vite-optional-peer-dep:canvas:jsdom'
at Object.openSync (node:fs:585:3)
at Object.readFileSync (node:fs:453:35)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1122:18)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (./node_modules/jsdom/lib/jsdom/utils.js:158:18)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
Of note in the stacktrace is this line ./node_modules/jsdom/lib/jsdom/utils.js:158
. Which looks like this
exports.Canvas = null;
let canvasInstalled = false;
try {
require.resolve('canvas');
canvasInstalled = true;
} catch (e) {
// canvas is not installed
}
if (canvasInstalled) {
////// 👇 This is the line that causes the error //////
const Canvas = require('canvas');
if (typeof Canvas.createCanvas === 'function') {
// In browserify, the require will succeed but return an empty object
exports.Canvas = Canvas;
}
}
I was unable to reproduce this error in vite alone, and before the upgrade it was not an issue.
Reproduction
This problem can be reproduced by
- Creating a new sveltekit project
- Adding the
jsdom
dependency - Adding an import to
jsdom
to a new+page.server.ts
file - Loading that page in the browser
I have a repo made with the above steps
In that repo, you can see the issue by running npm run dev
If you replace the require.resolve('canvas');
line in ./node_modules/jsdom/lib/jsdom/utils.js:158
, with the below
const r = require.resolve('canvas');
console.log('I RESOLVED CANVAS', JSON.stringify(r, null, 2));
You can see that it returns a string like in the error
I RESOLVED CANVAS "__vite-optional-peer-dep:canvas:jsdom"
If you comment out the import jsdom...
the error goes away and the page loads the code that mimics the code in the jsdom
modules, but require.resolve
throws the exception that jsdom
expects and so the require
is skipped and there is no issue.
Logs
No response
System Info
System:
OS: macOS 12.6
CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
Memory: 32.01 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm
Browsers:
Chrome: 105.0.5195.125
Firefox: 104.0.1
Safari: 16.0
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.76
@sveltejs/kit: next => 1.0.0-next.491
svelte: ^3.44.0 => 3.50.1
vite: ^3.1.0 => 3.1.3
Severity
blocking an upgrade
Additional Information
No response