Jest aliases not working with sveltekit/vite - jestjs

Here is the error:
$ z front
➜ Catalyze-frontend git:(more-tests) ✗
$ npm run test:jest
> catalyze-frontend#0.0.1 test:jest
> jest --rootDir ./src
Error: Jest: Failed to parse the TypeScript config file /home/ettinger/src/oblivion/Catalyze-frontend/jest.config.ts
Error: Must use import to load ES Module: /home/ettinger/src/oblivion/Catalyze-frontend/jest.config.ts
require() of ES modules is not supported.
require() of /home/ettinger/src/oblivion/Catalyze-frontend/jest.config.ts from /home/ettinger/src/oblivion/Catalyze-frontend/node_modules/#jest/core/node_modules/jest-config/build/readConfigFileAndSetRootDir.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from /home/ettinger/src/oblivion/Catalyze-frontend/package.json.
at readConfigFileAndSetRootDir (/home/ettinger/src/oblivion/Catalyze-frontend/node_modules/#jest/core/node_modules/jest-config/build/readConfigFileAndSetRootDir.js:136:13)
at async readConfig (/home/ettinger/src/oblivion/Catalyze-frontend/node_modules/#jest/core/node_modules/jest-config/build/index.js:233:18)
at async readConfigs (/home/ettinger/src/oblivion/Catalyze-frontend/node_modules/#jest/core/node_modules/jest-config/build/index.js:420:26)
at async runCLI (/home/ettinger/src/oblivion/Catalyze-frontend/node_modules/#jest/core/build/cli/index.js:132:59)
at async Object.run (/home/ettinger/src/oblivion/Catalyze-frontend/node_modules/jest-cli/build/cli/index.js:155:37)
➜ Catalyze-frontend git:(more-tests) ✗
Here is my jest.config.ts:
export default {
verbose: true,
testEnvironment: 'jsdom',
transform: {
'^.+\\.svelte$': [
'svelte-jester',
{
preprocess: true
}
],
'^.+\\.js$': 'babel-jest',
'^.+\\.ts$': 'ts-jest'
},
moduleFileExtensions: ['js', 'ts', 'svelte'],
setupFilesAfterEnv: ['#testing-library/jest-dom/extend-expect'],
moduleNameMapper: {
'^$components(.*)$': '<root-dir>/src/components$1'
}
};
I believe package.json has type: "module" which is causing the issue however sveltekit/vite require this. So I don't know how to fix.

Related

Jest is unable to import default export from index file of absolute path: "ENOENT: no such file or directory"

I set up absolute path in my node.js typescript project.
Here's the content of my Jest config file (jest.config.js):
const { pathsToModuleNameMapper } = require('ts-jest');
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
transform: {
'^.+\\.ts?$': 'ts-jest',
},
transformIgnorePatterns: ['<rootDir>/node_modules/'],
modulePaths: ['./src'],
moduleNameMapper: pathsToModuleNameMapper({
'#/*': ['*'],
}),
clearMocks: true,
};
The above config enables Jest to understand absolute path in my code.
Below is a sample of my project structure. I have a events directory that has an index.ts file like so:
src
└─ events
└─ index.ts
When I import the default export like so:
import events from '#/events'
and run Jest it throws: "ENOENT: no such file or directory, open 'events'"
but it works if I import the default export like so
import events from '#/events/index'
How do I get Jest to recognize the index.ts file in the absolute path without explicitly specifying it?
Jest should be able to detect and use the index file of the absolute path when I import like so:
import events from '#/events'
Try to add this in your tsconfig.json
{
"compilerOptions": {
"baseUrl": "./"
},
}

Bundle NPM Package so it has different import paths with Vite and Typescript

How can I bundle my NPM package in a way that I can have different import paths for different parts of the package? I have found webpack approaches, but I am using Vite and TS.
My package looks like this:
- src
- atoms
- molecules
- organism
- index.ts (currently simply imports and exports everything)
Now I can use this currently like this
import { Button } from '#mypackage/library'
How can I do it, so I get this outcome:
import { Button } from '#mypackage/library/atom'
Here is the relevant part of my package.json
{
"entry": "src/index.ts",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"exports": {
".": {
"import": "./dist/index.es.js",
"require": "./dist/index.cjs.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json",
"./atoms": "./src/atoms/index.ts",
"./molecules": "./src/molecules/index.ts",
"./organisms": "./src/organisms/index.ts",
"./theme": "./src/theme/index.ts"
},
}
Here is my vite.config.ts
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
formats: ['es', 'cjs'],
name: '#workdigtital/component-library-react',
fileName: (format) => `index.${format}.js`
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM'
},
exports: 'named'
}
}
},
plugins: [react(), dts({ insertTypesEntry: true })],
resolve: {
alias: {
'#': path.resolve(__dirname, './src')
}
}
});
If I currently try an import like this, inside another project (Laravel+React), in which installed the library.
import { ThemeProvider } from '#workdigital/component-library-react/theme';
I get the following run time error (But no Typescript errors, even IntelliSense is working):
Failed to load url /resources/js/theme/ThemeProvider (resolved id: /resources/js/theme/ThemeProvider). Does the file exist?
My resulting Dist folder looks like this:
You can't have TypeScript exports, this simply won't work. An npm package should have only JS exports.
If you want to be able to selectively import different parts of your package, you must transpile them to different files.
rollup can do it, but it is lots of work, as you will have to set up a separate target for each exported file. Normally you use rollup to create a single bundle, this what this tool is made for.
tsc with a tsconfig.json will be a much better choice in your case. It does this by default, you only need to specify the output directory and it will produce a separate file for each source.
There is an excellent guide on the TypeScript site about packaging TypeScript libraries, you should probably start there.

How to use jsonapi-vuex [es6 module export] with Jest?

I'm trying to make use of the jsonapi-vuex npm package. I import it within my code like so:
import { jsonapiModule } from "jsonapi-vuex";
Jest however stumbles over this package. This package uses es6 modules. The index.js for that node module looks like this:
export { jsonapiModule, utils } from './src/jsonapi-vuex'
Jest fails on this even though babel-jest is installed with the following error:
Jest encountered an unexpected token
/node_modules/jsonapi-vuex/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export { jsonapiModule, utils } from './src/jsonapi-vuex'
^^^^^^
I've tried various things:
Tried adding to jest config so that just shouldn't ignore this library when transpiling:
transformIgnorePatterns: [
"<rootDir>/node_modules/(?!jsonapi-vuex)"
],
Tried the babel-plugin-transform-es2015-modules-commonjs plugin
As far as I can tell, babel-jest makes use of .babelrc. I have this configured with the #babel/preset-env preset, which is supposed to handle es6 modules... so I really don't understand why it is failing. Here's the .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"modules": "commonjs",
"targets": {
"node": "current"
}
}
]
]}

Jest Is Not Transpiling ES6 Modules In Test (SyntaxError: Unexpected token export)

I'm at a boiling point with getting Jest to understand ES6 modules import/export syntax and it is hindering my project development progress. My project structure is the following:
root module
org-domain (ES6)
org-services (ES6)
react-ui-module (React via CRA2)
org-services has a local path dependency on org-domain in its package json:
// in org-services package.json
"dependencies": {
"#org/domain": "file:../org-domain",
},
My .babelrc in org-services is the following:
{
"env": {
"test": {
"presets": ["#babel/preset-flow", "#babel/preset-env"]
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
},
"presets": [
"#babel/preset-flow",
["#babel/preset-env", {
"targets": {
"esmodules": true
}
}]
],
"plugins": [
["module-resolver", {
"root": ["./node_modules/#org/domain"],
"alias": {
"#org/constants": "./node_modules/#org/domain/src/constants",
"#org/contracts": "./node_modules/#org/domain/src/request-contracts"
}
}]
]
}
I do not know if the problem is due to how I am including my dependencies so I'm going to add the finer details of anything related to my import/export of these modules for the sake of clarity.
In the implementation files of org-services I am importing org-domain using npm scoped syntax like so: import ... from '#org/domain
Here are some observations I have:
In local development, when I try to reference click #org/domain, instead of being directed to org-services/node_modules/#org/domain I get redirected to the actual relative directory location which is root/org-services. I believe Jest ignores node_modules (correct me if I am wrong) but in my jest.config.js for org-services, I have:
collectCoverage: true,
coverageDirectory: 'coverage',
coveragePathIgnorePatterns: [
'/node_modules/'
],
moduleDirectories: [
'src',
'node_modules'
],
moduleFileExtensions: [
'js'
],
transform: {
'^.+\\.js$': 'babel-jest'
},
transformIgnorePatterns: [
'node_modules/(?!#org/domain)$'
]
To my understanding, everything should just work right now with all the configuration I have with respect to setting the plugin #babel/plugin-transform-modules-commonjs in test (within .babelrc) and including the '^.+\\.js$': 'babel-jest' instruction under the transform key in jest.config.js located under org-services -- but it does not.
I have tried every single thing I could find online with respect to this issue with no success. I have not gotten anywhere since and my patience is lost with this testing framework and the lack of support for ES6. It should not be this hard, so clearly I am doing something wrong here. Please advise.
Update 1
Found another SO post that is a mirror of this situation I am in.
Jest fails to transpile import from npm linked module
Unfortunately, the provided solution does not work for my case.
After upgrading from #babel/xyz: 7.0.0 to 7.1.2 I started getting an error regarding "import"
Jest encountered an unexpected token
<snip>
Details:
C:\....\SstcStrategy.test.js:2
import sequelizeFixtures from 'sequelize-fixtures';
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
To fix this I had to add #babel/plugin-transform-modules-commonjs as you mention in your question.
My babel.config.js now looks like this:
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: '8.10',
},
debug: false,
},
],
],
ignore: ['node_modules'],
plugins: [
'#babel/plugin-transform-runtime',
'#babel/plugin-transform-modules-commonjs',
// Stage 2
['#babel/plugin-proposal-decorators', { legacy: true }],
'#babel/plugin-proposal-function-sent',
'#babel/plugin-proposal-export-namespace-from',
'#babel/plugin-proposal-numeric-separator',
'#babel/plugin-proposal-throw-expressions',
// Stage 3
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-syntax-import-meta',
['#babel/plugin-proposal-class-properties', { loose: false }],
'#babel/plugin-proposal-json-strings',
],
};
Also BTW you don't need to define babel-jest transform in jest.config.js as this is the default setting.
Hope this helps

Jest gives an error: "SyntaxError: Unexpected token export"

I'm using Jest to test my React app.
Recently, I added DeckGL to my app. My tests fail with this error:
Test suite failed to run
/my_project/node_modules/deck.gl/src/react/index.js:21
export {default as DeckGL} from './deckgl';
^^^^^^
SyntaxError: Unexpected token export
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:318:17)
at Object.<anonymous> (node_modules/deck.gl/dist/react/deckgl.js:9:14)
at Object.<anonymous> (node_modules/deck.gl/dist/react/index.js:7:15)
This looks like an issue with Jest transforming a node module before running it's tests.
Here is my .babelrc:
{
"presets": ["react", "es2015", "stage-1"]
}
Here is my jest setup:
"jest": {
"testURL": "http://localhost",
"setupFiles": [
"./test/jestsetup.js"
],
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
],
"moduleDirectories": [
"node_modules",
"/src"
],
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/test/EmptyModule.js"
}
},
I seem to have the correct things necessary to transform export {default as DeckGL }. So any ideas whats going wrong?
This means, that a file is not transformed through TypeScript compiler, e.g. because it is a JS file with TS syntax, or it is published to npm as uncompiled source files. Here's what you can do.
Adjust your transformIgnorePatterns allowed list:
{
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!#ngrx|(?!deck.gl)|ng-dynamic)"
]
}
}
By default Jest doesn't transform node_modules, because they should be valid JavaScript files. However, it happens that library authors assume that you'll compile their sources. So you have to tell this to Jest explicitly. Above snippet means that #ngrx, deck and ng-dynamic will be transformed, even though they're node_modules.
And if you are using 'create-react-app', it won't allow you to specify 'transformIgnorePatterns' via Jest property in package.json
As per this https://github.com/facebook/create-react-app/issues/2537#issuecomment-390341713
You can use CLI as below in your package.json to override and it works :
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!your-module-name)/\"",
},
This is because Node.js cannot handle ES6 modules.
You should transform your modules to CommonJS therefore.
Babel 7 >=
Install
npm install --save-dev #babel/plugin-transform-modules-commonjs
And to use only for test cases add to .babelrc,
Jest automatically gives NODE_ENV=test global variable.
"env": {
"test": {
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
}
Babel 6 >=
npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
to .babelrc
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
Jest by default won't compile files in the node_modules directory.
transformIgnorePatterns [array]
Default: ["/node_modules/"]
An array of regexp pattern strings that are matched against all source
file paths before transformation. If the test path matches any of the
patterns, it will not be transformed.Default: ["/node_modules/"]
DeckGL seems to be in ES6, to make jest able to read it, you need to compile this as well.
To do that, just add an exception for DeckGL in the transformignorePatterns
"transformIgnorePatterns": ["/node_modules/(?!deck\.gl)"]
https://facebook.github.io/jest/docs/en/configuration.html#transformignorepatterns-array-string
I was having this issue with a monorepo. A package in the root node_modules was breaking my tests. I fixed by changing my local .babelrc file to babel.config.js. Explanation: https://github.com/facebook/jest/issues/6053#issuecomment-383632515
It was work around #1 on this page that fixed it for me though workaround #2 on that page is mentioned in above answers so they may also be valid.
"Specify the entry for the commonjs version of the corresponding package in the moduleNameMapper configuration"
jest.config.js
moduleNameMapper: {
"^uuid$": require.resolve("uuid"),
"^jsonpath-plus$": require.resolve("jsonpath-plus")
...
In my case I use this config in the file package.json:
"jest": {
"transformIgnorePatterns": [
"!node_modules/"
]
}
This code worked for me
// .babelrc
{
"presets": [
["env", {
"modules": "commonjs", // <- Check and see if you have this line
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}
jest understands commonJs so it needs babel to transform the code for it before use. Also jest uses caching when running code. So make sure you run jest --clearCache before running jest.
Tested Environment:
Node v8.13.0
Babel v6+
Jest v27
I'm using a monorepo (it contains multiple packages for the frontend and backend).
The package I'm testing imports a file from another package that uses the dependency uuid.
All the files are in Typescript (not Javascript).
The package I'm testing has a tsconfig file for testing only, called tsconfig.test.json. It has the properties commonjs and allowJs. Adding allowJs solves the problem when importing uuid, I don't know why.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": [
"jest",
"node"
],
// Necessary to import dependency uuid using CommonJS
"allowJs": true
},
"include": [
"jest.config.ts",
"**/*.test.ts",
"**/*.d.ts"
]
}
I was upgrading a project that uses a version of babel that reads the config from .babelrc, when I upgraded to a newer version I read:
https://babeljs.io/docs/en/configuration#whats-your-use-case
What's your use case?
You are using a monorepo?
You want to compile node_modules?
babel.config.json is for you!
On top of:
{
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!(module))"
]
}
}
I renamed .babelrc to babel.config.json too.
I had the same error of importing dataSet from vis-data.js library
import { DataSet } from 'vis-data/esnext';
So I just removed /esnext from the path and now it works:
import { DataSet } from 'vis-data';

Resources