Skip to content

Issue after upgrade using jsdom with optional dependencies #10255

@robpc

Description

@robpc

Describe the bug

I noticed an issue after upgrading an ssr project with vite from 3.0.4 to 3.1.3. Using jsdom in a server side page results in an error about an optional dependency.

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)

This error was not present before the upgrade and the optional dependency is not used in the project. If you look at the jsdom line referenced above, you see

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;
  }
}

Which if you replace the line require.resolve('canvas'); with something like

const r = require.resolve('canvas');
console.log('I RESOLVED CANVAS', JSON.stringify(r, null, 2));

You will get

I RESOLVED CANVAS "__vite-optional-peer-dep:canvas:jsdom"

Obviously that is not what jsdom is expecting and causes it to enter the block that requires the missing module.

I reproduced this issue by using the starter template npm create vite-extra@latest -- --template ssr-vanilla and installing jsdom and adding an import statement to the entry-server.js file. Here is a link to that simple project with the issue. Downgrading the version of vite to 3.0.4 removes the error.

Reproduction

https://github.com/robpc/vite-ssr-optional-dependency-issue

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

Used Package Manager

npm

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions