Mirage/Pretender causes errors in Vitest - vite

I'm working on migrating from Jest to Vitest (alongside CRA > Vite migration), and I think I've got everything working, except that using Mirage causes errors. Setting the vite config test environment between happy-dom and 'jsdom' both give different errors, though they appear to be related or similar or the same (just with happy-dom giving much more useful information!
My very simplified test:
import { describe, expect, it } from "vitest"
import { createServer } from "miragejs";
describe('tests', () => {
createServer({})
it('works', () => {
expect(true).toEqual(true)
})
})
happydom error
TypeError: Cannot read properties of undefined (reading 'prototype')
❯ interceptor node_modules/pretender/dist/pretender.js:1540:46
❯ new Pretender node_modules/pretender/dist/pretender.js:1638:32
❯ PretenderConfig._create node_modules/miragejs/dist/mirage-cjs.js:6398:14
❯ PretenderConfig.create node_modules/miragejs/dist/mirage-cjs.js:6259:27
❯ Server.config node_modules/miragejs/dist/mirage-cjs.js:6824:24
❯ new Server node_modules/miragejs/dist/mirage-cjs.js:6760:10
❯ Proxy.createServer node_modules/miragejs/dist/mirage-cjs.js:6725:10
❯ src/test.test.tsx:5:2
3|
4| describe('tests', () => {
5| createServer({})
| ^
6| it('works', () => {
7| expect(true).toEqual(true)
jsdom error
Error: Errors occurred while running tests. For more information, see serialized error.
❯ Object.runTests node_modules/vitest/dist/chunk-vite-node-externalize.6956d2d9.mjs:7048:17
❯ processTicksAndRejections node:internal/process/task_queues:96:5
❯ async file:/Users/jtuzman-superdraft/dev/superdraft-core-admin/NEW-vite-admin/node_modules/vitest/dist/chunk-vite-node-externalize.6956d2d9.mjs:10545:9
❯ Vitest.runFiles node_modules/vitest/dist/chunk-vite-node-externalize.6956d2d9.mjs:10558:12
❯ Vitest.start node_modules/vitest/dist/chunk-vite-node-externalize.6956d2d9.mjs:10479:5
❯ startVitest node_modules/vitest/dist/chunk-vite-node-externalize.6956d2d9.mjs:11204:5
❯ start node_modules/vitest/dist/cli.mjs:666:9
❯ CAC.run node_modules/vitest/dist/cli.mjs:662:3
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: {
"errors": [
[Error: Internal error: Error constructor is not present on the given global object.],
],
}
vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react'
import svgrPlugin from 'vite-plugin-svgr';
import macrosPlugin from "vite-plugin-babel-macros"
import checker from 'vite-plugin-checker'
// https://vitejs.dev/config/
export default defineConfig({
test: {
globals: true,
environment: "jsdom", // or "happy-dom"
},
define: {
global: {},
},
esbuild: {
logOverride: { 'this-is-undefined-in-esm': 'silent' }
},
plugins: [
react(),
svgrPlugin({
svgrOptions: {
icon: true,
},
}),
macrosPlugin(),
checker({
typescript: true,
overlay: {
panelStyle: 'height: 100vh; max-height: unset;'
}
})
],
});
This GitHub issue appears to deal with the same question but doesn't appear to solve it.

Ran into the same thing. It's the global: {} statement. When I commented it out in my vite.config.ts file, my tests ran successfully. I haven't figured out another way to solve the global error yet that caused me to set that in the first place though.

happy-dom does not provide an implementation for XMLHttpRequest, which is used by pretenderjs. The most straightforward walk around is to put the following line at the very top of your test code, before the the vitest environment:
this.XMLHttpRequest = vi.fn()
//#vitest-environment happy-dom

Related

Switching Storybook from Webpack to Vita in Gatsby app

I work on a Gatsby project and I'm hoping to run our Storybook with Vita instead of our existing Webpack setup. I'm clearly not doing it right.
I added the plugins:
"#storybook/builder-vite": "^0.4.2",
"#vitejs/plugin-react": "^3.1.0",
"vite": "^4.1.1",
I also added our aliases by importing my tsconfigand converting the paths to the right format.
Although most of my attempts to run it resulted in about 1000 instances of
Failed to resolve import "react/jsx-dev-runtime" from "react/jsx-dev-runtime". Does the file exist?
it's actually running now. And it booted up WAY faster than it used to.
The only issue appears to be that it's not reloading, not at all. I make a change in a component, or a change in a story, and there is zero output in the terminal running storybook.
Although I do notice that this run, although it looks like it's working in the browser, does still give only these two errors:
Failed to resolve dependency: react/jsx-runtime, present in 'optimizeDeps.include'
Failed to resolve dependency: react/jsx-dev-runtime, present in 'optimizeDeps.include'
How can I fix this? I'm so close!
I've tried...
const react = require('#vitejs/plugin-react');
//...
module.exports = {
// ...
async viteFinal(config) {
return mergeConfig(config, {
// is this where this goes?
plugins: [
react({
jsxRuntime: 'classic',
}),
],
resolve: { alias: aliasPathsVite },
},
})
},
}
Which does open Storybook in the browser, but it doesn't load, and the terminal gives endless instances of:
10:30:38 AM [vite] Internal server error: Transform failed with 2 errors:
Typography/Links.tsx:3:4: ERROR: The symbol "prevRefreshReg" has already been declared
Typography/Links.tsx:4:4: ERROR: The symbol "prevRefreshSig" has already been declared
Plugin: vite:esbuild
File: Typography/Links.tsx:1:42
The symbol "prevRefreshReg" has already been declared
1 | import RefreshRuntime from "/#react-refresh";let prevRefreshReg;let prevRefreshSig;if (import.meta.hot) { if (!window.__vite_plugin_react_preamble_installed__) { throw new Error( "#vitejs/plugin-react can't detect preamble. Something is wrong. " + "See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201" ); } prevRefreshReg = window.$RefreshReg$; prevRefreshSig = window.$RefreshSig$; window.$RefreshReg$ = (type, id) => { RefreshRuntime.register(type, "Typography/Links.tsx" + " " + id) }; window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;}var _jsxFileName = "Typography/Links.tsx";
2 | import RefreshRuntime from "/#react-refresh";
3 | let prevRefreshReg;
| ^
4 | let prevRefreshSig;
5 | if (import.meta.hot) {
The symbol "prevRefreshSig" has already been declared
2 | import RefreshRuntime from "/#react-refresh";
3 | let prevRefreshReg;
4 | let prevRefreshSig;
| ^
5 | if (import.meta.hot) {
6 | if (!window.__vite_plugin_react_preamble_installed__) {
at failureErrorWithLog (node_modules/esbuild/lib/main.js:1604:15)
at node_modules/esbuild/lib/main.js:837:29
at responseCallbacks.<computed> (node_modules/esbuild/lib/main.js:701:9)
at handleIncomingPacket (node_modules/esbuild/lib/main.js:756:9)
at Socket.readFromStdout (node_modules/esbuild/lib/main.js:677:7)
at Socket.emit (node:events:513:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Socket.Readable.push (node:internal/streams/readable:228:10)
at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)
I've tried...
module.exports = {
// ...
async viteFinal(config) {
return mergeConfig(config, {
resolve: {
alias: {
...aliasPathsVite,
'react/jsx-runtime': path.join(
__dirname,
'node-modules/react/jsx-runtime'
),
},
optimizeDeps: {
include: ['react/jsx-runtime']
}
},
})
},
}
which opens a non-working Storybook in the browser, and the terminal says this hundreds of times
Failed to resolve import "react/jsx-dev-runtime" from "react/jsx-dev-runtime". Does the file exist?
Then some of these:
[vite] error while updating dependencies:
Error: ENOENT: no such file or directory, rename 'node_modules/.vite-storybook/deps_temp' -> 'node_modules/.vite-storybook/deps'
at renameSync (node:fs:1030:3)
at Object.commit (file:///node_modules/vite/dist/node/chunks/dep-3007b26d.js:42874:19)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async commitProcessing (file:///node_modules/vite/dist/node/chunks/dep-3007b26d.js:42348:17)
at async runOptimizer (file:///node_modules/vite/dist/node/chunks/dep-3007b26d.js:42386:17)
And then a bunch of issues importing CSS files, like this one
10:45:29 AM [vite] Internal server error: Failed to resolve import "./header.css" from "node_modules/#storybook/mdx1-csf/dist/esm/stories/Header.js?v=ec48b265". Does the file exist?
Have you tried something like this?
resolve: {
alias: {
'react/jsx-runtime': 'react/jsx-runtime.js',
},
},
Source: https://github.com/vitejs/vite/issues/6215
Also:
optimizeDeps.include: ['react/jsx-runtime']
Another way can be tweaking the configuration of #vitejs/plugin-react:
import react from '#vitejs/plugin-react';
export default defineConfig({
plugins: [
react({
jsxRuntime: 'classic',
}),
]
});

Vite & Vite-plugin-html-purgeCSS: failed to load config, error during build

I'm using Vite as the build tool for a project and added the plugin "vite-plugin--html-purgecss" to use PurgeCSS. However on build I get the following error:
failed to load config from C:\Users\User Name\Documents\GitHub\project-template\vite.config.js
error during build:
TypeError: htmlPurge is not a function
at file:///C:/Users/User%20Name/Documents/GitHub/project-template/vite.config.js.timestamp-1663917972492.mjs:6:5
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:533:24)
at async loadConfigFromBundledFile (file:///C:/Users/User%20Name/Documents/GitHub/project-template/node_modules/vite/dist/node/chunks/dep-cff57044.js:63470:21)
at async loadConfigFromFile (file:///C:/Users/User%20Name/Documents/GitHub/project-template/node_modules/vite/dist/node/chunks/dep-cff57044.js:63356:28)
at async resolveConfig (file:///C:/Users/User%20Name/Documents/GitHub/project-template/node_modules/vite/dist/node/chunks/dep-cff57044.js:62973:28)
at async doBuild (file:///C:/Users/User%20Name/Documents/GitHub/project-template/node_modules/vite/dist/node/chunks/dep-cff57044.js:45640:20)
at async build (file:///C:/Users/User%20Name/Documents/GitHub/project-template/node_modules/vite/dist/node/chunks/dep-cff57044.js:45629:16)
at async CAC.<anonymous> (file:///C:/Users/User%20Name/Documents/GitHub/project-template/node_modules/vite/dist/node/cli.js:748:9)
Vite.config.js is defined at the root of the project, and am running node 16.17.0. The template project isn't running any frameworks.
I've tried two config files:
import { defineConfig } from 'vite'
import htmlPurge from 'vite-plugin-html-purgecss'
export default defineConfig({
plugins: [
htmlPurge()
]
})
and
import htmlPurge from 'vite-plugin-html-purgecss'
export default {
plugins: [
htmlPurge()
]
}
I had the same issue. I think it's a compatibility issue or an update that no longer supports that plugin. Try running the following:
npm install vite-plugin-purgecss -D
vite.config.js file:
import { defineConfig } from "vite";
import htmlPurge from 'vite-plugin-purgecss';
export default defineConfig({
plugins: [
htmlPurge([htmlPurge()]),
],
});
Let me know if that works for you.

Vite with Jest: cannot find module start with alias '#'

I'm using Jest in Vite. It works until I import a module from node_module.
import { defineComponent } from 'vue'
import { useCookies } from '#vueuse/integrations/useCookies'
I got this error.
FAIL src/components/MyComponent/index.test.ts
● Test suite failed to run
Cannot find module '#vueuse/integrations/useCookies' from 'src/components/MyComponent/index.vue'
Require stack:
src/components/MyComponent/index.vue
src/components/MyComponent/index.test.ts
16 | <script lang="ts">
17 | import { defineComponent } from 'vue'
> 18 | import { useCookies } from '#vueuse/integrations/useCookies'
| ^
19 |
20 | export default defineComponent({
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
I guess somehow Jest cannot resolve the module starts with '#'. Maybe I should write a moduleNameMapper? I also tried to install vite-jest, but somehow my app just crash, maybe I mess up something.
Anyway, thanks for your time, and if you need more information like my jest.config.js or vite.config.ts, please let me know.
Thank you.
Use moduleNameMapper in your jest.config.js file like following:
module.exports = {
//...
moduleNameMapper: {
"^#/(.*)$": "<rootDir>/src/$1",
},
};
Also, if you are using TypeScript, you should add the following to your tsconfig.json file as well:
{
"compilerOptions": {
"paths": {
"#/*": ["./src"]
}
}
}

Cannot test jest with monaco editor - unexpected token

Running jest on the application fails with:
Details:
/home/**/node_modules/monaco-editor/esm/vs/editor/editor.api.js:5
import { EDITOR_DEFAULTS } from './common/config/editorOptions.js';
^
SyntaxError: Unexpected token {
> 1 | import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
| ^
2 |
3 | /**
4 | * Get create function for the editor.
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (src/utils/editor-actions.js:1:1)
Application has installed packages for jest and babel-jest.
Babel config:
const presets = [
[
"#babel/env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
},
useBuiltIns: "usage",
corejs: 3,
}
],
"#babel/preset-react"
];
const plugins = [
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-class-properties",
"babel-plugin-styled-components"
];
module.exports = { presets, plugins };
The import statement as suggested in the docs for lazy loading modules from monaco leads to the esm folder, which jest is not familiar with.
import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
By default, babel-jest would not transform node_modules and hence anything referencing the monaco-editor would error out. A possible solution is to include monaco-editor package into the compilation step by transformIgnorePatterns as mentioned in the docs
Add these to the jest config:
{
"transformIgnorePatterns": [
"node_modules\/(?!(monaco-editor)\/)"
]
}
PS: If you are using jest-dom, it might start complaining on not implmenting certain features from monaco-editor, you can mock it out with:
jest.mock("monaco-editor/esm/vs/editor/editor.api.js");
The only workaround that helped me in that issue (from here):
In folder __mocks__ create file react-monaco-editor.js with content:
import * as React from 'react';
export default function MonacoEditor() {
return <div />;
}
I have the same issue with Jest and Monaco and to make the tests pass I had to:
Add a moduleNameMapper for monaco-editor: #133 (comment)
Configure a setupTests.js like explained here: stackOverflow
I'm using:
"jest": "^24.9.0"
"babel-jest": "24.9",
"monaco-editor": "^0.20.0"
"react-monaco-editor": "0.33.0",
"monaco-editor-webpack-plugin": "^1.8.2",

Nest.js Type 'DynamicModule' is not assignable to type 'ForwardReference' on nest-modules/mailer

I have an Nest.js application. I wanted to add MailerModule to my app using following link -> https://npm.taobao.org/package/#nest-modules/mailer
However, I just did the following steps:
First, npm install --save #nest-modules/mailer
Second I add app module mail config but it is giving an error here is my app.module.ts:
import { Module } from '#nestjs/common';
import { HandlebarsAdapter, MailerModule } from '#nest-modules/mailer';
#Module({
imports: [
MailerModule.forRootAsync({
useFactory: () => ({
transport: 'smtps://user#domain.com:pass#smtp.domain.com',
defaults: {
from:'"nest-modules" <modules#nestjs.com>',
},
template: {
dir: __dirname + '/templates',
adapter: new HandlebarsAdapter(), // or new PugAdapter()
options: {
strict: true,
},
},
}),
}),],
})
export class ApplicationModule {}
Now I can't compile because it is saying that :
TS2345: Argument of type '{ imports: DynamicModule[]; }' is not assignable to parameter of type 'ModuleMetadata'.   Types of property 'imports' are incompatible.     Type 'DynamicModule[]' is not assignable to type '(Type | DynamicModule | Promise | ForwardReference)[]'.       Type 'DynamicModule' is not assignable to type 'Type | DynamicModule | Promise | ForwardReference'.         Type 'DynamicModule' is not assignable to type 'ForwardReference'.           Property 'forwardRef' is missing in type 'DynamicModule'.
Perhaps check what version of nest you're using, this issue may be resolved in versions of nestjs 6+:
https://github.com/nestjs/nest/issues/669
I had a similar problem. I started to make a new project based on the old one. After installing the modules, this error appeared. The problem lay in private modules. They did not install without package-lock.json.

Resources