I'm using babel to transpile files from src to lib and when i try to run jest I get a conflict between src/Template.js and lib/Template.js
Using Jest CLI v0.9.0, jasmine2, babel-jest
Error: Failed to build DependencyGraph: #providesModule naming collision:
Duplicate module name: Template
Paths: src/Template.js collides with lib/Template.js
How should one deal with this scenario? Is there maybe a way to ignore one of the directories?
In package.json:
babel-cli#6.x
babel-jest#9.x
babel-polyfill#6.x
babel-preset-es2015#6.x
babel-preset-react#6.x
jasmine#2.x
jasmine-spec-reporter#2.x
jest-cli#0.9.x
Problem was that jest is by default searching the whole project for tests.
https://facebook.github.io/jest/docs/api.html#config-testpathdirs-array-string
Solution in package.json
"jest": {
"testPathDirs": [
"<rootDir>/__tests__", # Default is <rootDir>
"<rootDir>/lib" # Needed for automatic mocking to work
],
...
}
Related
I followed a JavaScript unit testing tutorial at acadamind.com in that tutorial instructor used Vitest for demonstrations and the reason they mentioned using Vitest instead of Jest was Jest needed some extra configuration to work with the latest JavaScript syntax.
After doing my own research about unit testing I realized industry demand unit testing skills with the Jest. So I followed another tutorial for learning unit testing with Jest and React Testing Library (RTL).
I created a brand new TypeScript project with Create React App (CRA) and followed the instructions in that tutorial and everything went well. The instructor mentioned that Jest and RTL are supported out of the box with CRA.
After studying unit testing I tried to apply that knowledge and write some tests with my application, which was created some time back, and recently we updated it to React Scripts 5. In that application, I check node_modules folder, and Jest is there as a dependency. But I have noticed that the following packages are not listed in the package.json file in my project, so I installed them:
#testing-library/jest-dom": "^5.16.5",
#testing-library/react": "^13.4.0",
#testing-library/user-event": "^14.4.3",
#types/jest": "^29.4.0",
After that, I noticed my new project has this file in the src folder so I have copy pasted this file as well.
setupTest.ts
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '#testing-library/jest-dom';
When I tried to run when I tried to write my first unit test I noticed that VS Code doesn't recognize this test function as a global function and indicates an error and then I try to run the test script and I am getting this error
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/home/pathum/Documents/tagd/node_modules/axios/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import axios from './lib/axios.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | import axios from 'axios';
| ^
2 | // config
3 | import { HOST_API } from '../config';
4 |
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/utils/axios.ts:1:1)
at Object.<anonymous> (src/hooks/useRefresh.tsx:2:1)
at Object.<anonymous> (src/hooks/useAxiosPrivate.tsx:3:1)
at Object.<anonymous> (src/pages/contracts/contract-form/new-contact-person.tsx:12:1)
at Object.<anonymous> (src/pages/contracts/contract-form/parties.tsx:15:1)
at Object.<anonymous> (src/pages/contracts/contract-form/contract-form.tsx:9:1)
at Object.<anonymous> (src/pages/contracts/contract-form/contract-form.test.tsx:2:1)
at TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/#jest/core/build/runJest.js:404:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 2.398 s
Ran all test suites related to changed files.
Watch Usage: Press w to show more.
Seems I need to do some configurations for Jest to work properly in the application. How do I fix this?
Install the necessary dependencies: npm install --save-dev #babel/preset-typescript and npm install --save-dev jest-cli typescript
Create a new file in the root of your project called jest.config.js and add the following content to it:
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
};
Add a new property called "jest" to the "scripts" section of your package.json file and set it to the following: "jest --config jest.config.js --coverage". This will tell Jest to use the configuration file you just created and also generate a coverage report.
Create a new file in the root of your project called tsconfig.test.json and add the following content to it:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./test-dist"
},
"include": [
"src/**/*.test.ts"
]
}
Finally, you can run your tests with npm run jest.
You also need to make sure that you are using import statement correctly in your tests. You should use import statement to import functions, classes, and variables from other modules, but you should use require statement to import modules that are not written in TypeScript.
I'm trying to export a Vue component as a package, and using vue cli to build the dist. I intend to publish it on npm, but I'm currently using a symbolic link for testing purpose. However even with a simple hello-world project I can't make a valid package.
I created a project:
vue create hello-world
Then I modified the package.json:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --target lib --name vue-hello-world ./src/components/HelloWorld.vue",
"lint": "vue-cli-service lint"
},
"main": "./dist/vue-hello-world.common.js",
Then I call
npm run build
and it compiles without error.
Then I make an import in a vue component in another project (I used a symbolic link in node_modules):
import HelloWorld from "hello-world";
On page render I get the following error:
[Vue warn]: Failed to resolve async component: function MediaViewerPdf() {
return Promise.all(/*! import() */[__webpack_require__.e(62), __webpack_require__.e(46)]).then(__webpack_require__.bind(null, /*! ./viewers/MediaViewerPdf.vue */ "./vuejs/components/mediaViewer/viewers/MediaViewerPdf.vue"));
}
Reason: ReferenceError: require is not defined
Any idea what's happening?
Remarks:
using vue inspect, I checked that in webpack config that:
target: "web"
I already set resolve.symlinks at false on the importing project.
EDIT: I have confirmed that it doesn't come from the symbolic link, I have exactly the same error with package directly on node_modules.
Repo with whole code: https://github.com/louis-sanna/vue-hello-world
So I asked the question on the vue-cli repo and I got the solution! https://github.com/vuejs/vue-cli/issues/4245
Turns out NODE_ENV was already set at development in my shell, so it was the mode used to make the build.
Just need to set the mode explicitly and it works:
vue-cli-service build --target lib --name vue-hello-world ./src/components/HelloWorld.vue --mode production
You may need to add it to vue.config.js:
config
.mode("production")
This happens due to the fact that Vue CLI Webpack setup by default does not import commonjs modules, as described in your "main" field in package.json. So the problem is with the project that attempts import, not with the project that exports the component.
There are two ways to attempt to solve this problem.
From the importing project side
You can remedy this by installing babel plugins for the project that imports your components and setting babel.config.js
module.exports = {
presets: [
'#vue/app'
],
plugins: [
'#babel/plugin-transform-modules-commonjs', // leave to import .common.js files
'#babel/plugin-transform-modules-umd' // leave to import .umd.js files
]
}
But doing this alone will not be sufficient: you also will need to import CSS that is generated with the library by adding this in your entry file
import 'hello-world/dist/vue-hello-world.css';
Note that I have only tested this using yarn link, but I have confidence that this will work with an imported separate npm module just fine.
From the library side
The intent (I suppose) of the original question - how do I bundle a library so my users don't have to do this little dance each time they want to use it?
Option 1: don't bundle it - provide .vue files and sources. Just include everything in 'src' directory of your module, write a readme with explanation and be done with it. Let the importing project figure the compilation and bundling out.
Option 2: use rollup with Vue plugin to roll components into bundle. There is an example on how to do that. In that example you can see that your project will be able to import .esm build
https://github.com/vuejs/rollup-plugin-vue/tree/master/cookbook/library
Not sure how you are creating the symbolic link, but you should use npm link for that. If you are still having problems (like I did myself) I would suggest you try npm-link-better:
npm install -g npm-link-better
cd vue-hello-world
npm link
cd ../hello-world
nlc -w vue-hello-world
For building component libraries, I suggest you have a look at vue-cli-plugin-component. This plugin already sets up the vue-cli project pretty well.
I am trying to use this with my webpack project
https://blog.meteor.com/leverage-the-power-of-meteor-with-any-client-side-framework-bfb909141008
but I get this error
ReferenceError: __meteor_runtime_config__ is not defined
Here are the steps I did
create a new meteor project
then I run the client bundler like this
meteor-client bundle —source=./ —destination=./meteor-client.bundle.js —config=meteor-client.config.json
and here is the config
{
"runtime": {
"DDP_DEFAULT_CONNECTION_URL": "http://localhost:3000"
},
"import": [
"meteor-base#1.3.0",
"mongo#1.4.2",
"reactive-var#1.0.11",
"jquery#1.11.10",
"tracker#1.1.3",
"shell-server#0.3.1",
"react-meteor-data"
]
}
then I copy my meteor-client.js to my webpack project node_modules
and import it like this
import 'meteor-client'
then I bundle webpack and run dev-server and I get the above mentioned error.
I had the same issue, and fixed that by putting my meteor-client.js to node_modules and exclude node_modules from processing by babel-loader with webpack (or you could just exclude meteor-client.js). Raw loading will workaround that.
In case someone still searching.
I am testing using Jest and my appication is running on Next.js... I am trying to test a page component in my Next application, but I am receiving errors that are shown in the following screenshot; The "Before" image is before I tried implementing a solution found on Stackoverflow, and the "After" is after the solution was implemented. I am still stuck and need some friendly help!
Here is also my current Jest config in my package.json
"jest": {
"setupFiles": ["./shim.js", "./setupTests.js"],
"verbose": true,
"moduleNameMapper": {
"^.+\\.(css|scss)$": "./cssStub.js"
}
}
Thanks!
I'm using CSS modules and it convenient for me to use "proxy" as if the code requires styles, jest will return a proxy, that will return the required field name instead of the value.
For example:
import * as styles from './styles.scss';
console.log(styles.someClassName);
// the proxy in that case will return a string with `someClassName` value.
All you need to configure is install
npm install --save-dev identity-obj-proxy
and add
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy",
}
to your Jest section in the package.json file.
Edit
Pay attention that according to the docs you should use <rootDir>
when you are mapping to a file.
"\\.(css|scss)$": "<rootDir>/cssStub.js.js",
My issue was silly enough that I wrongly specified my <rootDir> path. I would suggest reading the solution from this post for further details to how to resolve similar issue... Thanks all for the help!
SyntaxError with Jest and React and importing CSS files
I am using webpack to build my app and I use a library (eventemitter4) that itself depends on another library (underscore).
However, I am already using in my application an alternative to underscore (lodash and more exactly the es6 version).
I would like eventemitter4 to use this later library and avoid including in my build the two.
I install my dependencies using npm install. As a result, underscore is bundled as a subdirectory inside the eventemitter4's directory.
It tried to set aliases but I could not make it work:
alias: {
"underscore": "lodash-es",
"lodash": "lodash-es",
"~/underscore": "lodash-es"
}
raises
ERROR in ./~/eventemitter4/index.js
Module not found: Error: Cannot resolve module 'lodash-es' in /Users/me/myapp/node_modules/eventemitter4
# ./~/eventemitter4/index.js 6:2-23
If I do not add "~/underscore": "lodash-es", the sub-underscore is included instead of lodash.
Any idea?
Thank you very much for your help.
I actually found the reason. The alias was working. The cause of the error was that lodash-es does not provide a main attribute in his package.json (it only provides an esnext:main which is not recognised by webpack).
I solve the issue by using:
alias: {
"underscore": "lodash-es",
"lodash": "lodash-es/lodash",
"~/underscore": "lodash-es"
}