Vitest alias or inline.deps fail to resolve import error - vite

I am migrating some jest tests over to vitest and some of my tests are failing due to an import issue of an external package dependency in node_modules. Specifically: #package/dependency seems to be an ES Module but shipped in a CommonJS package.
vitest suggests this change to my config:
export default {
test: {
deps: {
inline: [
"#package"
]
}
}
}
Unfortunately, this fix does not work. Previously I resolved this issue with moduleNameMapper in jest where "#package/dependency": "#package/dependency/js" mapped to a valid import. I tried setting alias in both test.alias and resolve.alias, but neither works.
I am using Typescript in this project, and the rest of my test config looks like this:
test: {
globals: true,
environment: "jsdom",
setupFiles: "./src/setupTests.js",
}
// setupTests.js
import {configure} from 'enzyme/build';
import Adapter from 'enzyme-adapter-react-16/build';
configure({ adapter: new Adapter() });
What can I do to get around this? Thanks.

Related

rollup.js: crypto.getRandomValues() not supported

I am working on an Obsidian plugin that requires bundling using rollup.js. This plugin needs to import inrupt solid libraries that, when imported, are causing the following error:
Error: crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported
at rng (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:16740:10)
at v4 (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:17186:53)
at new Session (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:23526:88)
at Repro.<anonymous> (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:23669:17)
at step (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:160:15)
at Object.next (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:111:11)
at /Users/candide/work/sekund/solid-build-issues/main_rollup.js:83:65
at new Promise (<anonymous>)
at __awaiter (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:65:9)
at Repro.login (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:23664:10)
When debugging the code, it turns out that the crypto constant is not defined. However, at the start of the generated bundle, I can see:
var crypto_1 = require("crypto");
So it looks like my problem basically boils down to rollup redefining global variables when it should not.
Indeed, using the typescript compiler (tsc) on the same source file outputs a perfectly working program.
Here's my rollup config:
import commonjs from "#rollup/plugin-commonjs";
import json from "#rollup/plugin-json";
import { nodeResolve } from "#rollup/plugin-node-resolve";
import typescript from "#rollup/plugin-typescript";
const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
`;
export default {
input: "src/main.ts",
inlineDynamicImports: true,
output: [
{
file: "main.js",
sourcemap: "inline",
format: "cjs",
exports: "default",
banner,
},
],
external: ["obsidian", "fs", "os", "path"],
plugins: [json(), nodeResolve({ preferBuiltins: true }), commonjs(), typescript({ sourceMap: true })],
};
I created a repro repo at https://github.com/ckemmler/solid-build-issues
man this wrecked my brain for a bit, i managed to find a solution but i don't understand it 100%
please see the solution suggested in this comment https://github.com/uuidjs/uuid/issues/544#issuecomment-740394448
resolved the problem for me

jest.config.ts: "registerer.enabled is not a function" error when running jest from Github Actions

When running jest locally, it instantiates my app and runs tests without any issues.
When running jest inside github actions, I'm getting this error:
Error: Jest: Failed to parse the TypeScript config file /home/runner/work/myproject/myproject/jest.config.ts
TypeError: registerer.enabled is not a function
at readConfigFileAndSetRootDir (/home/runner/work/myproject/myproject/node_modules/#jest/core/node_modules/jest-config/build/readConfigFileAndSetRootDir.js:118:13)
the package.json script entry is just:"test": "jest"
and the jest.config.ts file is:
import tsJestUtils from 'ts-jest/utils'
import tsConf from './tsconfig.json'
const rootDir = __dirname
const { pathsToModuleNameMapper } = tsJestUtils
const {
compilerOptions: { paths },
} = tsConf
const config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: [`${rootDir}/src`],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
moduleNameMapper: pathsToModuleNameMapper(paths, {
prefix: `${rootDir}/src`,
}),
}
export default config
So I just bypassed use of typescript for my jest config entirely, and went with an equivalent jest.config.js file based on the docs. Works in Github Actions now, runner does not fail! \o/
I am still not sure what the issue was, but I think ts-node just wasn't processing the config file properly. I feel like the actual failure was with the attempt to load a .ts config file, specifically at this point in the source code when it tries to call registerer.enabled().
It can be fixed by upgrading to "ts-node": "^8.5.0"

Node.js: How to import test files in custom test runner

I'm trying to create my own custom testing framework for learning purpose. Test files are written in following way
import { somemethod } from './some/module'
test(/I click on a button)/, () => {
browser.get("someSelector").should("have.text",somemethod());
});
I user require(file) to load test files. But it throw error SyntaxError: Unexpected token {
for import statement in test file. I'm using node js version 11.15.
If I switch to node v13.14 and define "type": "module" in my package.json then it doesn't let me use require(file) to load a test file or any module in my package.
How can I import tests files considering the user may be importing the modules using import or require?
This answer is very empirical...
Considering that it works using canonical commonjs approach you can try to debug it with newer version of NODE (currently I would use 14). For it, I would suggest you to use a node version manager like NVM so you can switch between node version easily and test that accordling seeing differences between various node installations.
Make a minimal project with npm init with a single dependency, save your index with the .mjs extension and try an import the above dependency. If you are be able to import that dependency with that minimal environment you can blame either your previous node or your configuration or both of them.
At the moment you should only create a small 2 files project to reproduce the problem. It seems your current node does not consider the "type": "module" configuration and runs everything in its classic way.
Regarding your comments....
As far as I know import can be used even in your code, not just at the beginning:
(async () => {
if (somethingIsTrue) {
// import module for side effects
await import('/modules/my-module.js');
}
})();
from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Additionally you can try Webpack with a configuration like:
// webpack.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'production',
target: 'node',
externals: [nodeExternals()],
entry: {
'build/output': './src/index.js'
},
output: {
path: __dirname,
filename: '[name].bundle.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
'targets': {
'node': 'current'
}
}]
]
}
}
}]
}
};
With NodeExternals you don't put your node dependencies in the bundle but only your own code. You refer to node_modules for the rest. You might not want that.

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",

Loading a static file in Angular during build

I'm want to load the contents of a file and inject it as a string in TypeScript at build time. I understand that this code would ordinarily be server code, but what I want is to have a build step that reads the file and injects its contents as a string.
import { readFileSync } from 'fs';
import { Component } from '#angular/core';
#Component({
template: `<pre>${readFileSync('./example.code')}</pre>`
})
export class ExampleComponent { }
Assuming example.code just has "Hello World" I would want this file to be built as:
template: `<pre>"Hello World"</pre>`
I have found babel-plugin-static-fs which I think should allow me to do this, but I was originally using ng (angular-cli) to build the project. I have done ng eject and updated webpack:
module: {
rules: [
/* snip */
{
"test": /\.ts$/,
"use": [
{
loader: "babel-loader",
options: {
plugins: ['babel-plugin-static-fs']
}
},
{
"loader": "#ngtools/webpack"
}, ] } ] }
However, when I run webpack, I still get
Cannot find module 'fs'
If I reverse the order of the loaders, it seems like babael does not like the # used in may annotations such as the #Component above so that loader does not work.
Is there any way to load a file as static content during an Angular project build?
The issue here is actually related to the tsconfig.app.json file that Angular creates and uses for AoT. This is separate from the tsconfig.json used to actually build the project which does load #types/node as expected.
If you've created a project with ng new, you can change tsconfig.app.json:
- "types": [],
+ "types": ["node"],
This will have the AoT compiler use the type definitions from #types/node.

Resources