How to compile React JS code using Craco? - reactjs

I created a React JS app using the npm create-react-app command.
In this project, I wanted to use Tailwind CSS so I installed and used Craco as showed in the Tailwind Setup Documentation.
But since then my js code doesn't compile at all.
I would like to know how to fix this problem and associate a compiler to Craco for my js code such as babel.
Here are my scripts set in package.json:
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
This is my craco.config.js file:
module.exports = {
style: {
postcss: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
}

Try with this
module.exports = {
style: {
postcss: {
plugins: [require('tailwindcss'), require('autoprefixer')],
},
},
webpack: {
configure: {
module: {
rules: [
{
type: 'javascript/auto',
test: /\.woff2$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
},
},
],
},
],
},
},
},
};

Related

Add cypress code coverage to react project created without cra

I have React project created without cra. I need to add code coverage for cypress e2e tests.
In app created with cra I do the following instructions for add code coverage. And add this line of code in package.json
"start": "react-scripts -r #cypress/instrument-cra start",
This work's well with cra.
But in app without cra I can't add react-scripts or #cypress/instrument-cra for get code coverage information.
How to realize this?
My current configuration ->
babel.config.json
{
"presets": [
"#babel/preset-env",
[
"#babel/preset-react",
{
"runtime": "automatic"
}
],
"#babel/preset-typescript"
],
"plugins": [
"istanbul",
"transform-class-properties",
[
"#babel/plugin-transform-runtime",
{
"useESModules": true,
"regenerator": false
}
]
],
"env": {
"development": {
"plugins": ["istanbul", "transform-class-properties"]
},
"test": {
"presets": [
["#babel/preset-env", {
"targets": "current node"
}]
]
}
}
}
e2e.ts
// Import commands.js using ES2015 syntax:
import "#cypress/code-coverage/support";
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
Cypress.on('uncaught:exception', () => {
/**
* Returning false here prevents Cypress from
* failing the test when one of requests fails
*/
return false
});
package.json
"scripts": {
"start": "webpack-cli serve --port 9007 --env currentEnv=local",
"build": "webpack --mode production",
"serve": "serve dist -p xxxx",
"clean": "rm -rf dist",
"test": "cross-env BABEL_ENV=test jest",
"cy:open": "cypress open",
"cy:run": "cypress run",
"pretest:e2e:run": "npm run build",
"test:e2e:run": "start-server-and-test start http://localhost:9000 cy:run",
"test:e2e:dev": "start-server-and-test start http://localhost:9000 cy:open",
"watch-tests": "cross-env BABEL_ENV=test jest --watch",
"check:coverage": "nyc report --reporter=text-summary --check-coverage",
"prepare": "husky install"
},
// ...
"nyc": {
"all": true,
"excludeAfterRemap": true,
"check-coverage": true,
"extension": [
".tsx"
],
"include": [
"src/views/**/*.tsx"
]
}
cypress.config.ts
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here,
require("#cypress/code-coverage/task")(on, config);
// include any other plugin code...
// It's IMPORTANT to return the config object
// with any changed environment variables
return config;
},
video: false,
baseUrl: "http://localhost:3000/",
},
});
Currently, in browser after each test does finished I get the following error
Could not find any coverage information in your application by looking at the window coverage object. Did you forget to instrument your application? See code-coverage#instrument-your-application [#cypress/code-coverage]

How to enable import assertions for Babel?

In my React app I want to use import assertion:
import data from "./json/clients-m.json" assert { type: "json" }
However, I get the following error:
ERROR in ./src/Clients.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: E:\src\Clients.js: Support for the experimental syntax 'importAssertions' isn't currently enabled.
Add #babel/plugin-syntax-import-assertions (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-import-assertions) to the 'plugins' section of your Babel config to enable parsing.
Line 1:41: Parsing error: This experimental syntax requires enabling the parser plugin: "importAssertions". (1:41)
I have installed this plugin:
npm install #babel/plugin-syntax-import-assertions --save-dev
Then I created .babelrc.json:
{
"plugins": [
"#babel/plugin-syntax-import-assertions"
]
}
And also added this plugin into package.json:
{
"name": "clients-frontend",
"version": "0.1.0",
"private": true,
"babel": {
"plugins": [
"#babel/plugin-syntax-import-assertions"
]
},
"dependencies": {
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^13.1.1",
"#testing-library/user-event": "^13.5.0",
"bootstrap": "^5.1.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"devDependencies": {
"#babel/plugin-syntax-import-assertions": "^7.16.7"
}
}
However, I keep getting this error. 😐
react-scripts doesn't load babel configuration by default. Install the following packages
npm i -D customize-cra react-app-rewired
These packages let you customize react-scripts's default configuration for babel so you can use additional plugins
Now, change the scripts in your package.json
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test"
}
Create a file config-overrides.js at the root of your app with the following content
/* config-overrides.js */
/* eslint-disable react-hooks/rules-of-hooks */
const { useBabelRc, override } = require('customize-cra');
module.exports = override(useBabelRc());
Now, create .babelrc at the root of your package
{
"plugins": [
"#babel/plugin-syntax-import-assertions"
]
}
Now, your babel configuration will be loaded correctly. There's another library craco that lets you customize the react-scripts configuration
Try installing the babel-eslint package as well. And, in your .eslintrc.json file add:
{
"parserOptions": {
"babelOptions": {
"parserOpts": {
"plugins": ["importAssertions"]
}
}
}
}
npm install #babel/plugin-syntax-import-assertions --save-dev
babel.config.cjs
module.exports = function (api) {
api.cache(true);
let presets = [];
let plugins = [];
switch (process.env['NODE_ENV']) {
case 'test':
presets = [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
];
plugins = [
'babel-plugin-transform-import-meta',
'#babel/plugin-proposal-export-default-from',
'#babel/plugin-syntax-import-assertions'
];
break;
default:
presets = [
[
'#babel/preset-env',
{
modules: false, //Setting this to false will preserve ES services
targets: {
node: 'current',
},
},
],
];
plugins = ['#babel/plugin-syntax-import-assertions'];
break;
}
return {
presets,
plugins,
};
};
If you (like me) use an ejected react-script app, maybe you need to set your configuration in webpack.config.js in the application-scope babel-loader:
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve('babel-preset-react-app/webpack-overrides',),
presets: [/* ... */],
plugins: [ // ADD THIS 👇
require.resolve('#babel/plugin-syntax-import-assertions'),
[require.resolve('babel-plugin-direct-import'), {
modules: [
require.resolve('#mui/material'),
require.resolve('#mui/icons-material'),
require.resolve('#mui/lab'),
require.resolve('#mui/base'),
require.resolve('#mui/system'),
],
}],
isEnvDevelopment && shouldUseReactRefresh && require.resolve('react-refresh/babel'),
].filter(Boolean),
// ...
},
},
But NOT here:
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.(js|mjs)$/,
exclude: /#babel(?:\/|\\{1,2})runtime/,
// ...

electron-builder built app doesn't run after build, but works before

I have a project which uses both electron-packager and electron-builder. When I run npm run packaged it is packaged up as .app file into the builds/ folder and there is no issue running the app. When I run npm run build or npm run build:mac, electron-builder successfully builds, signs and creates a .dmg and a .zip file as well as the .app file into the dist/ folder, however the .app file doesn't run as it appears that the src has not compiled correctly and files are missing. I'm sure I'm over looking something in my config but have hit a roadblock.
Here is my package.json:
{
"name": "my-electron-app",
"productName": "ACME Electron",
"version": "0.1.0",
"license": "MIT",
"main": "mainprocess/main.js",
"scripts": {
"start": "react-scripts start",
"clean:build": "rimraf builds",
"clean:dist": "rimraf dist",
"tes": "rimraf archive/tunnel-utils-darwin-x64",
"testDev": "cross-env NODE_ENV=development electron .",
"testProd": "cross-env NODE_ENV=production electron . --noDevServer",
"dev": "webpack-dev-server --progress --hot --host 0.0.0.0 --config=./webpack.dev.config.js",
"build": "npm run clean:dist && webpack --progress --config webpack.build.config.js",
"package": "cross-env NODE_ENV=production npm run clean:dist && webpack --config webpack.build.config.js",
"postpackage": "cross-env NODE_ENV=production npm run clean:build && electron-packager . ${npm_package_productName} --overwrite --icon=assets/icons/mac/icon.icns --prune=true --ignore='(.circleci|archive|assets|build|builds|signing|scaffold|src)' --asar.unpackDir=node_modules/ngrok/* --out=builds",
"package-mac": "cross-env NODE_ENV=production electron-packager . ${npm_package_productName} --overwrite --platform=darwin --arch=x64 --icon=assets/icons/mac/icon.icns --prune=true --ignore='(.circleci|archive|assets|build|builds|signing|scaffold|src)' --asar.unpackDir=node_modules/ngrok/* --out=builds",
"package-win": "cross-env NODE_ENV=production electron-packager . ${npm_package_productName} --overwrite --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --asar.unpackDir=node_modules/ngrok/* --out=builds --version-string.CompanyName=ACME --version-string.FileDescription=ACME --version-string.ProductName=\"My App\"",
"package-linux": "cross-env NODE_ENV=production electron-packager . ${npm_package_productName} --overwrite --platform=linux --arch=x64 --icon=assets/icons/png/icon.png --prune=true --ignore='(scaffold|src|builds|archive)' --asar.unpackDir=node_modules/ngrok/* --out=builds",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"build-bak": "run-os",
"build:win32": "electron-builder --win",
"build:darwin": "electron-builder --mac",
"clean": "rimraf ./dist",
"release": "electron-builder --publish always",
"postinstall": "electron-builder install-app-deps"
},
"build": {
"appId": "com.acme.app",
"productName": "ACME Electron",
"files": [
"**/*",
"builds/Release/*",
"assets/icons/*.*",
"assets/icons/mac/*.*",
"assets/icons/png/*.*",
"assets/icons/win/*.*"
],
"mac": {
"category": "public.build.automation",
"icon": "assets/icons/mac/icon.icns"
},
"dmg": {
"contents": [
{
"x": 110,
"y": 150
},
{
"x": 440,
"y": 150,
"type": "link",
"path": "/Applications"
}
],
"artifactName": "acme-app-${version}.${ext}"
},
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
},
{
"target": "portable"
}
],
"icon": "assets/icons/win/icon.ico"
},
"nsis": {
"runAfterFinish": true,
"installerIcon": "assets/icons/win/icon.ico",
"artifactName": "acme-app-${version}.${ext}"
},
"portable": {
"artifactName": "acme-app.exe"
},
"appx": {
"applicationId": "acme.app",
"backgroundColor": "#000000",
"identityName": "acme.app",
"publisherDisplayName": "nolandubeau",
"artifactName": "acme-app-${version}.${ext}"
},
"publish": [
{
"provider": "github",
"releaseType": "release"
}
]
},
"dependencies": {
...
},
"devDependencies": {
...
}
}
And here is my webpack.build.config.js:
const webpack = require('webpack');
const path = require('path');
//const BabiliPlugin = require('babili-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
// Config directories
const SRC_DIR = path.resolve(__dirname, 'src');
const OUTPUT_DIR = path.resolve(__dirname, 'dist');
// Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up
const defaultInclude = [ SRC_DIR ];
module.exports = {
entry: SRC_DIR + '/index.js',
output: {
path: OUTPUT_DIR,
publicPath: './',
filename: 'bundle.js'
},
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.json$/, loader: "json-loader" },
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
}),
include: defaultInclude
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/react'],
plugins: ['#babel/proposal-class-properties', '#babel/plugin-proposal-object-rest-spread', '#babel/plugin-syntax-dynamic-import']
}
}
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }
],
include: defaultInclude
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/, use: [
{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }
],
include: defaultInclude
}
]
},
target: 'electron-renderer',
plugins: [
new HtmlWebpackPlugin({title: 'CaptureCloud Remote'}),
new ExtractTextPlugin("bundle.css"),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.LoaderOptionsPlugin({
debug: false,
optimization: {
minimizer: [
new UglifyJsPlugin({
sourceMap: true,
}),
],
}
})
//new BabiliPlugin()
],
stats: {
colors: true,
children: false,
chunks: false,
modules: false
}
};

How to use webpack with antd

I try to customize a theme of antd with webpack.config.js, but I don't understand how it works. I want to customize the CSS with less-loader.
I follow this link
I have a `webpack.config.js :
module.exports = {
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
options: {
lessOptions: { // If you are using less-loader#5 please spread the lessOptions to options directly
modifyVars: {
'font-size-base': '140px'
},
javascriptEnabled: true,
},
},
}],
}],
}
But the font size base doesn't change anyway.
Note: I develop a React application with TypeScript.
npm install craco-less --save
in my package.json (for craco less add this):
{
"dependencies": {
"#craco/craco": "^5.6.4",
"craco-less": "^1.17.0"
},
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "craco eject"
},
"devDependencies": {
"less": "^4.0.0",
"less-loader": "^7.2.1"
}
}
At the root of the project i had a craco.config.js :
const CracoLessPlugin = require('craco-less');
module.exports = {
plugins: [
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: { '#primary-color': 'rgba(0, 0, 0, 0.87);' },
javascriptEnabled: true,
},
},
},
},
],
};
If you want to modify the theme indicate the modification in modifyVars
Vars of antd : https://ant.design/docs/react/customize-theme#Ant-Design-Less-variables
And in my react component i had :
import './competenceGrid.less';
The competenceGrid.less :
#import '~antd/dist/antd.less';
/*some css*/
}

Webpack 4.8 and Babel 7 don't work after compiling in production

After compiling SPA (React) to production with NODE_ENV=production there is error:
n.e(...).then(...).config is not a function
n - Promise in UglifyJS
This is package.json
"scripts": {
"dev": "webpack-dev-server --mode development --colors",
"start": "cross-env NODE_ENV=production webpack-dev-server --mode production --env.NODE_ENV=production --colors",
"build": "cross-env NODE_ENV=production webpack --mode production --env.NODE_ENV=production --colors --optimize-minimize",
"test": "test",
"analyze:build": "cross-env ANALYZE=true npm run build",
"analyze:start": "cross-env ANALYZE=true npm run start",
"analyze:dev": "cross-env ANALYZE=true npm run dev"
},
.babelrc
{
"presets": [
["#babel/preset-env", {
"targets": {
"browsers": "last 2 versions"
}
}],
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-transform-runtime",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-proposal-class-properties",
"react-hot-loader/babel"
]
}
webapack.config.js
entry: {
app: [
'./index.js'
],
core: [
'react',
'react-dom',
'core-js',
'react-router',
'redux',
'react-redux'
]
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: 'core',
name: 'core',
chunks: 'initial'
},
async: {
test: /[\\/]node_modules[\\/]/,
chunks: 'async',
priority: -10
},
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: 'initial',
priority: -20
}
}
}
},
dont know what im doing wrong =(
i was trying and with #babel/polyfill - same
screenshot of error
Some libraries are not supported latest webpack.
Problem with with support .mjs files. So when you downgrade to version 3.x problem should be solved

Resources