babel-plugin-module-resolver not working on .jsx files - reactjs

I am working on a Typescript + SSR + ReactJs application. I am struggling to making this project works. The project actually works if I use relative paths, however I would like to use alias, and here is when the problems come. I also was able to make my project work by using tsconfig-paths/register but the problem is that it takes about 25 seconds to compile the project. The module-resolver is able to resolve paths on .ts files but when it comes to render the first Component (.jsx) it shows me the Cannot find module 'app/components/Page/Page' error.
This are my config files:
package.json
{
"name": "teachme-frontend",
"version": "1.0.0",
"description": "This project contains the frontend of Teach Me application",
"main": "index.ts",
"scripts": {
"build": "webpack --mode=development --config webpack.config.js",
"watch": "webpack --mode=development --config webpack.config.js --watch",
"start-dev": "NODE_ENV=development nodemon --ext ts,tsx,js index.ts",
"start": "NODE_ENV=production ts-node index.ts",
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint .",
"lint:fix": "eslint --fix ."
},
"repository": {
"type": "git",
"url": "git+https://github.com/vreviglio/teachme-frontend.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/vreviglio/teachme-frontend/issues"
},
"homepage": "https://github.com/vreviglio/teachme-frontend#readme",
"dependencies": {
"#babel/register": "^7.17.7",
"#emotion/react": "^11.8.2",
"#emotion/server": "^11.4.0",
"#emotion/styled": "^11.8.1",
"#mui/icons-material": "^5.5.1",
"#mui/material": "^5.5.1",
"#types/react-dom": "^17.0.14",
"eslint-config-airbnb-typescript": "^16.1.4",
"express": "^4.17.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.2",
"ts-loader": "^9.2.8",
"ts-node": "^10.7.0"
},
"devDependencies": {
"#babel/core": "^7.17.7",
"#babel/eslint-parser": "^7.17.0",
"#babel/preset-env": "^7.16.11",
"#babel/preset-flow": "^7.16.7",
"#babel/preset-react": "^7.16.7",
"#babel/preset-typescript": "^7.16.7",
"#swc/core": "^1.2.159",
"#swc/helpers": "^0.3.8",
"#types/express": "^4.17.13",
"#types/react": "^17.0.41",
"#typescript-eslint/eslint-plugin": "^5.16.0",
"#typescript-eslint/parser": "^5.16.0",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.3",
"babel-plugin-module-resolver": "^4.1.0",
"buffer": "^6.0.3",
"eslint": "^8.11.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-standard-jsx": "^10.0.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.3.0",
"html-loader": "^3.1.0",
"nodemon": "^2.0.15",
"stream-browserify": "^3.0.0",
"ts-node-dev": "^1.1.8",
"tsconfig-paths": "^3.14.0",
"typescript": "^4.6.2",
"typescript-transform-paths": "^3.3.1",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2"
}
}
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"target": "esnext",
"module": "commonjs",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"jsx": "react",
"moduleResolution": "nodenext",
"importHelpers": true,
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"resolveJsonModule": true,
"paths": {
"*": ["./*"],
"app": [
"./app/*"
]
},
},
"include": ["./app/**/*"],
"exclude": [
"node_modules",
"jest",
"app/client/**/*",
"public",
".eslintrc.js",
"babel.config.js",
"webpack.config.js"
]
}
babel.config.js
module.exports = {
presets: [
['#babel/preset-env', { targets: { node: 'current' } }],
['#babel/preset-react', { runtime: 'automatic' }],
'#babel/preset-typescript',
],
plugins: [
[
'module-resolver',
{
root: ['.'],
alias: {
app: "./app"
}
},
],
]
}
Example of file that resolves paths correctly - router/index.ts
import express from 'express';
import HomeRoute from 'app/pages/home/index';
const router = express.Router();
// Routes to the pages are declared
router.use('/home', HomeRoute);
export default router;
Example of file that throws error - pages/home/views/HomePage.tsx
import React from 'react';
import Page from 'app/components/Page/Page';
const styles = {
title: {
color: 'blue',
},
};
function HomePage() {
return (
<Page name="home">
<h1 style={styles.title}>
Hello world
</h1>
</Page>
);
}
export default HomePage;
P.S. I have already try to add the extensions key in the module_resolver options including [".ts", ".tsx"]

Try update your tsconfig.json to :
"baseUrl": ["."],
"paths": {
"*": ["."],
"#app": ["app/*"]
},
And your babel.config.js
module.exports = {
presets: [
['#babel/preset-env', { targets: { node: 'current' } }],
['#babel/preset-react', { runtime: 'automatic' }],
'#babel/preset-typescript',
],
plugins: [
[
'module-resolver',
{
root: ['.'],
extension: {
'.js',
'.ts',
'.tsx',
},
alias: {
'#app': "./app",
}
},
],
]
}
Now update your import with #

Related

Add local fonts to my react typescript package

I have created an npm package in react js typescript and I'm trying to add local fonts to the package but I keep getting "Cannot find module" error.
my package.json:
{
"name": "question",
"version": "1.0.41",
"description": "description",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"scripts": {
"build": "npm run build:esm && npm run build:cjs",
"build:esm": "tsc",
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\"",
"prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\"",
"test": "jest --config jestconfig.json",
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run prettier && npm run lint"
},
"repository": {
"type": "git",
"url": "*****************************************************************"
},
"author": "author.",
"license": "ISC",
"bugs": {
"url": "*****************************************************************"
},
"homepage": "*****************************************************************",
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^6.2.1",
"#fortawesome/free-solid-svg-icons": "^6.2.1",
"#fortawesome/react-fontawesome": "^0.2.0",
"#types/react": "^18.0.26",
"#typescript-eslint/eslint-plugin": "^5.48.2",
"#typescript-eslint/parser": "^5.48.2",
"axios": "^1.2.2",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.1",
"eslint-plugin-react-hooks": "^4.6.0",
"mobx": "^6.7.0",
"prettier": "^2.8.3",
"react": ">=16",
"react-dom": "^18.2.0",
"react-loading": "^2.0.3",
"reactjs-popup": "^2.0.5",
"styled-components": "^5.3.6",
"typescript": "^4.9.4"
},
"devDependencies": {
"#testing-library/react": "^13.4.0",
"#types/jest": "^29.2.6",
"#types/styled-components": "^5.1.26",
"jest": "^29.3.1",
"jest-canvas-mock": "^2.4.0",
"jest-environment-jsdom": "^29.3.1",
"ts-jest": "^29.0.5",
"typescript-plugin-css-modules": "^4.1.1"
},
"peerDependencies": {
"react": ">=16"
},
"files": [
"dist",
"LICENSE",
"README.md"
]
}
tsconfig.json:
{
"include": ["src", "src/types/*"],
"exclude": [
"dist",
"node_modules"
],
"compilerOptions": {
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
"declaration": true,
"sourceMap": false,
"rootDir": "./src",
"outDir": "./dist/esm",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"moduleResolution": "node",
"allowJs": true,
"jsx": "react",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"plugins": [{ "name": "typescript-plugin-css-modules" }],
"typeRoots" : ["node_modules/#types", "src/types"],
}
}
fonts.tsx file:
import { createGlobalStyle } from 'styled-components'
import Poppins_400 from '/src/assets/fonts/Poppins-Regular.ttf'
const FontStyles = createGlobalStyle`
#font-face {
font-family: "Poppins_400";
src: local("Poppins_400"),
url(${Poppins_400}) format("truetype");
font-weight: 400;
}
`
export default FontStyles
App.tsx file:
import React from 'react'
import { Container, Body } from './styles'
import FontStyles from '../assets/fonts/fonts'
const App = () => {
return (
<Container>
<FontStyles />
<Body />
</Container>
)
}
export default App
I've tried adding fonts.d.ts file with "declare module '*.tff'" but the error persist
The full message is: Cannot find module '/src/assets/fonts/Poppins-Regular.ttf' from 'src/assets/fonts/fonts.tsx'
Would much appreciate any help in order to add the fonts to my package.
Thanks!
import Poppins_400 from '/src/assets/fonts/Poppins-Regular.ttf'
url(${Poppins_400}) format("truetype");
You're importing the .ttf file as though it's a module, but the Styled Components 'createGlobalStyle' function is expecting a string.
Place your ttf file in the public directory of your project and remove the import statement. Then you can just do this:
url("/assets/fonts/Poppins-Regular.ttf") format("truetype");

Typescript + jest Cannot use import statement outside a module

I nearly searched every topic in google but it looks like it changes with the config and version.
I am having trouble with ES6 imports. I did everything I can, I checked ts-jest and jest github issues and whole stackoverflow but couldn't get it done. Maybe I am forgetting something? I am still getting this error:
SyntaxError: Cannot use import statement outside a module
I really don't know what else to do...
my babel.config.js
module.exports = 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',
},
},
],
],
env: {
test: {
plugins: [
"transform-es2015-modules-commonjs"
]
}
}
};
};
jest.config.js
module.exports = {
preset: 'ts-jest',
rootDir: "./",
testEnvironment: "node",
globals: {
'ts-jest': {
tsconfig: {
jsx: 'react',
isolatedModules: true
},
},
},
testPathIgnorePatterns: ['/dist', '<rootDir>/src/assets'],
transform: {
'^.+\\.ts?$': 'ts-jest',
},
moduleNameMapper: {
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/src/__mocks__/fileMock.js",
"^#common(.*)$": "<rootDir>/src/common$1",
},
collectCoverage: true,
verbose: true,
};
my package.json
{
"name": "project",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"#types/jest": "^26.0.15",
"#types/node": "^12.0.0",
"#types/react": "^17.0.0",
"#types/react-dom": "^17.0.0",
"dayjs": "^1.10.7",
"lodash": "^4.17.21",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-hot-loader": "^4.13.0",
"react-scripts": "4.0.3",
"react-select": "^5.1.0",
"react-spinners": "^0.11.0",
"sp-rest-proxy": "^3.1.1",
"typescript": "^3.6.4",
"web-vitals": "^1.0.1"
},
"scripts": {
"serve": "node server.js",
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production",
"test": "npx jest",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/preset-env": "^7.16.0",
"#babel/preset-react": "^7.16.0",
"#babel/preset-typescript": "^7.16.0",
"awesome-typescript-loader": "^5.2.1",
"babel-core": "7.0.0-beta.3",
"babel-jest": "^27.3.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"css-loader": "^3.2.0",
"file-loader": "^6.2.0",
"jest": "26.4.2",
"react-test-renderer": "^17.0.2",
"style-loader": "^1.0.0",
"ts-jest": "26.3.0",
"ts-loader": "^9.2.6",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0"
}
}
and lastly tsconfig
{
"compilerOptions": {
"sourceMap": true,
"noImplicitAny": false,
"module": "commonjs",
"target": "es5",
"lib": [
"es2015",
"es2017",
"ES6",
"dom"
],
"types": [
"jest"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "./",
"paths": {
"#common/*": [
"src/common/*"
],
"#components/*": [
"src/components/*"
],
"#webparts/*": [
"src/WebParts/*"
],
}
},
"include": [
"src"
],
"exclude": [
"node_modules"
]
}```

ReferenceError: Cannot access {variable name} before initialization

I updated react-scripts#^4.0.3 as well as typescript#~3.7.2 to the latest however when I run npm run start I get the following error :
ReferenceError: Cannot access {variable name} before initialization
I'm aware of "Temporal Deadzones" however this app has had no problem with declaring exports for arrow functions like this, in fact, we declare most/all of our functions in this syntax:
export const someFunc = () => {}
Now it's only allowing me to export after declaration like this:
function someFunction(){} -or- const someFunction = () => {}
export { someFunction }
Question: How can I allow for the export shorthand function expression syntax, with these new package updates?
Filename: tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"es2015",
"dom",
"dom.iterable",
"esnext"
],
"jsx": "react",
"baseUrl": "src",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"allowJs": true,
"noEmit": true,
"skipLibCheck": true,
"isolatedModules": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"include": [
"src"
],
"exclude": [
"./node_modules"
],
"extends": "./tsconfig.paths.json"
}
Filename: tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#src": ["*"],
"#pages": ["pages"],
"#pages/*": ["pages/*"],
"#hooks": ["core/hooks"],
"#hooks/*": ["core/hooks/*"],
"#components": ["core/components"],
"#components/*": ["core/components/*"],
"#containers": ["containers"],
"#containers/*": ["containers/*"],
"#services": ["core/services"],
"#services/*": ["core/services/*"],
"#configs": ["core/configs"],
"#configs/*": ["core/configs/*"],
"#assets": ["core/assets"],
"#assets/*": ["core/assets/*"],
"#models": ["core/models"],
"#models/*": ["core/models/*"],
"#store": ["core/store"],
"#store/*": ["core/store/*"],
"#utils": ["core/utils"],
"#utils/*": ["core/utils/*"],
"#styles": ["core/styles"],
"#styles/*": ["core/styles/*"]
}
}
}
Filename: craco.config.js
const CracoAlias = require("craco-alias")
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
source: "tsconfig",
baseUrl: "./src",
tsConfigPath: "./tsconfig.paths.json"
}
}
]
}
Filename: package.json
{
"name": "ui",
"version": "0.1.0",
"private": true,
"dependencies": {
"#craco/craco": "^6.1.2",
"#prettier/plugin-xml": "^0.12.0",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.1.2",
"#types/bootstrap": "^4.5.1",
"#types/classnames": "^2.2.11",
"#types/debug": "^4.1.5",
"#types/jest": "^24.9.1",
"#types/jquery": "^3.5.5",
"#types/lodash": "^4.14.168",
"#types/node": "^12.19.15",
"#types/react": "^16.14.2",
"#types/react-dom": "^16.9.10",
"#types/react-helmet": "^5.0.16",
"#types/react-redux": "^7.1.15",
"#types/react-router-dom": "^5.1.7",
"#types/react-select": "^3.1.2",
"#types/react-table": "^7.0.27",
"bootstrap": "^4.6.0",
"classnames": "^2.2.6",
"core-js": "^3.12.1",
"debug": "^4.3.1",
"file-selector": "^0.1.19",
"husky": "^4.3.8",
"i18next": "^19.8.4",
"immer": "^6.0.9",
"jquery": "^3.5.1",
"lint-staged": "^10.5.3",
"node-sass": "^4.14.0",
"prettier": "^2.2.1",
"react": "^17.0.2",
"react-bootstrap": "^1.4.3",
"react-dom": "^16.14.0",
"react-dropzone": "^10.2.2",
"react-helmet": "^6.1.0",
"react-i18next": "^11.8.5",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3",
"react-select": "^3.1.1",
"react-table": "^7.6.3",
"redux-thunk": "^2.3.0",
"typescript": "~3.7.2"
},
"scripts": {
"start": "BROWSER=none craco start",
"build": "npm run check && craco build",
"test": "craco test",
"coverage": "CI=true npm test -- --colors --coverage",
"check": "prettier --check \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md,xml,svg}\"",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md,xml,svg}\"",
"eject": "react-scripts eject"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"jest": {
"coverageReporters": [
"text",
"html"
],
"moduleNameMapper": {
"react-i18next": "<rootDir>/__mocks__/react-i18next.js",
"^file-loader": "<rootDir>/__mocks__/file-loader.js"
},
"resetMocks": false
},
"prettier": {
"singleQuote": true,
"jsxSingleQuote": true
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md,xml,svg}": [
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"devDependencies": {
"#babel/core": "^7.14.3",
"craco-alias": "^3.0.0"
}
}

Error: App(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null

I have problem with jest & enzyme tests. At the beginning: it's not a duplicate, as I didn't do mistakes described in similar questions.
My App.tsx:
import React from 'react';
export class App extends React.Component<{}, {}> {
render(): JSX.Element {
return <div>abc</div>;
}
}
My App.test.tsx:
import * as React from 'react';
import {mount, ReactWrapper} from 'enzyme';
import App from '../src/App';
describe('App', () => {
it('renders', () => {
const wrapper: ReactWrapper = mount(<App/>);
expect(wrapper).toMatchSnapshot();
})
})
My package.json:
{
"name": "andretweb",
"version": "0.1.0",
"private": true,
"author": "Alicja Kozik",
"description": "",
"main": "index.js",
"dependencies": {
"#babel/core": "^7.9.0",
"#babel/plugin-proposal-class-properties": "^7.8.3",
"#babel/plugin-proposal-object-rest-spread": "^7.9.5",
"#babel/preset-env": "^7.9.5",
"#babel/preset-react": "^7.9.4",
"#babel/preset-typescript": "^7.9.0",
"#fortawesome/fontawesome-svg-core": "^1.2.28",
"#fortawesome/free-solid-svg-icons": "^5.13.0",
"#fortawesome/react-fontawesome": "^0.1.9",
"#types/enzyme": "^3.10.5",
"#types/jest": "^25.2.1",
"#types/node": "^13.13.4",
"#types/react": "^16.9.34",
"#types/react-dom": "^16.9.7",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.3",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.4.4",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.2.1",
"jest": "^25.4.0",
"jest-css-modules": "^2.1.0",
"jest-environment-enzyme": "^7.1.2",
"jest-enzyme": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"style-loader": "^1.2.1",
"tslint": "^6.1.2",
"tslint-immutable": "^6.0.1",
"typescript": "^3.8.3",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"scripts": {
"test": "jest --colors --coverage",
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production",
"check-types": "tsc"
},
"jest": {
"clearMocks": true,
"collectCoverageFrom": [
"**/*.tsx",
"**/*.ts"
],
"coverageDirectory": "coverage/jest",
"moduleFileExtensions": [
"js",
"jsx",
"node",
"ts",
"tsx"
],
"collectCoverage": true,
"coveragePathIgnorePatterns": [
"\\\\node_modules\\\\",
"<rootDir>/webapp/test/dataProviders/.*\\.ts"
],
"coverageReporters": [
"json",
"text",
"html"
],
"setupFilesAfterEnv": [
"jest-enzyme"
],
"testEnvironment": "enzyme",
"testEnvironmentOptions": {
"enzymeAdapter": "react16"
},
"testPathIgnorePatterns": [
"<rootDir>/webapp/test/dataProviders/.*\\.ts"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupFiles": [
"./webapp/test/setup-tests.js"
],
"roots": [
"<rootDir>/webapp/test/"
],
"moduleDirectories": [
"<rootDir>",
"node_modules",
"webapp/src"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/webapp/test/__mocks__/fileMock.ts",
"\\.(css|less|scss|sss|styl)$": "<rootDir>/node_modules/jest-css-modules"
}
}
}
My project structure is:
<rootDir>
├───node_modules
└───webapp
├───resources
│ └───images
├───src
│ ├──typings
│ └──App.tsx
└───test
├───__mocks__
├───__snapshots__
└───App.test.tsx
And if needed, here's my tsconfig.json:
{
"compilerOptions": {
"target": "esnext",
"outDir": "./dist/",
"strictNullChecks": true,
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"strict": true,
"esModuleInterop": true,
"jsx": "react",
"baseUrl": "./webapp/src",
"lib": [
"es2015",
"dom.iterable",
"es2016.array.include",
"es2017.object",
"dom"
],
"module": "es6",
"removeComments": true,
"alwaysStrict": true,
"allowUnreachableCode": false,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"importHelpers": true
}
}
I just run command npm test and get error:
FYI: I also tried to convert this class component into function one:
function App(): JSX.Element {
return <div>abc</div>;
}
And nothing changed.
The react app is administrated by webpack with following script in webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// webpack will take the files from ./src/index
entry: './webapp/src/index',
// and output it into /dist as bundle.js
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.js'
},
// adding .ts and .tsx to resolve.extensions will help babel look for .ts and .tsx files to transpile
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
module: {
rules: [
// we use babel-loader to load our jsx and tsx files
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(sc|sa|c|le)ss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
context: ''
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './webapp/index.html'
})
]
};
I have no idea what went wrong now.
I found the solution. A few libraries were missing. Here is my fixes package.json:
{
"name": "andretweb",
"version": "0.1.0",
"private": true,
"author": "Alicja Kozik",
"description": "",
"main": "index.js",
"dependencies": {
"#babel/core": "^7.9.6",
"#babel/plugin-proposal-class-properties": "^7.8.3",
"#babel/plugin-proposal-decorators": "^7.8.3",
"#babel/plugin-proposal-optional-chaining": "^7.9.0",
"#babel/plugin-transform-async-to-generator": "^7.8.3",
"#babel/plugin-transform-regenerator": "^7.8.7",
"#babel/plugin-transform-runtime": "^7.9.6",
"#babel/preset-env": "^7.9.6",
"#babel/preset-react": "^7.9.4",
"#babel/preset-typescript": "^7.9.0",
"#babel/runtime": "^7.9.6",
"#fortawesome/fontawesome-svg-core": "^1.2.28",
"#fortawesome/free-solid-svg-icons": "^5.13.0",
"#fortawesome/react-fontawesome": "^0.1.9",
"#types/enzyme": "^3.10.5",
"#types/jest": "^25.2.1",
"#types/node": "^13.13.4",
"#types/react": "^16.9.34",
"#types/react-dom": "^16.9.7",
"babel-core": "^6.26.3",
"babel-jest": "^25.5.1",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.3",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.4.4",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.2.1",
"jest": "^25.5.2",
"jest-css-modules": "^2.1.0",
"jest-environment-enzyme": "^7.1.2",
"jest-enzyme": "^7.1.2",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-test-renderer": "^16.13.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"style-loader": "^1.2.1",
"ts-loader": "^7.0.2",
"ts-jest": "^25.4.0",
"tslint": "^6.1.2",
"typescript": "^3.8.3",
"url-loader": "^4.1.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"scripts": {
"build:dev": "webpack --mode development",
"build:prod": "webpack --mode production",
"watch:dev": "webpack-dev-server --mode development --open --hot",
"watch:prod": "webpack-dev-server --mode production --open --hot",
"test": "jest --colors --coverage",
"check-types": "tsc"
},
"jest": {
"clearMocks": true,
"collectCoverageFrom": [
"**/*.tsx",
"**/*.ts"
],
"coverageDirectory": "coverage/jest",
"moduleFileExtensions": [
"js",
"jsx",
"node",
"ts",
"tsx"
],
"collectCoverage": true,
"coveragePathIgnorePatterns": [
"\\\\node_modules\\\\",
"<rootDir>/webapp/test/dataProviders/.*\\.ts"
],
"coverageReporters": [
"json",
"text",
"html"
],
"setupFilesAfterEnv": [
"jest-enzyme"
],
"testEnvironment": "enzyme",
"testEnvironmentOptions": {
"enzymeAdapter": "react16"
},
"testPathIgnorePatterns": [
"<rootDir>/webapp/test/dataProviders/.*\\.ts"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupFiles": [
"./webapp/test/setup-tests.js"
],
"roots": [
"<rootDir>/webapp/test/"
],
"moduleDirectories": [
"<rootDir>",
"node_modules",
"webapp/src"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/webapp/test/__mocks__/fileMock.ts",
"\\.(css|less|scss|sss|styl)$": "<rootDir>/node_modules/jest-css-modules"
}
}
}
Missing libraries were: #babel/runtime, babel-core, babel-jest, ts-loader and ts-jest.

setting up ts-jest for react typescript project

I am trying to setup test environment for a react project written in typescript. I have done it before for react but with ES6.
Following is how the relevant parts of my package.json look like -
"scripts": {
"test": "NODE_ENV=test jest",
"build": "webpack --mode production",
"start": "webpack-dev-server --open --mode development"
},
"jest": {
"moduleNameMapper": {
"\\.(css)$": "jest-css-modules"
},
"transform": {
"\\.(ts|tsx)$": "ts-jest"
},
"testRegex": ".test.(ts|tsx?)$",
"moduleFileExensions": ["ts", "tsx", "js", "jsx", "json", "node"]
},
I would like to mention that I am counting on ts transpiler and not configured babel at all.
Following are the dependencies I have included -
"dependencies": {
"#types/jest": "^23.1.4",
"#types/react": "^16.4.5",
"#types/react-dom": "^16.0.6",
"#types/react-redux": "^6.0.3",
"#types/redux": "^3.6.0",
"deep-freeze": "0.0.1",
"jest": "^23.2.0",
"jest-css-modules": "^1.1.0",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"ts-jest": "^23.0.0",
"webpack": "^4.12.2"
},
"devDependencies": {
"awesome-typescript-loader": "^5.2.0",
"css-loader": "^0.28.11",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"style-loader": "^0.21.0",
"typescript": "^2.9.2",
"typings-for-css-modules-loader": "^1.7.0",
"url-loader": "^1.0.1",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4"
}
I am unable to understand following error when I run npm run test as I have already installed and specified ts-jest in transform -
Validation Error:
Module ts-jest in the transform option was not found.
<rootDir> is: /Users/rahul/ot/Lab/webpack-playlist
Following is how tsconfig.json looks like
{
"compilerOptions": {
"jsx": "react",
"noImplicitAny": true,
"sourceMap": true,
"target": "es5"
}
}
Not sure how I can I resolve the error above.
I also tried configuring ts-jest in tsconfig.json like below but it still gave same error -
// tsconfig.json
"jest": {
"globals": {
"ts-jest": {
"tsConfigFile": "tsconfig.jest.json"
}
}
}
// tsconfig.jest.json
{
"extends": "./tsconfig",
"compilerOptions": {
"module": "commonjs"
}
}
Looking through this, there isnt much that is different from my setup here:
https://github.com/jasonraimondi/typescript-react-starter
There is minor differences in your jest config. Below is the contents of my jest.config.js file.
module.exports = {
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"setupFiles": [
"<rootDir>/test/setupTests.ts"
]
};
I have a post about testing a Typescript React App using ts-jest without "create-react-app" that hopefully may be of some help to.
Here is an example setup for using Jest in a TypeScript React project. I created it myself and I hope it helps you:
jest.config.js
const {defaults} = require('jest-config');
module.exports = {
bail: true,
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'],
roots: ['src'],
testMatch: ['<rootDir>/src/**/?(*.)test.{ts,tsx}'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
verbose: true,
};
package.json
{
"dependencies": {
"#types/react": "16.7.18",
"#types/react-dom": "16.0.11",
"react": "16.7.0",
"react-dom": "16.7.0"
},
"devDependencies": {
"jest": "23.6.0",
"ts-jest": "23.10.5"
},
"scripts": {
"test": "jest"
},
"version": "0.0.0"
}
src/Welcome.tsx
import * as React from 'react';
interface WelcomeProps {
name: string,
}
const Welcome: React.FunctionComponent<WelcomeProps> = (props: WelcomeProps) => {
return <h1>Hello, {props.name}</h1>;
};
export default Welcome;
src/Welcome.test.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import Welcome from './Welcome';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Welcome name="John Doe"/>, div);
ReactDOM.unmountComponentAtNode(div);
});
This is the only configuration that worked for me. Here are my specs:
{
"name": "project",
"version": "1.0.0",
"description": "project",
"jest": {
"modulePathIgnorePatterns": [
"dist/"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"moduleNameMapper": {
"^.+\\.(css|less|scss)$": "identity-obj-proxy"
},
"setupFilesAfterEnv": [
"./setupTests.ts"
],
"coverageReporters": [
"text",
"lcov"
],
"coverageDirectory": ".",
"transform": {
".(js|jsx)": "babel-jest",
".(ts|tsx)": "ts-jest"
}
},
"peerDependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
"devDependencies": {
"#types/enzyme": "^3.10.5",
"#types/enzyme-adapter-react-16": "^1.0.6",
"#types/jest": "^26.0.4",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"enzyme-adapter-react-16": "^1.12.1",
"ts-jest": "^26.1.0",
"typescript": "~3.9.5"
},
"scripts": {
"tsc": "tsc --build tsconfig.json",
"watch": "tsc --watch",
"test": "jest",
"test-coverage": "jest --coverage"
}
}
setupTests.ts:
import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
And finally here is my tsconfig.json:
{
"compileOnSave": false,
"compilerOptions": {
"allowJs": true,
"declaration": true,
"declarationMap": true,
"jsx": "react",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"noImplicitAny": true,
"target": "es5",
"outDir": "./dist",
"declarationDir": "./dist",
"lib": ["es2016", "dom"]
},
"include": ["./src/index.ts"]
}
According to docs of ts-jest you should set globals.tsConfig, but it must be globals.tsconfig. For example:
globals: {
'ts-jest': {
// ts-jest configuration goes here
// https://huafu.github.io/ts-jest/user/config/#ts-jest-options
// specify tsconfig.json to be used by ts-jest
tsconfig: '<rootDir>/test/tsconfig.test.json',
},
},
With tsconfig in works for me, with tsConfig no.
Source: https://dev.to/ushakovmaksim/comment/1bc8j
I had same error and got it fixed by running following commands in terminal:
Via npm:
1. "npm i -D jest typescript"
2. "npm i -D ts-jest #types/jest "
3. "npx ts-jest config:init"
4. "npm t or npx jest"
Via yarn:
1. "yarn add --dev jest typescript"
2. "yarn add --dev ts-jest #types/jest"
3. "yarn ts-jest config:init"
4. "yarn test or yarn jest"
I am using ubuntu 18.04.3 LTS.

Resources