Removing log statements in Create React App without ejecting - create-react-app

I use lots of console.log() statements while developing Apps (and I mean LOTS). How exactly can I remove them without "ejecting" from a
Create React App
What I considered but not sure how exactly to implement:
In my package.json:
"build": "react-scripts build && uglifyjs --compress drop_console build/static/js/main.xxxxx.js -o build/static/js/main.xxxxx.js
However How exactly can I know the hash suffix on the main.js file so I can call this command and save the output js file with same filename

Add this to index.js
if (process.env.NODE_ENV !== 'development') {
console.log = () => {}
}
Note that this will only suppress the messages, it will not strip them from your deployed code.
Note Nov 2020
Don't do this for library modules, it will disable console.log for the parent project.
Update Sept 2020
There is some movement on this issue on the CRA repo... go give it support/thumbs up here https://github.com/facebook/create-react-app/pull/9222
References:
How to quickly and conveniently disable all console.log statements in my code?

If you just want to suppress log output you could wrap console.log and use that instead
const log = (...msgs) => {
if (process.env.NODE_ENV === 'development') console.log(...msgs)
}
You can import / export this, but that sounds like a pain. Seems like a good thing to add to global
global.log = log
global.log('will only log in dev')

Do this in package.json scripts:
"build": "./scripts/build.sh"
and then in your project:
scripts/build.sh looks like:
#!/usr/bin/env bash
set -e;
cd "$(dirname $(dirname "$BASH_SOURCE"))" # cd to project root
react-scripts build
for f in build/static/js/*.js; do
uglifyjs --compress drop_console "$PWD/$f" -o "$PWD/$f"
done

You can try this combo of packages to override the config:
Note: from the document of react-app-rewired, this would break the the "guarantees" that CRA provides. So you should be careful before using it.
npm i -D customize-cra react-app-rewired babel-plugin-transform-remove-console
Modify your package.json, replace react-scripts to react-app-rewired except the reject. Once complete, your scripts should look like this:
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
}
Then create a file under the root directory:
touch config-overrides.js
// config-overrides.js
const { override, addBabelPlugins } = require('customize-cra')
module.exports = override(
addBabelPlugins(
"transform-remove-console"
)
)
Finally, after running npm run build, all console.log gone.

I use this setup. I still need console log while in dev.
// config-overrides.js
const { override, addBabelPlugins } = require('customize-cra')
module.exports = override(
process.env.NODE_ENV !== 'development' && addBabelPlugins(
"transform-remove-console"
)
)

Related

DRY way to change working directory for npm scripts

I'm just trying out NPM as my build system for a small project and I'd like to ask if there is a clean and easy to maintain way to change the working directory for the build scripts. My first thought was something like
"scripts": {
"cd:workdir": "cd src/path/to/my/work/dir/",
"task:1": "npm run cd:workdir && command1",
"task:2": "npm run cd:workdir && command2",
[...]
}
But it seams command* is executed in a different process then npm run cd:workdir, so this doesn't work.
The only working way I found so far is:
"scripts": {
"task:1": "cd src/path/to/my/work/dir/ && command1",
"task:2": "cd src/path/to/my/work/dir/ && command2",
[...]
}
But there must be a better way to do this to keep it DRY and better maintainable. Thanks!
I think you can use child_process.exec to execute some commands from a javascript file:
// task.js
const { exec } = require('child_process');
exec('command', {
cwd: 'src/path/to/my/work/dir/'
}, (error, stdout, stderr) => {
// handle error, stderr...
console.log(stdout)
});
and execute that javascript file using node in npm script: "task:1": "node task.js"

The keyword 'interface' is reserved when using lerna

I had a react project created using create-react-app which I am now trying to convert to a monorepo architecture. I moved all the independent code in one package, package1 and the rest of the code (along with App.tsx and index.tsx) in another, package2. Also I have added the dependency of package1 in package2.
However, when I try to do yarn start in the second package, I get this error:
Module parse failed: The keyword 'interface' is reserved (11:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
What is it that I am doing wrong in the setup which is causing me this error?
It seems that it is related to tsconfig file.
so change jsx option in tsconfig.json from "preserve" to "react".
run yarn add -W craco within lerna project and
add this to your craco.config.js file within package2
const path = require('path');
const { getLoader, loaderByName } = require('#craco/craco');
const packages = [
path.join(__dirname, '../package1')
];
module.exports = {
webpack: {
configure: (webpackConfig, arg) => {
const { isFound, match } = getLoader(
webpackConfig,
loaderByName('babel-loader')
);
if (isFound) {
const include = Array.isArray(match.loader.include)
? match.loader.include
: [match.loader.include];
match.loader.include = include.concat(packages);
}
return webpackConfig;
}
}
};
and change your package.json file
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "craco eject"
}

nuxt.config.js: load different config for development or production

How can I load for production and development different settings.
I want something like this for example:
nuxt.config.js
sentry: {
dsn: 'xxx',
config: {
disabled: !env.isDev
}
},
Unfortunately isDev is not usable at that stage.
Create 2 different config files:
nuxt.config.dev.js
nuxt.config.js
and in package.json in scripts section specify config file for dev version
with --config-file nuxt.config.dev.js:
"scripts": {
"dev": "cross-env NODE_ENV=development HOST=111.111.111.111 PORT=3001 nodemon --watch api --exec \"nuxt --config-file nuxt.config.dev.js --spa\"",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production HOST=111.111.111.111 PORT=3002 nuxt start --spa "
}
Thank you for the good input.
In the meantime a found an other solution which is working fine for my current use case.
nuxt.config.js
import stdEnv from 'std-env'
...
sentry: {
dsn: 'xxx',
config: {
disabled: !stdEnv.dev
}
},
...
I think this is a good and easy solution if you have only little difference to your production setup.
At the end I will probably use a mix of both.
EDIT:
importing 'std-env' in nuxt.config.js gave me some problems on production.
I use this peace of code at the moment without any issues:
(process.env.NODE_ENV === 'development')
That way you don't need to import anything!

How add variable npm run build in package.json

I have 6 projects in an Angular workspace and I have to build each. Instead of write six lines in my package.json for each projet, for example :
"build_a":" npm run build a"
"buiild_b": "npm run build b"
I would like to create only one line like this :
"build_app": "npm run build name="aaa""
How I can do it ?
you could rely on environment variables in order to discover such names.
however it depends on which operating system you're using on how to define env variables.
"scripts":{
"build:a":"cross-env NAME=a npm run build",
"build:b":"cross-env NAME=b npm run build",
"build:c":"cross-env NAME=c npm run build",
"build":"browserify src/main.js -o build.js"
}
You would end up with a script section more or less like this.
Finally I found the solution using a node.js script: build-subproject.js.
const { exec } = require('child_process');
const args = process.argv.slice(2).join(' ');
console.log(`RUNNING build with args: ${args}`);
exec(
`ng build ${args} && cd dist/${args} && npm pack `,
(error, stdout) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.info(`stdout: ${stdout}`);
}
);
In package.json,
"build-subproject": "node ./build-subproject.js",
Then run , npm run build-subproject my-project-name

Add `jshint` worker into `scripts` for package.json

Dear stackoverflowers.
I have decided to include jshint into my project to helps me detect errors and potential problems in my JavaScript code. I have installed it at the project's root and I'm able to run next code from the console:
jshint --config .jshintrc ./app/
It returns me several notifications.
Then I've decided to create a special section inside my package.json scripts section. It looks like that:
"scripts": {
"jshint": "jshint --config .jshintrc ./app/"
}
And when I try to run
npm run jshint
It returns me an exception...
please check it out https://github.com/npm/npm/issues/6124, you can prevent this error if you set your script with following || true like in code snippet bellow
{
"scripts": {
"test": "jshint || true"
}
}
in this case your script will finish with exit code = 0, and npm will no throw an error