2

I'm creating a utility package that exports multiple tools like eslint, playwright, vitest, react testing library etc, and I'm using rollup to bundle the package. However, when I install this package in the consumer project and try running npm run test, I get:

Error: Vitest failed to access its internal state. One of the following is possible:

  • "vitest" is imported directly without running "vitest" command
  • "vitest" is imported inside "globalSetup" (to fix this, use "setupFiles" instead, because "globalSetup" runs in a different context)
  • Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues

After searching through a few resources, I stumbled upon this Github issue comment which said, the problem is likely bottling up due to re-exporting a module in an entry file (e.g: dist/index.js) that is importing vitest which is what I was precisely doing. But when I created another entry point (non index.js) and tried exporting the module, it still gave the same error. Further, if I didn't export anything vitest from my package but included it as a dependency (instead of devDependencies) and used the imports directly from vitest/rtl in my consumer project it did work correctly, but that's not what I want.

What Am I trying to achieve?

I'd want to export all the methods/functions on `vitest` and `@testing-library/react` from my custom package and use them in my consumer project by importing the modules from my package instead of `vitest`/`rtl`, but when I'm doing this I'm getting the above error. How should I go about fixing this?

My package's code structure looks something like this:

src
  eslint:
    index.ts
  playwright:
    index.ts
  vitest:
    index.ts (tried with a non-index name, threw the same error)
      import * as vitest from 'vitest'
      import * as trl from '@testing-library/react'
      export * from './vitestDefaultConfig';
      export {vitest,rtl}
      //I alternatively tried exporting vitest and rtl directly without importing them, like:
      // export * as vitest from 'vitest', but that didn't work either
    vitestDefaulConfig.ts:
      import {defineConfig} from 'vitest/config';
      import react from '@vitejs/plugin-react';
      export const vitestDefaultConfig = () => {
         return defineConfig({...});
      }

rollup.config.mjs


import typescript from '@rollup/plugin-typescript';
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
import generatePackageJson from 'rollup-plugin-generate-package-json';
import dotenv from 'dotenv';
import glob from 'glob';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { readFileSync } from 'node:fs';
import copy from 'rollup-plugin-copy';

const ts = JSON.parse(readFileSync('tsconfig.json', { encoding: 'utf8' }));

const devMode = process.env.ENVIRONMENT === 'development';

const __dirname = path.resolve();
dotenv.config({ path: path.resolve(__dirname, './.env') });

const common = {
  input: 'src/index.ts',
  watch: {
    include: './src/**',
    clearScreen: false,
  },
  plugins: [
    typescript(),
    getBabelOutputPlugin({
      presets: ['@babel/preset-env'],
      allowAllFormats: true,
    }),
    terser({
      compress: {
        module: true,
        pure_funcs: ['console.log', 'console.info'],
        drop_debugger: true,
      },
    }),
    generatePackageJson({
      baseContents: (pkg) => ({
        ...pkg,
      }),
    }),
    copy({
      targets: [
        { src: 'README.md', dest: `${ts.compilerOptions.outDir}/` },
        { src: 'scripts', dest: `${ts.compilerOptions.outDir}/` },
      ],
      copyOnce: true,
    }),
  ],
};

const esmBundlePathLevel = {
  ...common,
  input: Object.fromEntries(
    glob
      .sync('src/**/*.{ts,tsx}')
      .filter((file) => !file.includes('typings/')) // Exclude the 'typings' directory
      .map((file) => [
        /* This removes `src/` as well as the file extension from each file
         * Ex: src/nested/foo.js becomes nested/foo
         */
        path.relative('src', file.slice(0, file.length - path.extname(file).length)),
        /* This expands the relative paths to absolute paths
         * Ex: src/nested/foo becomes ~/project/src/nested/foo.js
         */
        fileURLToPath(new URL(file, import.meta.url)),
      ])
  ),
  output: {
    dir: ts.compilerOptions.outDir,
    format: 'es',
    sourcemap: devMode,
  },
};
const esmBundle = {
  ...common,
  output: {
    file: `${ts.compilerOptions.outDir}/index.mjs`,
    format: 'es',
    sourcemap: devMode,
  },
};

const cjsBundle = {
  ...common,
  output: {
    file: `${ts.compilerOptions.outDir}/index.js`,
    format: 'cjs',
    sourcemap: devMode,
  },
};

export default [esmBundlePathLevel, cjsBundle, esmBundle];

tsconfig.json

{
  "compilerOptions": {
    "paths": {
      "@eslint/*": ["./src/eslint/*"],
      "@playwright/*": ["./src/playwright/*"]
    },
    "moduleResolution": "node",
    "target": "ES2017",
    "module": "ES2015",
    "strict": true,
    "sourceMap": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "typeRoots": ["node_modules/@types"],
    "jsx": "react-jsx"
  },
  "include": ["src", "test"]
}

package.json (Brief)

{
  "name": "web-config-utility",
  "version": "0.0.1",
  "description": "",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "module": "dist/index.mjs",
  "repository": {
    "type": "git",
    "url": "XYZ"
  },
  "scripts": {
    "prepare": "rm -rf .husky/_ && husky install",
    "postinstall": "node ./scripts/postinstall.js",
    "prebuild": "rimraf dist",
    "build": "npx rollup -c",
    "tsc": "tsc"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@testing-library/react": "^16.0.1",
    "@vitejs/plugin-react": "4.3.3",
    "vitest": "2.1.5"
  },
  "devDependencies": {
  ...
  },

  "optionalDependencies": {
    "@rollup/rollup-linux-x64-gnu": "4.21.2"
  },
}

Note: Ignore missing dependencies like @playwright or eslint

I'd firstly like to understand why is vitest complaining that it is executes outside of its context, and secondly what changes do I need to make to accomplish the desired result?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.