Error when I try to test with NestJS, Jest and GraphQLFederationModule - jestjs

When I try to test with this module it gives me the following error:
FAIL test/test.e2e-spec.ts (28.561s)
AppController (e2e)
× test (4555ms)
● AppController (e2e) › test
Configuration error:
Could not locate module ./src/index-minimal mapped as:
C:\absolute\path\server\company\src\$1.
Please check your configuration for these entries:
{
"moduleNameMapper": {
"/src\/(.*)/": "C:\absolute\path\server\company\src\$1"
},
"resolver": undefined
}
at createNoMappedModuleFoundError (../node_modules/jest-resolve/build/index.js:545:17)
at Object.<anonymous> (../node_modules/#apollo/protobufjs/minimal.js:4:18)
The jest config file is:
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"testEnvironment": "node",
"moduleDirectories": ["node_modules", "src"],
"moduleNameMapper": {
"src/(.*)": "<rootDir>/../src/$1"
}
}
The app.module file:
#Module({
imports: [
...,
GraphQLFederationModule.forRootAsync({
imports: [CustomConfigModule],
inject: [EnvironmentStateService],
useFactory: (environmentStateService: EnvironmentStateService) => ({
introspection: environmentStateService.isDev,
debug: environmentStateService.isDev,
playground: environmentStateService.isDev,
autoSchemaFile: true,
tracing: environmentStateService.isDev,
}),
}),
...,
],
})
export class AppModule {}
When I try the following settings in app.module it works correctly:
#Module({
imports: [
...,
GraphQLModule.forRootAsync({
imports: [CustomConfigModule],
inject: [EnvironmentStateService],
useFactory: (environmentStateService: EnvironmentStateService) => ({
introspection: environmentStateService.isDev,
debug: environmentStateService.isDev,
playground: environmentStateService.isDev,
autoSchemaFile: true,
tracing: environmentStateService.isDev,
}),
}),
...,
],
})
export class AppModule {}
I have been reviewing the file where it gives me the error and I find the following protobufjs code in node_modules (minimal.js):
// minimal library entry point.
"use strict";
module.exports = require("./src/index-minimal");
Does anyone know what may be happening? Thank you!

I have changed my paths in the form: "src/folder/..." to "#App/folder/..." and in the end it works fine, but I'm left curious why this happens and if there is any solution To this, I will be attentive to possible solutions and recommendations, thank you very much!
In case someone wants to see the solution, it is as follows:
The tsconfig.json:
{
"compilerOptions": {
...
"baseUrl": "./",
"paths": {
"#App/*": ["src/*"]
},
...
},
...
}
The jest config file:
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"testEnvironment": "node",
"moduleNameMapper": {
"^#App/(.*)$": "<rootDir>/../src/$1"
}
}
Regards!

I ran into the same problem, my jest-e2e.json file was also similar
"moduleNameMapper": {
"src/(.*)": "<rootDir>/../src/$1"
}
The error Could not locate module ./src/index-minimal mapped as: ... occurred because the minimal.js file in protobufjs tries to import ./src/index-minimal but our Jest runner remaps the file path name to <rootDir>/../src/$1 so protobufjs threw an error because it cannot find the ./src/index-minimal.js file.
The solution is to leave src/index-minimal alone, so we don't remap its name. I added the following line to the moduleNameMapper field in jest-e2e.json and it solved the issue
"moduleNameMapper": {
"src/index-minimal": "./src/index-minimal",
"src/(.*)": "<rootDir>/../src/$1"
}
Just note not to create a file named index-minimal in your src folder because Jest will fail to map the filename properly.

Related

Module #adobe/leonardo-contrast-colors: How to use it. Failing on import

I'm setting app a new TypeScript/React Project using the following module https://www.npmjs.com/package/#adobe/leonardo-contrast-colors
Using node v16.17.0.
To start with I replicate the example in the README.md but the import doesn't work. Doing the following:
import { Theme, Color, BackgroundColor } from '#adobe/leonardo-contrast-colors';
returns:
Module '"#adobe/leonardo-contrast-colors"' has no exported member 'Theme'.
Module '"#adobe/leonardo-contrast-colors"' has no exported member 'Color'.
Module '"#adobe/leonardo-contrast-colors"' has no exported member 'BackgroundColor'.
Apparently '#adobe/leonardo-contrast-colors' leads to index.d.ts
and if I try to import the members like this:
import { Color } from "#adobe/leonardo-contrast-colors/color.mjs";
neither it works as I get:
Package path ./color.mjs is not exported from package /Users/.../package.json)
I see this open issue in the package repo: https://github.com/adobe/leonardo/issues/173
but backing to 1.0.0-alpha.13 turns out the same for me.
This is my tsconfig
{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"target": "ES2015",
"jsx": "react",
"typeRoots": ["./node_modules/#types"],
"module": "ESNext",
"moduleResolution": "Node",
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
And webpack.config.js:
module.exports = (env, argv) => ({
...
module: {
rules: [
// Converts TypeScript code to JavaScript
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
...
],
},
resolve: { extensions: [".tsx", ".ts", ".jsx", ".js"] },
...
});
Is this a problem with the package or my project cofiguration?
Thanks in advance

TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'esnext', or 'system'

When Jest.js encounters import.meta in the code, I get an error:
FAIL testFile.test.ts
● Test suite failed to run
testFile.ts:40:10 - error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'esnext', or 'system'.
40 return import.meta?.env as EnvironmentalVariablesType
I have installed the following babel related packages:
// package.json
"devDependencies": {
"#babel/core": "^7.16.5",
"#babel/preset-env": "^7.16.5",
"#babel/preset-typescript": "^7.16.5",
"#vitejs/plugin-react-refresh": "1.3.6",
"babel-jest": "^27.4.5",
"jest": "27.3.1",
"jest-environment-jsdom-global": "3.0.0",
"react": "17.0.1",
"ts-jest": "27.0.7",
"typescript": "4.1.3",
"vite": "2.6.14"
"dependencies": {
"babel-plugin-transform-vite-meta-env": "^1.0.3",
"babel-preset-vite": "^1.0.4",
I've setup babel.config.js as follows:
module.exports = {
plugins: [ 'babel-plugin-transform-vite-meta-env' ],
presets: [
[
'#babel/preset-env',
{ targets: { node: 'current' } },
],
[ '#babel/preset-typescript' ],
[ 'babel-preset-vite' ],
],
}
and my vite.config.js:
import { defineConfig } from 'vite'
import reactRefresh from '#vitejs/plugin-react-refresh'
import replace from '#rollup/plugin-replace'
// https://vitejs.dev/config/
export default defineConfig( {
base: '/time/',
server: {
port: 9000,
},
plugins: [
reactRefresh(),
replace( {
'process.env.NODE_ENV': JSON.stringify( 'development' ),
'process.env.SHOW_DEV_TOOLS': JSON.stringify( 'true' ),
} ),
],
} )
Tried
set module in tsconfig.json to es2020, esnext, or system
None of these cleared or changed the terminal error.
Is there some misconfiguration above that is preventing Jest from properly running babel?
In tsconfig.json, try setting the compilerOptions as so:
{
"compilerOptions": {
"module": "es2022",
"moduleResolution": "Node"
},
...
}
Install vite-plugin-environment plugin (https://www.npmjs.com/package/vite-plugin-environment)
Create .env file in your project root folder near package.json
provide your env variables in .env files
change all your import.meta.env.YOUR_VAR to process.env.YOUR_VAR
open vite.config.ts and list the vite-plugin-environment:
import EnvironmentPlugin from 'vite-plugin-environment';
...
plugins: [
react(),
...
EnvironmentPlugin('all')
]
Jest will understand process.env.YOUR_VAR, so if you change all your import.meta.env.YOUR_VAR to process.env.YOUR_VAR your test will pass without import.meta.env error
This article helped me for setting up Jest in my Vite project.
You can use the following command to run the test as per the jest documentation along with setting allowSyntheticDefaultImports to "true" in ts config file, these two changes solved the error for me.
yarn NODE_OPTIONS=--experimental-vm-modules npx jest
or
npm NODE_OPTIONS=--experimental-vm-modules npx jest
Ensure you have the relevant modules installed as per this. This article, have proper ts, jest and babel config added. (I have shared my config files for anyone who comes across this error. This article came in pretty handy to know about initial set-up requirements.)
//tsconfig.json
{
"compilerOptions": {
"target": "ES2020", /* Specify ECMAScript target version: '' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "ES2020", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"allowJs": true, /* Allow javascript files to be compiled. */
"allowSyntheticDefaultImports": true,
"strict": true, /* Enable all strict type-checking options. */
/* Module Resolution Options */
"moduleResolution": "Node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"baseUrl": "src", /* Base directory to resolve non-absolute module names. */
"types": [
"jest"
], /* Type declaration files to be included in compilation. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
},
"include": [
"src/**/*.ts",
"./src/**/*.js"
],
"exclude": [
"node_modules"
],
}
//babel.config.js
export default api => {
const isTest = api.env('test');
// You can use isTest to determine what presets and plugins to use.
return {
presets: [
[
'#babel/preset-env',
'#babel/preset-typescript',
{
'targets': {
'node': 'current',
},
},
]
],
};
};
//jest.config.js
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
export default {
preset: 'ts-jest',
testEnvironment: 'node',
testTimeout: 20000, //to resolve timeout error
roots: ['src'],
modulePaths: ['node_modules', '<rootDir>/src'],
testPathIgnorePatterns: [
'<rootDir>/node_modules/', "/__utils"
],
moduleDirectories: [
"src"
],
transform: {
"^.+\\.js?$": "babel-jest",
"^.+\\.ts?$": "ts-jest"
},
transformIgnorePatterns: [""], // you can add any module that you do not want to transform, The first pattern will match (and therefore not transform) files inside /node_modules.
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|tsx?)$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
testEnvironment: "node",
"moduleNameMapper": {
"src/(.*)": "<rootDir>/src/$1"
},
globals: {
"ts-jest": {
"useESM": true
}
},
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
}
};
I switched from jest to vitest, which got rid of this error.
No changes to the test code were necessary.
For reference, this is my vitest.config.js:
import { defineConfig } from 'vite';
export default defineConfig({
test: {
globals: true,
environment: 'jsdom'
}
});

Building es6 module in typescript project with webpack

I am trying to use imagemin node package in my project. It is a es6 module and I am getting error while using it.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module. with "type" as "module" in package.json
ReferenceError: require is not defined with "type" as "commonjs" in package.json
My webpack config:
export default env => {
return {
mode: env.production ? 'production' : 'development',
entry: {
main: './src/main.ts',
worker: './src/worker.ts'
},
target: ['node', 'es2019'],
devtool: env.production ? false : 'inline-source-map',
watch: !env.production,
resolve: {
extensions: ['.ts', '.js'],
alias: {
src: _resolve(process.cwd(), './src')
}
},
module: {
rules: [{
test: /\.ts$/,
include: _resolve(process.cwd(), "src"),
use: 'ts-loader',
exclude: [/node_modules/, /\.spec\.ts/, /\.e2e-spec\.ts/]
}],
},
externalsPresets: { node: true },
externals: [nodeExternals()],
output: {
filename: '[name].js',
path: OUTPUT_DIR,
clean: !!env.production,
devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]',
library: {
type: 'module'
}
},
optimization: {
minimize: false, //!!env.production
mangleExports: true,
minimizer: [new terserPlugin({
terserOptions: {
output: {
comments: false
},
keep_classnames: true,
},
extractComments: false,
})]
},
experiments: {
outputModule: true
}
};
};
My tsconfig:
{
"compilerOptions": {
"module": "ES2020",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2019",
"sourceMap": true,
"strict": true,
"baseUrl": ".",
"esModuleInterop": true,
"noImplicitAny": true,
"moduleResolution": "node",
"outDir": "../bin/server",
"typeRoots": [
"node_module/#types",
"./typings"
],
"types": [
"node",
"#types/jest"
]
},
"exclude": [
"node_modules"
]
}
When I try to "import" imagemin in one of my .ts file, webpack convert it to "require". I have also tried using import() but it doesn't work either.
I have made a repo on github
Is there a way to get es6 bundle (preferred) or use imagemin with commonjs bundle?
I couldn't found a way to bundle es6 format through webpack but i was able to use es6 module in commonjs system while bundling through webpack.
externals: [
nodeExternals({
allowlist: ['imagemin', 'imagemin-mozjpeg']
}),
async function ({ request }) {
if (request === 'imagemin' || request === 'imagemin-mozjpeg')
return `import ${request}`;
},
]
This is how i got imagemin to work.
Change your start script
"start": "node --experimental-modules src/index.mjs "
and In package.json Add
{
...
"type": "module",
...
}

SyntaxError: Cannot use import statement outside a module webpack-typescript

Here is webpack.config.ts
// const path = require("path");
import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import CopyWebpackPlugin from "copy-webpack-plugin";
import webpack from "webpack";
import WebpackDevServer from "webpack-dev-server";
declare module "webpack" {
interface Configuration {
devServer?: WebpackDevServer.Configuration;
}
}
const config: webpack.Configuration = {
mode: "development",
target: "web",
entry: ["regenerator-runtime/runtime", "./src/index.tsx"],
output: {
filename: "bundle.js",
path: path.join(__dirname, "build"),
publicPath: "/",
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".css"],
alias: {
// add as many aliases as you like!
components: path.resolve(__dirname, "src/components"),
},
fallback: {
// path: require.resolve("path-browserify"),
fs: false,
assert: require.resolve("assert/"),
os: require.resolve("os-browserify/browser"),
constants: require.resolve("constants-browserify"),
},
},
devtool: "eval-cheap-source-map",
module: {
rules: [
{ test: /\.(ts|tsx)/, loader: "babel-loader", exclude: /node_modules/ },
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
{
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[contenthash].[ext]",
outputPath: "fonts/",
},
},
],
},
{
test: /\.svg$/,
use: [
{
loader: "svg-url-loader",
options: {
limit: 10000,
},
},
],
},
],
},
devServer: {
contentBase: path.join(__dirname, "build"),
historyApiFallback: true,
overlay: true,
},
plugins: [
new HtmlWebpackPlugin({
title: "esBUild",
template: "src/index.html",
}),
new CopyWebpackPlugin({
patterns: [{ from: "assets", to: "assets" }],
}),
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
React: "react",
}),
],
};
export default config;
here is tsconfig.json:
{
"compilerOptions": {
// The standard typing to be included in the type checking process.
"lib": ["dom", "dom.iterable", "esnext"],
// Whether to allow JavaScript files to be compiled.
"allowJs": true,
//This allows default imports from modules with no default export in the type checking process.
"allowSyntheticDefaultImports": true,
// Whether to skip type checking of all the type declaration files (*.d.ts).
"skipLibCheck": true,
// This enables compatibility with Babel.
"esModuleInterop": true,
"strict": true,
// Ensures that the casing of referenced file names is consistent during the type checking process.
"forceConsistentCasingInFileNames": true,
// This allows modules to be in .json files which are useful for configuration files.
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"module": "es6",
"target": "es5",
"sourceMap": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "src",
"paths": {
"components": ["components/*"]
}
},
"include": ["src"]
}
THis is the error I get :
import path from "path";
^^^^^^
SyntaxError: Cannot use import statement outside a module
I googled it and see some people suggest adding "type":"module", it did not work.
in tsconfig.json
"module": "es6" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
I tried each option but this did not work neither.
If I discard the typescript configuration, set up webpack with common.js, it works
Also .babelrc
{
"presets": [
"#babel/preset-react",
"#babel/preset-env",
"#babel/preset-typescript"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread"
]
}
In my case I have to change to "module": "commonjs", inside tsconfig.json. Refer https://www.typescriptlang.org/tsconfig#module
In my case I have to install typescript types of plugins (vscode suggested it after restart the ide).
For example:
For dotenv-webpack package, I installed #types/dotenv-webpack.
Please refer to this section of the Webpack configuration documentation:
The above sample assumes version >= 2.7 or newer of TypeScript is used with the new esModuleInterop and allowSyntheticDefaultImports compiler options in your tsconfig.json file.
Note that you'll also need to check your tsconfig.json file. If the module in compilerOptions in tsconfig.json is commonjs, the setting is complete, else webpack will fail with an error. This occurs because ts-node does not support any module syntax other than commonjs.
There are three solutions to this issue:
Modify tsconfig.json.
Modify tsconfig.json and add settings for ts-node.
Install tsconfig-paths.
You've set the correct values for "esModuleInterop" and "allowSyntheticDefaultImports" in your tsconfig.json, so, to get rid of the error, you should do one of the above three options.
The first one suggests you to change the "module" compiler option's value to "commonjs".
The second one allows you to keep the "module" option's value as is, but you should add the settings for ts-node in your tsconfig.json.
The third one requires additional package installation and a separate TS configuration file.

angular4 server side rendering issue

I am trying to add server-side rendering to my angular 4 (4.0.3) app using the universal, already integrated to platform-server.
I used this project as an example:
https://github.com/FrozenPandaz/ng-universal-demo
and also I was following this guide:
https://www.softwarearchitekt.at/post/2017/03/07/server-side-rendering-with-angular-4.aspx
My app.server.module, which is in app/server folder:
import {AppModule} from "../app.module";
import {ServerModule} from "#angular/platform-server";
import {NgModule} from "#angular/core";
import {AppComponent} from "../app.component";
import {BrowserModule} from "#angular/platform-browser";
import {APP_BASE_HREF} from '#angular/common';
import {routing} from "../app.routes";
#NgModule({
bootstrap: [AppComponent],
imports: [
BrowserModule.withServerTransition({
appId: 'kassir'
}),
ServerModule,
AppModule,
routing
],
providers: [
{provide: APP_BASE_HREF, useValue: "/site/"}
]
}
)
export class ServerAppModule {
}
tsconfig.server.json:
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"noEmit": true,
"noEmitHelpers": true,
"importHelpers": true,
"strictNullChecks": false,
"lib": [
"es2015",
"dom"
],
"typeRoots": [
"node_modules/#types"
],
"types": [
"hammerjs",
"node"
]
},
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"angularCompilerOptions": {
"entryModule": "./app/server/app.server.module#ServerAppModule"
},
"exclude": [
"node_modules",
"dist",
"src/**/*.spec.ts",
"src/**/*.e2e.ts",
"../src/main.browser.aot.ts"
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
webpack config for server, which is merged then to the common config:
const ngtools = require('#ngtools/webpack');
const path = require('path');
const ngcWebpack = require('ngc-webpack');
const helpers = require('./helpers');
module.exports = function(env){
return {
entry:{
"main": helpers.root('./src/main.server.ts')
},
output: {
path: path.join(process.cwd(), "dist/server"),
filename: "[name].server.bundle.js",
//chunkFilename: "[id].server.chunk.js"
},
node: {
fs: 'empty'
},
plugins: [
new ngtools.AotPlugin({
"entryModule": helpers.root('/src/app/server/app.server.module.ts#ServerAppModule'),
"exclude": [],
"tsConfigPath": helpers.root("./tsconfig.server.json"),
"skipCodeGeneration": true
}),
],
target: 'node',
module: {
rules: [
{
test: /\.ts$/,
loaders: ['#ngtools/webpack', 'angular2-template-loader']
},
]
}
}
};
Everything builds ok, main.server.bundle.js gets generated but when i start it
nodemon dist/server/main.server.bundle.js
i get a clean exit even with an empty server:
import * as express from 'express';
var server = express();
server.listen(8080, function (err) {
if (err) {
console.log(err);
} else {
console.log("server started at port 8080");
}
});
It supposed to fire either success log message or error but I can't see none of them. I also tried to launch it with node command with no success.
Would appreciate any help regarding this issue.
P.S. I've seen plenty of examples with universal, all them are using aot for server-side and then import in server.ts like that:
import { AppServerModuleNgFactory } from './aot/src/app/app.server.module.ngfactory';
Is there any way to not generate it?

Resources