vitest icon indicating copy to clipboard operation
vitest copied to clipboard

server.deps.inline doesnt work

Open shirecoding opened this issue 1 year ago • 7 comments

Describe the bug

i have a package that i cant replace "@coral-xyz/anchor"

Vitest gives me the following error and solution

Module .../@coral-xyz/anchor/dist/esm/workspace.js:1 seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package "@coral-xyz/anchor" asking them to ship the file in .mjs extension or add "type": "module" in their package.json.

As a temporary workaround you can try to inline the package by updating your config:

// vitest.config.js
export default {
  test: {
    server: {
      deps: {
        inline: [
          "@coral-xyz/anchor"
        ]
      }
    }
  }
}

I tried to implement this with no avail

import { purgeCss } from "vite-plugin-tailwind-purgecss";
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
// "vite-plugin-node-polyfills": "^0.17.0" is required for this to work 0.19.0 does not work with buffer
import { nodePolyfills } from "vite-plugin-node-polyfills";

export default defineConfig({
    envDir: "../",
    plugins: [sveltekit(), purgeCss(), nodePolyfills()],
    define: {},
    resolve: {
        alias: {
            process: "process/browser",
        },
    },
    test: {
        server: {
            deps: {
                inline: ["@coral-xyz/anchor"],
            },
        },
    },
});

As it is a critical library i am totally stuck. I tried using environment="jsdom" but now crypto.getRandomValues() is not defined, i then tried to polyfill crypto in setupFiles, but it doesnt work, i read that its run after jsdom setup. There doesnt seem to be a solution other than abandoning vitest and moving to jest were their setup file runs before jsdom.

  1. inline server.deps doesnt seem to solve the problem
  2. cant polyfill jsdom to avoid 1.

Reproduction

import { purgeCss } from "vite-plugin-tailwind-purgecss";
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
// "vite-plugin-node-polyfills": "^0.17.0" is required for this to work 0.19.0 does not work with buffer
import { nodePolyfills } from "vite-plugin-node-polyfills";

export default defineConfig({
    envDir: "../",
    plugins: [sveltekit(), purgeCss(), nodePolyfills()],
    define: {},
    resolve: {
        alias: {
            process: "process/browser",
        },
    },
    test: {
        server: {
            deps: {
                inline: ["@coral-xyz/anchor"],
            },
        },
    },
});

System Info

System:
    OS: macOS 14.3.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 15.03 GB / 64.00 GB
    Shell: 3.6.1 - /opt/homebrew/bin/fish
  Binaries:
    Node: 21.2.0 - /opt/homebrew/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.2.3 - /opt/homebrew/bin/npm
  Browsers:
    Brave Browser: 121.1.62.156
    Chrome: 121.0.6167.160
    Safari: 17.3.1
  npmPackages:
    @vitest/browser: ^1.2.2 => 1.2.2 
    vite: ^5.0.3 => 5.0.12 
    vitest: ^1.2.2 => 1.2.2

Used Package Manager

npm

Validations

shirecoding avatar Feb 14 '24 06:02 shirecoding

Using mocha test doesn't seem to throw the error for inlining the module. is vitest being to strict? seems many external modules are not following best practices and waiting for them to fix their packages is not realistic

shirecoding avatar Feb 14 '24 09:02 shirecoding

There is not enough reproduction. What is the actual code that's running?

sheremet-va avatar Feb 14 '24 09:02 sheremet-va

Hello @shirecoding. Please provide a minimal reproduction using a GitHub repository or StackBlitz. Issues marked with need reproduction will be closed if they have no activity within 3 days.

github-actions[bot] avatar Feb 14 '24 09:02 github-actions[bot]

I can reproduce the issue, with another package I rely on.

https://stackblitz.com/edit/vitest-dev-vitest-anpy79?file=src%2Fbasic.ts

diagram-js-grid uses CommonJS modules, but imports diagram-js/lib/features/grid-snapping/GridUtil, which is using ES6 modules, but the diagram-js package does not have "type": "module" in its package.json. I don't even have to use the value in the test, just having the import in the SUT file is enough to blow vitest up. I tried adding the suggested configuration to the config file, but it has no effect -- the error still shows up. If I go into node_modules and manually change diagram-js to be "type": "module" it does not fix the issue either - it just makes the diagram-js-grid module blow up as it can't import an ES module from a require() statement. Both modules work fine in an actual browser application built using Vite and ESBuild.

joeskeen avatar Feb 15 '24 10:02 joeskeen

@joeskeen Thanks for the reproduction.

I tried adding the suggested configuration to the config file, but it has no effect -- the error still shows up.

In your case, probably this is more like diagram-js-grid side packaging issue, but since Vitest's suggestion is only a best-effort guess, so it might be confusing sometimes.

diagram-js-grid already provides esm version in diagram-js-grid/dist/index.esm.js but Vitest doesn't pick that up by default. To workaround this, I think you can use resolve.alias["diagram-js-grid"] or resolve.mainFields. Here is an updated reproduction to illustrate this. Does either of approach work for you? https://stackblitz.com/edit/github-eex6nv?file=vite.config.ts

hi-ogawa avatar Feb 17 '24 02:02 hi-ogawa

Yeah, I did discover the esm version in the dist folder and switched to that and things worked. But it still does highlight that the warning that vitest gives and the suggested resolution doesn't appear to work, or really do anything.

joeskeen avatar Feb 17 '24 02:02 joeskeen

Right, If current error message's suggestion doesn't help in some cases, then we might need to adjust that and expand on other possibilities. I don't think we would change the default behavior, but we might be able to help some situation by improving error message + documentation.

hi-ogawa avatar Feb 17 '24 02:02 hi-ogawa

I think the problem is when there are require imports in esm modules and vitest detects that and throws the error? However some libraries use require in esm because apparently some bundles support that

I've been trying to ask some of the mantainers to fix their package which throws this error you can look here https://github.com/coral-xyz/anchor/issues/2844

I have to manually patch any require statements inside the esm modules. but its pretty hard to get all 3rd party packages to fix it? is it possible to make vitest allow require statements in esm moduels?

shirecoding avatar Mar 15 '24 14:03 shirecoding

Thanks for the update. Btw, is it something reproducible without sveltekit and other plugins? It would be easier for us to look into further if you could provide a reproducrtion just with "@coral-xyz/anchor".


Hmm, I just took a look and this looks like a bit exotic code. Vites/Vite-node is more generous when it comes to cjs, but I'm not even sure what other bundlers do with this:

https://cdn.jsdelivr.net/npm/@coral-xyz/[email protected]/dist/esm/index.js

import { isBrowser } from "./utils/common.js";
export { default as BN } from "bn.js";
export * as web3 from "@solana/web3.js";
export { getProvider, setProvider, AnchorProvider, } from "./provider.js";
...
if (!isBrowser) {
    exports.workspace = require("./workspace.js").default;
    exports.Wallet = require("./nodewallet.js").default;
}

hi-ogawa avatar Mar 16 '24 02:03 hi-ogawa

Yep that was the code causing the issue, i had to manually patch that to use dynamic imports and it worked, i did ask them if its possible to change it to that though im not sure if its possible that vitest can handle it

shirecoding avatar Mar 17 '24 08:03 shirecoding