I'm attempting to use React Storybook in a project that already has an extensive Webpack 2 config. I started the Storybook following the basic steps:
npm i -g #storybook/cli
getstorybook
When I run yarn storybook, it breaks on the JSX of the demo component:
ERROR in ./stories/index.jsx
Module parse failed: /Users/alexanderhadik/project/web/node_modules/#storybook/react/node_modules/babel-loader/lib/index.js??ref--0!/Users/alexanderhadik/project/web/stories/index.jsx Unexpected token (9:55)
You may need an appropriate loader to handle this file type.
| import { Button, Welcome } from '#storybook/react/demo';
|
| storiesOf('Welcome', module).add('to Storybook', () => <Welcome showApp={linkTo('Button')} />);
|
| storiesOf('Button', module)
# ./.storybook/config.js 4:2-23
# multi ./node_modules/#storybook/react/dist/server/config/polyfills.js ./node_modules/#storybook/react/dist/server/config/globals.js ./node_modules/webpack-hot-middleware/client.js?reload=true ./.storybook/config.js
Since I didn't start this project originally using create-react-app - do I need to modify the Storybook webpack config to enable JSX?
This might to be a problem with Storybook not replicating webpack babelrc behaviour exactly.
In my case, I had an empty (just {}) .babelrc file with all the important react/jsx plugins defined in webpack.config.js. Storybook read the .babelrc instead of using the babel settings in webpack.config.js.
Deleting the .babelrc solved that issue.
in my case, i didnt have a .babelrc at all -- i used the entry "babel" in the package.json. when running the storybook in this project, the babel entry wasnt there. i added it and things magically started working.
{
"name": "root",
"private": true,
"devDependencies": {
"#storybook/addon-actions": "^4.1.11",
"#storybook/addon-links": "^4.1.11",
"#storybook/addons": "^4.1.11",
"#storybook/react": "^4.1.11",
...
},
"dependencies": {},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"babel": {
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
}
i hope this helps someone.
Related
I've just used create-react-app to start a new typescript react app and then installed firebase. I ran firebase init, selected the typescript option, enabled es lint and enabled functions.
As soon as I uncommented the boilerplate function code in functions/index.ts, I noticed some warnings in VS Code...
functions/eslintrc.js:
Giving error: "Parsing error: "parserOptions.project" has been set for #typescript-eslint/parser.
The file does not match your project config: .eslintrc.js.
The file must be included in at least one of the projects provided"
functions/tsconfig.json:
functions/src/index.ts:
giving error: "Parsing error: Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.eslint"
functions/package.json:
{
"name": "functions",
"scripts": {
"lint": "eslint --ext .js,.ts .",
"build": "tsc",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "14"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1"
},
"devDependencies": {
"#typescript-eslint/eslint-plugin": "^3.9.1",
"#typescript-eslint/parser": "^3.8.0",
"eslint": "^7.6.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.22.0",
"firebase-functions-test": "^0.2.0",
"typescript": "^3.8.0"
},
"private": true
}
I don't understand these errors. Can someone please help?
Thanks
The first error from TypeScript ESLint is related to not being able to find a project tsconfig.json that matches your functions.
To fix this, we need to tell TypeScript ESLint where the other tsconfig.json is by editing your parserOptions.
.eslintrc.js
// [...]
"parser": "#typescript-eslint/parser",
"parserOptions": {
"project": [
"./tsconfig.json",
"./functions/tsconfig.json",
]
}
// [...]
To fix the parsing issue related to JSX for your React files, you must add the jsx compiler option to your tsconfig.json configurations that include JSX. This will likely be your non-function configuration, and you will most likely need to set it to react-jsx for React v17+ or react in all other cases for Create React App.
tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx"
// [...]
}
// [...]
}
further to the above excellent suggestion by Evelyn Hathaway , and after I installed just the functions with no hosting and I changed the ".eslingrc.js: file
FROM
.eslingrc.js
parserOptions: {
project: ["tsconfig.json",
"tsconfig.dev.json"],
to
.eslingrc.js
parserOptions: {
project: ["./functions/tsconfig.json",
"./functions/tsconfig.dev.json"],
At last the seemed to work after I spent a frustrating day.....
If I use import/export from ES6 then all my Jest tests fail with error:
Unexpected reserved word
I convert my object under test to use old school IIFE syntax and suddenly my tests pass. Or, take an even simpler test case:
var Validation = require('../src/components/validation/validation'); // PASS
//import * as Validation from '../src/components/validation/validation' // FAIL
Same error. Obviously there's a problem with import/export here. It's not practical for me to rewrite my code using ES5 syntax just to make my test framework happy.
I have babel-jest. I tried various suggestions from GitHub issues. It is no go so far.
File package.json
"scripts": {
"start": "webpack-dev-server",
"test": "jest"
},
"jest": {
"testPathDirs": [
"__tests__"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"testFileExtensions": ["es6", "js"],
"moduleFileExtensions": ["js", "json", "es6"]
},
File babelrc
{
"presets": ["es2015", "react"],
"plugins": ["transform-decorators-legacy"]
}
Is there a fix for this?
From my answer to another question, this can be simpler:
The only requirement is to configure your test environment to Babel, and add the ECMAScript 6 transform plugin:
Step 1:
Add your test environment to .babelrc in the root of your project:
{
"env": {
"test": {
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
}
}
Step 2:
Install the ECMAScript 6 transform plugin:
npm install --save-dev #babel/plugin-transform-modules-commonjs
And that's it. Jest will enable compilation from ECMAScript modules to CommonJS automatically, without having to inform additional options to your jest property inside package.json.
UPDATE 2020 - native support of ECMAScript modules (ESM)
According to this issue, there is native support of ESM from jest#25.4.0. So you won't have to use babel anymore. At the time of writing this answer (05/2020), to activate that you need to do three simple things:
Make sure you don't transform away import statements by setting transform: {} in config file
Run node#^12.16.0 || >=13.2.0 with --experimental-vm-modules flag
Run your test with jest-environment-node or jest-environment-jsdom-sixteen.
So your Jest configuration file should contain at least this:
export default {
testEnvironment: 'jest-environment-node',
transform: {}
...
};
And to set --experimental-vm-modules flag, you will have to run Jest as follows:
node --experimental-vm-modules node_modules/jest/bin/jest.js
Also note in the Github issue that this approach does not yet support the jest object. So you may need to import it manually:
import {jest} from '#jest/globals'
(I hope this will change in the future)
For an updated configuration, I'm using https://babeljs.io/setup#installation
Select JEST and be happy:
As a reference, the current configuration:
npm install --save-dev babel-jest
In your package.json file, make the following changes:
{
"scripts": {
"test": "jest"
},
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
}
}
Install babel preset:
npm install #babel/preset-env --save-dev
Create a .babelrc file:
{
"presets": ["#babel/preset-env"]
}
Run your tests:
npm run test
In package.json, kindly set like this one: "test": "node --experimental-vm-modules node_modules/.bin/jest"
Should be good!
It's a matter of adding stage-0 to your .babelrc file. Here is an example:
{
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-decorators-legacy"]
}
I encountered the same issue.
These are what I did:
yarn add --dev babel-jest #babel/core #babel/preset-env
Make file jest.config.js in rootDir.
module.exports = {
moduleFileExtensions: ["js", "json", "jsx", "ts", "tsx", "json"],
transform: {
'^.+\\.(js|jsx)?$': 'babel-jest'
},
testEnvironment: 'node',
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/$1'
},
testMatch: [
'<rootDir>/**/*.test.(js|jsx|ts|tsx)', '<rootDir>/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
],
transformIgnorePatterns: ['<rootDir>/node_modules/']
};
Then make file babal.config.js in rootDir.
Go like this:
module.exports = {
"presets": ["#babel/preset-env"]
}
Below is how I setup jest, typescript and ES Modules for my project.
jest.config.js
/**
* #type {import('ts-jest/dist/types').InitialOptionsTsJest}
* To configure ESM support, see: https://kulshekhar.github.io/ts-jest/docs/guides/esm-support
*
**/
export default {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
extensionsToTreatAsEsm: ['.ts'],
globals: {
'ts-jest': {
useESM: true
}
},
setupFiles: ['<rootDir>/__tests__/setup.ts'],
};
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"outDir": "./dist",
"moduleResolution": "node",
// "strict": true,
"esModuleInterop": true,
"inlineSourceMap": true,
}
}
package.json scripts and devDependencies
"scripts": {
"start": "node ./dist/server.js",
"dev": "tsc-watch --onSuccess \"node ./dist/server.js\"",
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
},
"devDependencies": {
"#jest/globals": "^27.4.4",
"#types/express": "^4.17.13",
"#types/jest": "^27.4.0",
"#types/supertest": "^2.0.11",
"cross-env": "^7.0.3",
"supertest": "^6.2.1",
"ts-jest": "^27.1.3"
}
__tests__/setup.ts
import dotenv from 'dotenv';
dotenv.config({
path: './.env.test'
});
all is explained in the jest docs: jest docs
1.
npm install --save-dev babel-jest #babel/core #babel/preset-env
in file: babel.config.js
module.exports = {
presets: [['#babel/preset-env', {targets: {node: 'current'}}]],
};
In addition to installing babel-jest (which comes with Jest by default now) be sure to install regenerator-runtime.
To add support for React and react-testing-library it may be useful to eject CreateReactApp and take all needed Jest configuration from the package.json. It is ready to use with another bundler, Rollup in my case.
I'm experimenting with yarn workspace monorepo. It is consisting of a TestProject created with create-react-app, and a SharedLib1 which is created with create-react-library. TestProject imports code from SharedLib1. The problem being, TestProject uses react-scripts 3.3.0 which is dependent on babel-jest ^24.9.0, while SharedLib1 uses react-scripts-ts ^2.16.0 which is dependent on babel-jest 22.4.4. When running yarn start in TestProject, it complains:
The react-scripts package provided by Create React App requires a dependency:
"babel-jest": "^24.9.0"
Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-jest was detected higher up in the tree:
/monoRepo/node_modules/babel-jest (version: 22.4.4)
I could disable the error by setting SKIP_PREFLIGHT_CHECK=true in TestProject or manually upgrade the react-scripts inside SharedLib1, but I'd like to know if there's a better way of handling this.
myMonorepo
-web
-SharedLib1
-package.json
-TestProject
-package.json
-package.json
Package.json of myMonoRepo:
{
"name": "my-mono-repo",
"version": "0.1.0",
"private": true,
"workspaces": [
"web/*"
],
"nohoist": [
"**/babel-jest",
"**/babel-jest/**"
]
}
Package.json of myMonoRepo:
{
"name": "test-proj",
"version": "0.1.0",
"private": true,
"dependencies": {
...
"shared-lib-1": "^1.0.0"
}
}
And the test code App.tsx:
import React from 'react';
import TestComp from 'shared-lib-1';
import './App.css';
const App: React.FC = () => {
return (
<div className="App">
<TestComp text={'aaa'}/>
Learn React
</div>
);
}
export default App;
There is a babel-jest 24.9.0 inside the node_modules of TestProj and another 22.4.4 inside the node_modules of myMonoRepo
This is very similar, if not the same, to an issue opened on the GH repo for create-react-app and you may find additional information there.
That said, you might try moving babel-jest to a devDependency instead of a package dependency. If that does not work, you might try Selective dependency resolutions, where you can force your project to a specific version of babel-jest -
"resolutions": {
"babel-jest": "^24.9.0",
"shared-lib-1": "^1.0.0"
}
I am trying to get the tests of a React application that uses decorators and Typescript to work with Create React App v2.1.0
I am aware that decorators are not officially supported.
I can run the application fine thanks to React App Rewired and #babel/plugin-proposal-decorators.
Where I am stuck is to enable decorator support when running the tests.
My npm test script is : "test": "react-app-rewired test --env=jsdom --runInBand"
Tests fails with:
The 'decorators' plugin requires a 'decoratorsBeforeExport' option,
whose value must be a boolean. If you are migrating from Babylon/Babel
6 or want to use the old decorators proposal, you should use the
'decorators-legacy' plugin instead of 'decorators
I have tried to add a .babelrc file with the following :
{
"plugins": [["#babel/plugin-proposal-decorators", { "legacy": true }]]
}
but get hit by:
Cannot use the decorators and decorators-legacy plugin together
👋 I'm a Create React App maintainer.
Decorators are supported if you're using TypeScript and work with tests, no extra configuration required (CRA ^2.1.1, there was a bug in 2.1.0).
Decorators are only unsupported in JavaScript.
First, remove react-app-rewired and switch your scripts back to react-scripts.
Next, remove your .babelrc file.
Finally, convert any files using decorators to be TypeScript files (.tsx). Everything should just work now!
Also, your test script should only read "test": "react-scripts test" or "test": "react-scripts test --runInBand". Passing --env=jsdom is unnecessary as specified in the 2.0 upgrade guide.
#Onlyann take a backup of you current package.json or project.
And try this configuration, it should help you and you can add extra packages afterwards.
// package.json
"#babel/core": "^7.0.0-beta.42",
"#babel/plugin-proposal-class-properties": "^7.0.0-beta.42",
"#babel/plugin-proposal-decorators": "^7.0.0-beta.42",
"#babel/plugin-transform-runtime": "^7.0.0-beta.42",
"#babel/preset-env": "^7.0.0-beta.42",
"#babel/preset-react": "^7.0.0-beta.42",
"#babel/preset-stage-2": "^7.0.0-beta.42",
// .babelrc
{
"presets": [
["#babel/preset-env", { "modules": false }],
"#babel/preset-react",
"#babel/preset-stage-2"
],
"plugins": [
"#babel/plugin-transform-runtime",
"#babel/plugin-proposal-decorators",
["#babel/plugin-proposal-class-properties", { "loose": true }]
],
"env": {
"development": {
"plugins": ["react-hot-loader/babel"]
}
} }
I would like to keep console.log in developer builds, but in production builds I want them removed.
babel-plugin-transform-remove-console
I cannot remember if I installed it as --save or --save-dev (and not quite sure the difference). I also do not know how to check how it was installed, but it is in my node_modules directory as babel-plugin-transform-remove-console.
Whether I use npm run dev or npm run build to build my project I still see the console.log statements. I would have expected the npm run build command to remove the console.log files.
My .babelrc file looks like this:
{
"presets" : ["env", "stage-0", "react"],
"env" : {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
The pertinent parts of my package.json look like this:
"scripts": {
"dev": "webpack -d --watch",
"build": "webpack -p"
},
...
"dependencies": {
...
"babel-plugin-transform-remove-console": "^6.9.2",
...
}
Why is the npm run build not removing console.log statements for me?
-p is a flag for Webpack itself. Babel doesn't know anything about it. If you want your Webpack config to toggle behavior based on it, you'd need to do that yourself.
// webpack.config.js
module.exports = function(env) {
return {
// ...
module: {
rules: [{
loader: "babel-loader",
options: {
forceEnv: env.production ? "production" : "development"
}
}],
},
},
};
I cannot remember if I installed it as --save or --save-dev (and not quite sure the difference).
Just look at your package.json file.
-- save will make your package appear in dependencies (this is the default behaviour if no option was provided)
-- save-dev will make your package appear in devDependencies
https://docs.npmjs.com/cli/install
When you use run webpack -p, webpack sets process.env.NODE_ENV = "production", but Babel expects process.env.BABEL_ENV = "production".