trying to setup jest to work with css decorators.
The css file linked to my react component has:
#import './another.css'
Now, when I run jest I get:
SyntaxError: /Users/thiagofacchini/Documents/atomix/src/library/atoms/Label/styles.css: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (2:1):
Then I went to my .babelrc and added:
"env": {
"test": {
"plugins": [
"#babel/plugin-proposal-decorators", { "legacy": true },
]
}
Running jest again I get
[BABEL] /Users/thiagofacchini/Documents/atomix/src/library/protons/Animator/tests/index.test.js: The decorators plugin requires a 'decoratorsBeforeExport' option, whose value must be a boolean. If you want to use the legacy decorators semantics, you can set the 'legacy: true' option.
(While
processing:/Users/thiagofacchini/Documents/atomix/node_modules/#babel/plugin-proposal-decorators/lib/index.js")
Also tried to change my .babelrc to:
"env": {
"test": {
"plugins": [
"#babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true ,"legacy": true },
]
}
}
But get exactly the same error.
My package.json looks like:
"#babel/core": "^7.3.4",
"#babel/plugin-proposal-decorators": "^7.3.0",
"#babel/preset-env": "^7.3.4",
"#babel/preset-flow": "^7.0.0",
"#babel/preset-react": "^7.0.0",
"#logux/eslint-config": "^27.0.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.5",
NOTE: The error is just happening on JEST, my development build works fine.
I googled the hell but I simply cannot understand what's going on. Maybe something with versions? I'd appreciate any help.
When you run your app in development build the build process is taken care of by webpack/parcel/whichever tool you're using.
These tools allow you to (via the use of plugins) do thing like import css into javascript and then eventually spit it back out as css at the appropriate time. This is not a native feature of javascript.
Jest runs on node js which doesn't have all of the features of webpack and cannot parse raw css etc.
So when you had the error "SyntaxError: /Users/thiagofacchini/Documents/atomix/src/library/atoms/Label/styles.css: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (2:1):"
this is actually nodejs trying to parse the css as javascript! You can read more about what it though you were doing here https://www.sitepoint.com/javascript-decorators-what-they-are/
So how do you manage css in your jest environment?
in your jest configuration you set it up so that you don't import the css and instead you import a blank module.
first npm install identity-obj-proxy
then add the following to your jest.config.js
moduleNameMapper: {
"\\.css$": "identity-obj-proxy",
"^lodash-es$": "lodash"
},
Related
Context: I'm somewhat new to web development; I started about 2-3 weeks ago and jumped right into the MERN stack to understand the bigger picture of how everything works together. And as I encountered problems or questions, I gradually filled in knowledge gaps. After researching how to get started, I noticed that many tutorials used create-react-app, which I looked into and discovered that many discouraged its use. So I decided to use Webpack and Babel to set up React myself. I know it's recommended for beginners to use create-react-app, but I don't want to use it; I don't want to get into the habit of using create-react-app.
My first question is: how do Next.JS, Gatsby, and Vite set up a React project? The videos I came across recommended using one of those instead of create-react-app. I used Webpack and Babel instead because I had a resource available (Pro MERN Stack: Full Stack Web App Development with Mongo, Express, React, and Node) that used these instead of Next.JS, Gatsby, and Vite. I didn't want to get into the details of how Next.JS, Gatsby, and Vite worked with the MERN stack because it would make me indecisive on which path to follow.
The second (and related) question is: what is the difference between a Webpack/Babel react project setup and a Next.JS, Gatsby, or Vite setup?
Third question related to Webpack and Babel setup,
import { join } from 'path';
import HtmlWebpackPlugin from 'html-webpack-plugin';
module.exports = {
entry: './src/index.jsx',
output: {
path: './dist',
filename: 'app.bundle.js'
},
module: {
rules: [
{
test:/\.js$/,
use:'babel-loader',
exclude:/node_modules/
},
{
test:/\.jsx$/,
use:'babel-loader',
exclude:/node_modules/
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html'
})
]
};
I want my entry point to be a .jsx file instead of a .js file, so I used a babel-loader, but the setup isn't working.
{
"name": "reactsetup",
"version": "1.0.0",
"description": "",
"main": "index.jsx",
"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"#babel/core": "^7.20.12",
"#babel/preset-env": "^7.20.2",
"#babel/preset-react": "^7.18.6",
"babel-core": "^6.26.3",
"babel-loader": "^9.1.2",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
},
"browserslist": [
">0.3%",
"defaults",
"supports es6-module",
"maintained node versions"
]
}
My package.json file includes Babel-loader version 9.1.2.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
This is what my index.jsx file looks like for now. I'm not sure if this file must be a .jsx file, but I want to be able to set up the entry point as a .jsx file anyway since the book I'm using as a reference uses a .jsx file as its entry point. This is the webpack.config.js file of the book tutorial, (https://github.com/vasansr/pro-mern-stack/blob/master/webpack.config.js). I'm not 100% following the book; I'm just following sections as I need to learn them. Maybe my inconsistency in following the tutorial is why I'm struggling here.
This is what my .bablerc file looks like.
{ "presets": ["#babel/preset-env", "#babel/preset-react"] }
My error:
**Compiled with problems:
ERROR
Module not found: Error: Can't resolve './src/index.js' in
I was expecting the Babel loader to allow Webpack to figure out how to load .jsx files, but that's not how it went.
EDIT: My problem is solved. I followed this article (https://dev.to/alexeagleson/understanding-the-modern-web-stack-webpack-devserver-react-typescript-4b9b) which got rid of my original error. After which another error popped up:
Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
configuration.output.path: The provided value "./dist" is not an absolute path!
-> The output directory as absolute path (required).
To solve this, I changed the output path to:
path: path.resolve(__dirname, 'dist'),
After this, I got another error
Error: For the selected environment is no default script chunk format available:
JSONP Array push can be chosen when 'document' or 'importScripts' is available.
CommonJs exports can be chosen when 'require' or node builtins are available.
Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly.
To solve this, I removed
"maintained node versions"
from my package.json file in the "browserslist" folder.
I'm typing this in case anyone comes across any of these problems.
Please disregard my third question; I'd appreciate it if you could answer my first two. Thank you ahead of time.
I use #testing-library/react-native to test my RN app. When I run yarn test, following error occurs.
#testing-library/react-native should have "jest-preset.js" or "jest-preset.json" file at the root.
I use typescript for my app.
my test script is like this.
test": "jest --config jest.config.json"
jest.config.json file is like this.
{
"preset": "#testing-library/react-native",
"collectCoverageFrom": ["src/**/*.{ts,tsx}"],
"moduleDirectories": ["node_modules", "src"],
"setupFiles": [
"<rootDir>/jestSetup/setup.js",
"./node_modules/react-native-gesture-handler/jestSetup.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?(react-native|#?react-navigation|#react-native-community))"
],
"coveragePathIgnorePatterns": ["/node_modules/", "/jestSetup", "/src/config.ts", "/src/app.tsx"]
}
Why am I getting this error?
I'm using expo and after updates from 38 to 39, Jest stopped working. I had same issues — it was complaining about missing preset js files.
Preset below didn't work for me:
"preset": "#testing-library/react-native",
So I have changed jest.config.js like this:
module.exports = {
clearMocks: true,
coverageDirectory: 'coverage',
testEnvironment: 'node',
preset: './node_modules/jest-expo/jest-preset.js',
}
Changed preset file location to expo's one which im using and it did the work
The preset no longer exists in >=7.0.0 "#testing-library/react-native". According to the documentation it seems "react-native" should be used as the preset.
"preset": "react-native",
V7 upgrade documentation reference
For those seeing this in a fully up to date project, the missing file is [./node_modules/]react-native/jest-preset.js and you need to make sure that react-native itself is installed.
This will happen if you don't have react-native install globally.
yarn add react-native (or do it globally)
so in package.json you should see something like:
"react-native": "0.66.3",
In process of upgrading a webpack 4/storybook 5 project to webpack 5 to hopefully take advantage of federated modules. I have regular webpack --config webpack.config.js building working atfer some struggle, but I can't seem to overcome this storybook config issue to get that working. there's not a lot in the storybook webpack.config.js - just some module rules for testing for less files and using the appropriate loaders. It seems the error I'm encountering is typical when upgrading webpack majors, as I've found a number of folks that encountered the same thing going from 3-4, but anything I've tried has failed so far. The specific stacktrace is:
Cannot read property 'tapAsync' of undefined
at ExternalModuleFactoryPlugin.apply (/Users/tbullard/Workspace/unify/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js:29:39)
at compiler.hooks.compile.tap (/Users/tbullard/Workspace/unify/node_modules/webpack/lib/ExternalsPlugin.js:24:63)
at SyncHook.eval [as call] (eval at create (/Users/tbullard/Workspace/unify/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
at SyncHook.lazyCompileHook (/Users/tbullard/Workspace/unify/node_modules/tapable/lib/Hook.js:154:20)
at hooks.beforeCompile.callAsync.err (/Users/tbullard/Workspace/unify/node_modules/#storybook/core/node_modules/webpack/lib/Compiler.js:665:23)
at _err0 (eval at create (/Users/tbullard/Workspace/unify/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:11:1)
at compiler.inputFileSystem.readFile (/Users/tbullard/Workspace/unify/node_modules/#storybook/core/node_modules/webpack/lib/DllReferencePlugin.js:72:15)
at process.nextTick (/Users/tbullard/Workspace/unify/node_modules/#storybook/core/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:85:15)
at process._tickCallback (internal/process/next_tick.js:61:11)
Leads me to believe there's a plugin incompatibility 🤷🏻♂️ TIA!
As of 6.2.0, Storybook's preview builder is officially Webpack 5 compatible and the manager builder is unofficially Webpack 5 compatible. See this explanation of the builders and Webpack 5 compatibility. Also check out this gist/comments section with more detailed installation instructions.
If I understand correctly, setting the builder to Webpack 5 (as per these instructions) will force the preview builder to use Webpack 5, allowing you to expose your UI components for cool, new Webpack 5 features such as module federation.
However, if you also want to force the manager builder to use Webpack 5 (so that you can just finish breaking up with Webpack 4), you'll need to make use of Yarn selective dependency resolutions. Here is what I did specifically (in a package.json):
"resolutions": {
"webpack": "^5.27.2",
"css-loader": "^5.0.1",
"dotenv-webpack": "^7.0.2",
"html-webpack-plugin": "^5.0.0",
"style-loader": "^2.0.0",
"terser-webpack-plugin": "^5.1.1",
"webpack-dev-middleware": "^4.1.0",
"webpack-virtual-modules": "^0.4.2"
}
With these resolutions, Yarn detects that Webpack 4 is no longer used and removes it. The SB build gives this warning:
info #storybook/react v6.2.0-rc.10
info
info => Loading presets
WARN Unexpected webpack version in manager-builder
WARN - Received: 5.27.2
WARN - Expected: 4.x
One of the tasks of migrating from Webpack 4 to 5 involves manually providing browser polyfills for node packages which were automatically provided by Webpack 4. I want to note that if you find yourself manually providing a ton of polyfills while upgrading Storybook to Webpack 5, you have probably gotten off in the wrong direction. The Storybook dev-server builds get cached in a local (to the package where Storybook is installed) node_modules directory (whatever-package/node_modules/.cache/storybook/dev-server). Deleting the dev-server sub-directory regularly can help you debug your build and potentially spare you from building out long lists of unnecessary node polyfills. (I learned this the hard way).
With that said, for a cleanish install of Storybook you might not actually need any polyfills. On the other hand, some cases do require the node polyfills (e.g. #storybook/addon-docs requires "assert" (see below)). Here is one way to add polyfills (and addons, if you want) to Storybook's Webpack config in main.js:
module.exports = {
core: {
builder: 'webpack5',
},
stories: ['../whatever/src/**/*.stories.#(ts|tsx)'],
addons: [
'#storybook/addon-actions',
'#storybook/addon-controls',
'#storybook/addon-docs',
],
webpackFinal: (config) => {
return {
...config,
resolve: {
...config.resolve,
fallback: {
...config.fallback,
assert: require.resolve('assert-browserify/'),
},
},
};
},
};
Re: addons, I had serious issues with node polyfills when attempting to use addon-essentials. I've been... adding... addons piecemeal instead (standalone packages via npm), and that seems to be working without any polyfills (#storybook/actions and #storybook/controls are good oob; #storybook/docs requires the assert polyfill (above), #storybook/addons is also working fine with theming in manager.ts---that is:
import { addons } from '#storybook/addons';
import { themes } from '#storybook/theming';
addons.setConfig({
theme: themes.dark,
});
I also want to note that adding sass-loader to Webpack config.module.rules works as expected. Some people were running into problems with some scss preset with Storybook and Webpack 5. Here's the relevant portion of a proper Storybook Webpack config for Sass:
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.(scss)$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: function () {
return [require('precss'), require('autoprefixer')];
},
},
},
},
{
loader: require.resolve('sass-loader'),
options: {
// using sass (Dart) instead of node-sass because node-sass (Javascript) cannot resolve Yarn 2's Plug'N'Play synthetic node_modules directory
// Evidently, sass is a bit slower to compile than node-sass, but I think I prefer sass anyway for latest features (such as #use)
implementation: require('sass'),
},
},
],
},
],
},
Hope that will get you off the ground 🛫
Storybook is not yet ready to work with Webpack 5 but it is on their roadmap for version 7.0.
More context in this GitHub issue.
Upgrading webpack v4 to v5 in storybook v6.
check the below link for detailed explanation.
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#webpack-5
"#storybook/builder-webpack5": "^6.5.15",
"#storybook/manager-webpack5": "^6.5.15",
It happened to me as well, in the end I solved it setting the dependency for storybook webpack5 but using webpack4:
"#storybook/addon-actions": "^6.2.9",
"#storybook/addon-controls": "^6.2.9",
"#storybook/addon-storysource": "^6.2.9",
"#storybook/builder-webpack5": "^6.2.9",
"#storybook/vue": "^6.2.9",
As I read here: https://stackoverflow.com/a/67075112/5384339 I think it's better to wait a bit before using webpack5
Trying to use decorators in my React project, and even though I have installed the babel plugin that enables them, and referenced the plugin in .babelrc, I'm still getting a syntax error in my console.
package.json
// ...
"devDependencies": {
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-object-rest-spread": "^6.16.0",
"chai": "^3.5.0",
"file-loader": "^0.9.0",
"url-loader": "^0.5.7"
}
// ...
.babelrc - I previously had the transform-object-rest-spread plugin installed, so have just extended the plugins array:
{
"plugins": ["transform-object-rest-spread", "transform-decorators-legacy"]
}
And the console error, in full (just in case):
BabelLoaderError: SyntaxError: Decorators are not officially supported yet in 6.x pending a proposal update.
However, if you need to use them you can install the legacy decorators transform with:
npm install babel-plugin-transform-decorators-legacy --save-dev
and add the following line to your .babelrc file:
{
"plugins": ["transform-decorators-legacy"]
}
The repo url is: https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy.
What am I missing?
I had included the plugin in .babelrc but not webpack.config.js (as azium pointed out).
When I included this, it worked:
// ...
query: {
plugins: [ 'transform-decorators-legacy' ]
}
// ...
Hope that helps in case anyone else runs into this problem :)
I'm new to javascript and javascript build scripts, and I'm trying to build a "future-proof" build script for building a ReactJS/Redux app. I'm having trouble with getting imports to work between javascript files.
My question is what is the recommended approach to add support for es2016-style import statements?
As I've been trying to get this working, these are the questions and comments that are rolling around in my head that help color where I'm coming from.
I've just been getting a little more comfortable with Gulp. Is it possible to use just Gulp, Babel, and npm to add support for es2016-style import statements?
I'm wondering if Gulp still the recommended way to go for building javascript bundles, or should I learn WebPack instead.
In the past, I've used to use Browserify for including other javascript files, but I've heard people mention that you can do what Browserify does with pure npm and that Browserify may be falling out of favor.
I've noticed a lot of ReactJS examples using WebPack. I'm not sure where WebPack fits in or if it's necessary. I'm wondering if WebPack takes the place of Browserify and if I need WebPack or if I can do without it.
I'd prefer to use whatever import syntax is the recommended. I believe that Browserify uses require() and es2015 syntax uses "import ... from". I'm wondering if the "import ... from" is the recommended syntax to use for imports now or if I should be using something else.
I've been trying to use Babel 6 to use es2015-style code. I've noticed that it doesn't pre-process the import statements and I think I read somewhere that Babel 6 removed support for import statements. I'm wondering what to use in place of that to pre-process import statements.
I'd be interested in minimizing the amount of configuration (dot files and such) to build a basic project.
Below is a simple example that I've been trying to get working, using Gulp. Currently, when Gulp runs, is creates a bundle, but the import statement doesn't seem to work. When I try to load index.html, everything looks concated together and I get javascript errors.
more package.json
{
"name": "test_jsx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-cli": "^6.14.0",
"babel-plugin-transform-react-jsx": "^6.8.0"
},
"devDependencies": {
"babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-cli": "^1.2.2",
"gulp-concat": "^2.6.0",
"gulp-print": "^2.0.1",
"gulp-sourcemaps": "^1.6.0"
}
}
more gulpfile.js
var gulp = require("gulp");
var print = require('gulp-print');
var sourcemaps = require("gulp-sourcemaps");
var babel = require("gulp-babel");
var concat = require("gulp-concat");
const paths = {
src: 'src/**/*js',
dest: 'build'
}
gulp.task("default", function () {
return gulp.src(paths.src)
.pipe(print())
.pipe(sourcemaps.init())
.pipe(babel({ presets: ['react', 'es2015', ]}))
.pipe(concat("bundle.js"))
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("dist"));
});
more src/test.js
// This import statement is what I'm trying to get working.
import { square } from './lib';
var profile = <div>
<img src="avatar.png" className="profile" />
<h3>{[user.firstName, user.lastName].join(' ')}</h3>
</div>;
more src/lib.js
// This is just a example function that I want to try to import
export function square(x) {
return x * x;
}
more index.html
<script src="dist/bundle.js"></script>
TEST
Build steps
npm install
./node_modules/.bin/gulp
You can use either webpack or browserify to build your bundle, but they'll both be leveraging babel to provide ES6 support. I am not sure where you read that Babel 6 removed the import statement - I use Babel 6 and have had no such issue. You can build the bundle with gulp too but I find it's more work and tends to be harder to maintain. But, you might be getting a lot of opinionated answers here.
There is a tool that was provided by Facebook recently to bootstrap a React app without having to configure build tools: Create React App. You might want to either try that or one of the available boilerplate starters on Github, unless you like tinkering with build scripts. It's less flexible but if you are looking to reduce the amount of configuration it does the job.