TL;DR
How can you tell SWC to compile CSS files imported in React components?
How can you tell SWC to compile absolute imports in tests and in React components?
Here is a minimal reproducible example.
Context
We're migrating from Babel to SWC. (I asked a question a little while ago. I'm improving on that question's answer.)
We're migrated the command from:
"test": "NODE_ENV=test riteway -r #babel/register 'src/**/*.test.js' | tap-nirvana",
to
"test": "SWC_NODE_PROJECT=./jsconfig.json riteway -r #swc-node/register src/**/*.test.js | tap-nirvana",
where the jsconfig.json looks like this:
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./src",
"jsx": "react-jsx"
}
}
If we write try to compile a test for a self-contained component (no absolute imports, no CSS) it works:
import { describe } from 'riteway';
import render from 'riteway/render-component';
function HomePageComponent({ user: { email } }) {
return <p>{email}</p>;
}
describe('home page component', async assert => {
const user = { email: 'foo' };
const $ = render(<HomePageComponent user={user} />);
assert({
given: 'a user',
should: 'render its email',
actual: $('p').text(),
expected: user.email,
});
});
The test compiles fine.
With Babel we had a .babelrc like this:
{
"env": {
"test": {
"plugins": [
[
"module-resolver",
{
"root": [
"."
],
"alias": {
"components": "./src/components",
"config": "./src/config",
"features": "./src/features",
"hocs": "./src/hocs",
"hooks": "./src/hooks",
"pages": "./src/pages",
"redux": "./src/redux",
"styles": "./src/styles",
"tests": "./src/tests",
"utils": "./src/utils"
}
}
]
]
}
},
"presets": [
[
"next/babel",
{
"ramda": {}
}
]
],
"plugins": [
["styled-components", { "ssr": true }]
]
}
Where the styles where taken care of by styled-components and the absolute imports where defined via the module-resolver plugin. (We switched away from styled-components to CSS modules, which is why we import from .module.css CSS files. Anyways ...)
If we write the test how we wanted to write it with their actual imports like this:
import { describe } from 'riteway';
import render from 'riteway/render-component';
import { createPopulatedUserProfile } from 'user-profile/user-profile-factories';
import HomePageComponent from './home-page-component';
describe('home page component', async assert => {
const user = createPopulatedUserProfile();
const $ = render(<HomePageComponent user={user} />);
assert({
given: 'a user',
should: 'render its email',
actual: $('p').text(),
expected: user.email,
});
});
It fails with:
$ SWC_NODE_PROJECT=./jsconfig.json riteway -r #swc-node/register src/features/home/home-page-component.test.js | tap-nirvana
/Users/janhesters/dev/my-project/src/features/home/home.module.css:1
(function (exports, require, module, __filename, __dirname) { .container {
^
SyntaxError: Unexpected token '.'
when we leave in the CSS import in home-page-component.js, or with:
$ SWC_NODE_PROJECT=./jsconfig.json riteway -r #swc-node/register src/features/home/home-page-component.test.js | tap-nirvana
node:internal/modules/cjs/loader:936
throw err;
^
Error: Cannot find module 'user-profile/user-profile-factories'
Require stack:
- /Users/janhesters/dev/my-project/src/features/home/home-page-component.test.js
- /Users/janhesters/dev/my-project/node_modules/riteway/bin/riteway
respectively, when we get rid of the CSS import.
How can we help SWC understand CSS (or mock CSS modules) and how can we help it understand absolute imports?
We already set the baseUrl in jsconfig.json ...
About absolute path
You already add baseUrl in the jsconfig.json file but didn't add the paths, you should modify your config file like mine:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#screens": ["./screens"],
"#shared": ["./shared"],
"#shared/*": ["./shared/*"]
},
The paths are the alias of module-resolver, and I guess your root shouldn't be ".", it should be exactly like your jsconfig.json file, I mean the baseUrl value.
"plugins": [
[
"module-resolver",
{
"root": ["./src"],
"extensions": [".ts", ".tsx", ".js", ".jsx", ".json"],
"alias": {
"#screens": "./src/screens",
"#shared": "./src/shared"
}
}
]
],
If you have Webpack, you should have alias config in your resolve key off Webpack config object, like mine:
const resolve = {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
alias: {
'#screens': path.join(__dirname, 'src/screens/'),
'#shared': path.join(__dirname, 'src/shared/'),
},
modules: ['src', 'node_modules'],
descriptionFiles: ['package.json'],
};
About CSS
Actually, you are using CSS file as CSS-Modules not like recommended NexJS doc, in docs developer should import CSS like import './styles.css' and then use it as string in JSX like <div className="main"
But
You are importing it like a module (CSS-Module):
// you did it
import styles from './styles.css';
<div className={styles.main}
As you know it is built-in support by this doc, it is supported by NextJS, but SWC cannot understand it. I put in hours to find a way for it, but it seems SWC doesn't support CSS-Module yet. you should create your own plugin for SWC to support CSS-Module.
How can we help SWC understand CSS (or mock CSS modules)? - SWC doesn't understand css natively, and neither did Babel. As you noted, when you were using Babel, the plugin styled-components took care of this. You'll need to do the same with SWC. I can't find an existing SWC plugin that does this, but you can roll your own. Obviously this is a pain, but such is the cost of using new tooling.
How can we help SWC understand absolute imports? - The .swrc options for baseUrl and paths should do what you want, but that, too, seems to have some issues.
You may have better luck creating issues directly in the #swc-node GitHub repo, but given the comments there it feels like you might be SOL for a while. Might be faster/easier to rewrite your tests using one of the libraries that Next supports out of the box.
I was able to solve all issues without writing any plugins. I pushed the solution to my example repo from the question.
Firstly, use the official SWC project's register. This means, you have to compile your tests like this:
"test": "riteway -r #swc/register 'src/**/*.test.js' | tap-nirvana",
You can install it by running:
yarn add --dev #swc/core #swc/register
We need this version of register, because it takes into account an .swcrc file, which the other one did not.
Secondly, you need both "path" and "baseUrl" to fix the absolute imports because for some reason SWC doesn't infer all paths with only a "baseUrl" provided. And you need to adapt your .swcrc to handle React.
{
"jsc": {
"baseUrl": "./src",
"paths": {
"*.css": ["utils/identity-object-proxy.js"],
"utils/*": ["utils/*"]
},
"parser": {
"jsx": true,
"syntax": "ecmascript"
},
"transform": {
"react": {
"runtime": "automatic"
}
}
},
"module": {
"type": "commonjs"
}
}
Thirdly, to solve .css you need to remap all imports to .css files to an identity object proxy, which you can see in the .swcrc example above. An identity object proxy is an object that, when you reference any property, returns the stringified key that you're trying to reference. You can create one yourself like this:
const identityObjectProxy = new Proxy(
{},
{
get: function getter(target, key) {
if (key === '__esModule') {
return false;
}
return key;
},
},
);
export default identityObjectProxy;
For the .css remap to go into effect you need to make all your imports to .css files absolute imports. (import styles from './styles.module.css won't work!)
I create a webaite with angular 9 but i have a problem with angular .
In some route I have the error:
ERROR Error: Uncaught (in promise): Error: Angular JIT compilation failed: '#angular/compiler' not loaded!
- JIT compilation is discouraged for production use-cases! Consider AOT mode instead.
- Did you bootstrap using '#angular/platform-browser-dynamic' or '#angular/platform-server'?
- Alternatively provide the compiler with 'import "#angular/compiler";' before bootstrapping.
Error: Angular JIT compilation failed: '#angular/compiler' not loaded!
- JIT compilation is discouraged for production use-cases! Consider AOT mode instead.
- Did you bootstrap using '#angular/platform-browser-dynamic' or '#angular/platform-server'?
- Alternatively provide the compiler with 'import "#angular/compiler";' before bootstrapping.
But in some routes I do not have this error. Another weird thing is that in local it works fine but in server it did not work. What's the problem and how can I solve it?
In my server I place the put the files in the app folder, while in the local machine I don't have this folder.
Here is angular.json:
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"avastar": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "kt",
"schematics": {
"#schematics/angular:component": {
"style": "scss"
}
},
"architect": {
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/avastar",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.png",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [
"src/assets/vendors/global/vendors.bundle.js",
"src/assets/js/demo1/scripts.bundle.js"
],
"stylePreprocessorOptions": {
"includePaths": [
"src",
"src/stylings/",
"src/stylings/base/",
"src/stylings/kt-customs/"
]
},
"es5BrowserSupport": true
},
"configurations": {
"production": {
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [{
"type": "initial",
"maximumWarning": "5mb",
"maximumError": "10mb"
}]
}
}
},
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "avastar:build"
},
"configurations": {
"production": {
"browserTarget": "avastar:build:production"
}
}
},
"extract-i18n": {
"builder": "#angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "avastar:build"
}
},
"test": {
"builder": "#angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.scss"
],
"scripts": [],
"assets": [
"src/assets"
]
}
},
"lint": {
"builder": "#angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"avastar-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "#angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "avastar:serve"
},
"configurations": {
"production": {
"devServerTarget": "avastar:serve:production"
}
}
},
"lint": {
"builder": "#angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "avastar"
}
If you are like me and wound up here from google.
My error came when I included an Angular Material Component, rather than it's module in app.module.ts
special note: whenever you add a new material module to app.module.ts you must stop (and restart) ng serve or you will get this error.
change this
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
BrowserAnimationsModule,
MatDialog, // <====== this is the error
],
to this
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
BrowserAnimationsModule,
MatDialogModule, // <====== this is the solution
],
This is actually an issue with the angular 9 versions. There are mainly 3 different ways to fix this issue as the angular-cli haven't fixed this yet. (You can view the issue in https://github.com/angular/angular-cli/issues/16873),
Solution 1
Update all the dependencies in your node-modules (This issue can be generated due to incompatibility of some dependency versions)
run npm update in the project terminal to update all dependencies.
Solution 2
If the above solution didn't work add aot= true in angular.json and add "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points" in package.json and then delete node_modules and package lock file and install again.(https://github.com/angular/angular/issues/35788#issuecomment-627514285)
Solution 3
If non of the above worked, it would be a better option to downgrade the angular cli version globally. Because this issue have not been bugging in angular cli version 8 and 7.
ng --version
npm uninstall -g #angular/cli
npm cache clean --force
npm install -g #angular/cli#8.3.8
ng --version
............................................................................................................................................................
Update (30.07.2020)
Some folks have over comed this issue by disabling ivy engine on tsconfig.json file:
"angularCompilerOptions": { "fullTemplateTypeCheck": true, "strictInjectionParameters": true, "enableIvy": false }
Reffer : https://github.com/angular/angular/issues/35788#issuecomment-650550297
I hate these kind of answers but it worked for me, ha.
Using Angular 11 in my project
I deleted the node_modules folder and reinstalled the modules then rebuilt my project in dev and the compiler error went away.
I got the same message, I believe I have a different case with people already answered here ( maybe different from the one who initially asked the question too ).
My case was:
Update some libraries ( as I remember, it was ngx-spinner and ngx-datatables )
Using angular 13.
I believe that makes my case different than the others here is because I am using Angular 13 and updating things which initially was angular 8. Of course, I gradually upgrade the project from 8 to 13.
THE SOLUTION for me was:
Stop the ng serve script
Delete directory node_modules and .angular
Run npm install or yarn install
Execute the ng serve again
Compared to the existing answer here, which is suggesting to delete node_modules only, my solution was to delete .angular directory too. It's supposed to be the cache for Angular project I guess. I assume it because deleting node_modules only doesn't work for me.
As suggested already, make sure you always import the module and not the component!
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SharedModule } from './shared/components/shared.module';
#NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, SharedModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
I imported a component I defined in my SharedModule here by mistake.
This article helped me find the problem.
This issue can be generated due to incompatibility of some dependency versions.
install npm packages
npm i
then rebuild
ng serve
I had similar error using angular 12:
The injectable needs to be compiled using the JIT compiler, but
'#angular/compiler' is not available.
This was the post I was stumbling across, so thought to put an answer here if someone else experience this issue as well.
In my case I had lib compiled with ivy with option "partialy":
"compilationMode": "partial"
Angular app was also compiled in this mode and that was causing the issue. App that uses this lib should be compiled with default option "full".
Try this
// run
npm i
// then
npm audit fix
// and then rebuild
ng serve
In my case I'm facing same problem after upgrade Angular 9 to 10.
In Angular 10 simply remove "postinstall": "ngcc" from package.json and
"angularCompilerOptions": { "enableIvy": true } from tsconfig.app.json.
May be this can help you.
Note:
In Angular cli 9 they Introduce new compiler Ivy and for set up Ivy
compiler in project you can add bellow line in respective files
"postinstall": "ngcc" in package.json
"angularCompilerOptions": { "enableIvy": true } in tsconfig.app.json
"aot": true in angular.json
But With Angular 10 they set default compiler to Ivy. So that need to
remove option 1 and 2
For me, this issue was due to the wrong declaration in the declarations array of the module. I did declare something which was not part of that module.
declarations: [DropDownModule],
imports: [DropDownModule, CommonModule]
This DropDownModule is not a part of the module.
This error generally comes when we don't import any particular module or import any module improperly.
I was also getting same error once and importing BrowserAnimationsModule in a module.ts file worked for me at that time.
First import it like this:
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
Then add the module inside imports array of module.ts file:
#NgModule({
declarations: [NavBarComponent],
imports: [
CommonModule,
MatToolbarModule,
MatIconModule,
BrowserAnimationsModule, //<----------
],
exports:[NavBarComponent]
})
I import an #my/foo from an Nx module into a Cypress test which also exports Angular related code.
Importing individual files `lib/foo/src/lib/foo' instead fixed it.
We ran into this problem due to the angular auto upgrade scripts adding an additional #Injectable() annotation to one of our services. Double check that you have removed the duplicate annotation from any code it produced that may look similar to the following.
import { Injectable } from "../../../../node_modules/#angular/core";
import { Injectable as Injectable_1 } from "#angular/core";
#Injectable()
#Injectable_1()
export class Service {
}
Further, what helped us triage the issue was to comment out module imports for AppModule doing a binary search on what imports cause the issue and which don't until we found the problematic module. Then further binary searching by commenting out the individual services, components and directives of that module until we found the problematic one.
This error can also be thrown if there are any files in the files array in tsconfig.app.json that Aren't modules.
Having a non-module in the tsconfig causes the JIT and AOT compilers to fail on serve or build.
Before:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": ["node"]
},
"files": [
"src/main.ts",
"src/polyfills.ts",
"./src/app/<non-module>.ts", // <-- The culprit
],
"include": ["src/**/*.d.ts"]
}
After
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": ["node"]
},
"files": ["src/main.ts", "src/polyfills.ts"],
"include": ["src/**/*.d.ts"]
}
Simply remove the culprit...
The line "buildOptimizer": true will exclude #angular/compiler from the built result. The line "optimization": true will somehow remove related code of dynamic created component based on JIT compiler, I'm not very clear of this. But the workaround below will fix both of them.
angular.json
# other lines are ignored
{
"projects": {
"app-web": {
"architect": {
"build": {
"options": {
"customWebpackConfig": {
"path": "./webpack.config.js",
"mergeStrategies": {
"module.rules": "append",
"resolve": "append"
},
"replaceDuplicatePlugins": true
}
}
}
}
}
}
}
webpack.config.js
module.exports = (options) => {
if (options.optimization && options.optimization.minimizer && Array.isArray(options.optimization.minimizer)) {
(options.optimization.minimizer).forEach((plugin) => {
if ((plugin.options || {}).terserOptions) {
const terserOptions = (plugin.options || {}).terserOptions;
terserOptions.compress = {
side_effects: false,
};
}
});
}
return {
// other lines are ignored
...options
}
};
However, the size of built result will be increased.
Here are some references you can take a look.
Building a project for production with aot and buildOptimizer set to true throws Angular JIT compilation failed: '#angular/compiler' not loaded! Error
Create dynamic component loading documentation
In my case, I had {{ typeof someValue }} inside a component template, I wrote it quickly to debug something else but it turns out typeof does not work in there, and gives this weird error instead.
i just stop the application and i run it with 'ng serve' and strangely it runs!
I had a similar situation. I coded an Angular 8 app then restarted it after upgrading my Angular cli to v12. I've solved running npm update but then got a new error with flexlayout. I ran npm i -s #angular/flex-layout #angular/cdk and solved my problems
My problem was in app.modules.ts:
import { HttpClientModule, HttpClient } from '#angular/common/http';
I removed HttpClient and it works:
import { HttpClientModule } from '#angular/common/http';
I solved it by exporting the RouterModule from the feature components
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { QuestionsComponent } from './questions/questions.component';
const routes: Routes = [{ path: 'questions', component: QuestionsComponent }];
#NgModule({
imports: [RouterModule, RouterModule.forChild(routes)],
exports: [RouterModule], // this export might be missing
})
export class QuestionsRoutingModule {}
I solved this error simply by running a npm install inside the terminal
Ubuntu 22.04
Nothing above didn't help me. I solved problem in this way:
Delete node_modules and angular cache;
In folder, where node_modules must installing, change umask like this umask 000;
Install packages and run.
In sum up.
Most likely, when packages installing or angular compiling app - ubuntu do permission denied somewhere.
I had the same issue and what fixed it for me was an oversight with #Component.
#Component has to be right above the class its referring to.
screenshot
Just created a new TypeScript Aurelia project using aurelia-cli .
Installed bootstrap and included bootstrap css in the app.ts using import.
import 'bootstrap/dist/css/bootstrap.min.css';
import '../../static/assets/css/app.scss';
import { routes } from './routes';
interface IApp {
message: string;
}
export class App implements IApp{
message = 'Hello World!';
}
Now when I run the test , I get error unexpected token as below
yarn test
# and the output contains
yarn run v1.12.3
$ nps test
nps is executing `test` : nps test.jest
nps is executing `test.jest` : node node_modules/rimraf/bin.js test/coverage-jest && jest
ts-jest[config] (WARN) TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
FAIL test/unit/app.spec.ts
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To hav`enter code here`e 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.
SyntaxError: Unexpected token :
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
at Object.<anonymous> (src/home/app.ts:163:1)
I commented the import bootstrap.css line in app.ts and everything runs fine.
Am I missing some configuration for jest to allow me to use css imports in .ts components?
Here is my jest portion from package.json
"jest": {
"verbose": true,
"roots": [
"<rootDir>/test"
],
"modulePaths": [
"<rootDir>/src",
"<rootDir>/node_modules"
],
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"transform": {
"^.+\\.ts$": "ts-jest"
},
"testRegex": "\\.spec\\.(ts|js)$",
"testPathIgnorePatterns": [
"build",
"dist",
"sample"
],
"setupFiles": [
"<rootDir>/test/jest-pretest.ts"
],
"testEnvironment": "node",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{js,ts}",
"!**/*.spec.{js,ts}",
"!**/node_modules/**",
"!**/test/**"
],
"coverageDirectory": "<rootDir>/test/coverage-jest",
"coverageReporters": [
"json",
"lcov",
"text",
"html",
"clover"
]
},
I was getting the same error. I resolved my issue by changing the module compilerOption in tsconfig.json from "esnext" to "commonjs". Why am I getting “Unexpected token import” on one webpack project but not the other?
I am using Jest and Enzyme to test my application. I am getting error:
FAIL app/containers/Navbar/NavbarContainer.test.js
● Test suite failed to run
app/components/Navbar/styles.css: Unexpected token (1:0)
> 1 | #import "../../styles/base/_variables";
| ^
2 |
3 | .navbar{
4 | width: $navbar-width;
This is my Jest configuration in package.json:
"jest": {
"verbose": true,
"globals": {
"env": {
"isProd": false,
"isDev": true,
"command": "start"
}
},
"moduleNameMapper": {
"\\.(css)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"js",
"jsx",
"json",
"css"
],
"modulePaths": [
"/app"
],
"moduleDirectories": [
"node_modules"
],
"verbose": true,
"setupFiles": [
"./setupJest.js"
],
"setupTestFrameworkScriptFile": "<rootDir>/setupTests.js"
}
I was following the guides while setting up the application, and I found that identity-obj-proxy will help to mock css-modules functionality, but that's not working in my case. Please let me know what am I missing here.
P.S. this is about not ES6 modules import. The suit failed because there is a #import in css.
UPDATE who use create-react-app from feb 2018.
You cannot override the moduleNameMapper in package.json but in jest.config.js it works, unfortunately i havent found any docs about why it does the trick.
So my jest.config.js look like this:
module.exports = {
...,
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(scss|sass|css)$": "identity-obj-proxy"
}
}
and it skips scss files and #import quite well.
I added to devDependencies identity-obj-proxy
Backing my answer i followed jest webpack
So, I've found the solution to this problem. I was importing CSS without the extension in my components and Jest was confusing that import with JS file. Solution is instead of importing css like:
import * as styles from './styles'
you should import it like:
import * as styles from './styles.css'
One quick gotcha that I found with this. If you have a jest.config.js file, then you need to set your moduleNameWrapper inside of that config file.
I know this post is old but i solved this issue by adding jest-transform-css as a devDependency
npm i --save-dev jest-transform-css
and then adding the following inside jest.config.js
transform: {
'^.+\\.js$': 'babel-jest',
'.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css'
}
you can refer to this github issue for more information
I'm adding Jest Testing framework to my React Native project. I'm getting the following error:
Failed to get mock metadata: /Users/me/Documents/Development/project/node_modules/global/window.js
My test file looks like this:
import 'react-native'
import React from 'react'
import { MyComponent } from '../components/MyComponent'
import renderer from 'react-test-renderer'
it('renders correctly', () => {
const tree = renderer.create(<MyComponent />).toJSON()
expect(tree).toMatchSnapshot()
})
And also the Jest configuration in my package.json:
"jest": {
"preset": "jest-react-native",
"testPathIgnorePatterns": ["/node_modules/", "/example/", "/lib/"],
"testRegex": "(/tests/.*|\\.(test|spec))\\.(js|jsx)$",
"automock": "true",
"unmockedModulePathPatterns": [ "lodash" ],
"transformIgnorePatterns": [
"node_modules/(?!#exponent/ex-navigation",
")"
]
}
I had a look over http://facebook.github.io/jest/docs/manual-mocks.html#content as suggested on the error prompted.
I think something is wrong with your jest configuration in package.json.
Here is a sample jest config snippet:
"jest": {
"preset": "react-native",
"cacheDirectory": "./cache",
"coveragePathIgnorePatterns": [
"./app/utils/vendor"
],
"coverageThreshold": {
"global": {
"statements": 80
}
},
"transformIgnorePatterns": [
"/node_modules/(?!react-native|react-clone-referenced-element|react-navigation)"
]
}
preset: The preset is a node environment that mimics the environment of a React Native app. Because it doesn’t load any DOM or browser APIs, it greatly improves Jest’s startup time.
cacheDirectory: It helps you greatly improve the test speed. It does so by creating cache of compiled modules so that next time it doesn’t have to compile the node_modules while running tests.
coveragePathIgnorePatterns: Define the files which want to skip for coverage reports.
coverageThreshold: Defines the threshold limit for all the tests to pass. If the coverage is less than the defined limit, the tests would fail. This helped us to keep a good amount of coverage at all point of time.
transformIgnorePatterns: We pass all the NPM modules here which needs to be transpiled. These modules are basically ES6/7 modules.
PS: I have written a blog on how to setup jest for react-native project. Here is the URL : http://rahulgaba.com/react-native/2017/05/19/Jest-test-suite-with-superpowers.html
Set "automock": "false" in your package.json (automocking with the jest-react-native preset isn't supported)