How can i suppress logs from webpack when using react hot reloading? - reactjs

I am using this react redux starter kit https://github.com/coryhouse/pluralsight-redux-starter and i am getting the following outputs in my console
[HMR] connected
I tried to toggle the following fields in the web-pack config to true and false but it doesn't help
noInfo: true,
debug: false,
How can i turn these logs off?

Tried many solutions, the dev server option clientLogLevel: "none" had the closest meaning. But couldn't get it working.
Then I found a workaround:
Run your app with NODE_ENV=development; for that go to package.json and update scripts:
"scripts": {
"build": "webpack",
"start": "NODE_ENV=production webpack-dev-server --progress --inline --hot",
"dev": "NODE_ENV=development webpack-dev-server --progress --inline --hot"
}
modify webpack.config.js:
plugins: [
new webpack.DefinePlugin({
__DEVELOPMENT__: process.env.NODE_ENV !== 'production',
})
],
The DefinePlugin allows you to create global constants which can be
configured at compile time.
OR
Replace global.console.log with a custom console_log that filters out [HMR] and [WDS] logs. See this Github comment.
Add the below code to your development.js (a file which is conditionally appended to the entry in webpack.config.js based on the value process.env.NODE_ENV !== 'production')
(function(global) {
var console_log = global.console.log
global.console.log = function() {
if (!(
arguments.length == 1 &&
typeof arguments[0] === 'string' &&
arguments[0].match(/^\[(HMR|WDS)\]/)
)) {
console_log.apply(global.console,arguments)
}
}
})(window)
npm run dev
If you've used DefinePlugin, then we now have global constant __DEVELOPMENT__ === true on client side. So on every refresh you can do this:
if (__DEVELOPMENT__) {
console.clear();
}

On version >= 4.0.0 of Webpack You can keep the hot reload feature but limit the logs to errors under devServer like below:
devServer: {
hot: true,
client: {
overlay: false,
logging: 'error',
}
...
}
You can find more info about it on https://webpack.js.org/configuration/dev-server/#logging

Related

Why if I run the build command I don't have a server created?

There are two commands
"dev": "webpack serve --hot --mode development --config ./configs/webpack.config.ts",
"build": "webpack --mode production --config ./configs/webpack.config.ts",
When running in dev, I create a server. When I run build, a build is created for me.
Why is the localhost server not created when starting the build? if it is always specified to create? if I build on a real server, will the behavior be the same?
module.exports = (env: Server, argv: Imodul): Iwebpack => {
let { mode } = argv;
const isProduction: boolean = mode === 'production';
const isDevelopment: boolean = mode === 'development';
return {
entry: {
[MAIN]: ['./src/index.js'],
},
devServer: {
port: 3000,
historyApiFallback: true,
},
};
};
Did you see that you don't have the serve command in the build? You should look to this serve command in webpack, it can help.

electron & react: No resource with given URL found, DevTools failed to load SourceMap

For production (mac dmg) builds of my electron app, I am unable to trigger location.reload(), connect to redux-dev-tools, and the sourcemap fails to load.
When the app is loaded, the console warns that it cannot load the sourcemap:
The index.html in the sources says the resource cannot be loaded:
Executing location.reload() causes the app to crash with a white screen and no console logs (this command works in electron dev builds).
My electron code is contained in electron/index.electron.js and the relevant snippets are:
const options = {
icon: join(__dirname, '../src/common/assets/app-icons/png/256x256.png'),
webPreferences: {
nodeIntegration: false,
preload: join(__dirname, "preload.js")
}
};
// ...
mainWindow = new BrowserWindow({
...options,
...windowOptions
});
// ...
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: "file://../build/index.html"
});
// ...
mainWindow.loadURL(startUrl);
The relevant package.json snippets:
"homepage": "./",
"scripts": {
"electron-build:mac": "rm -rf dist/ && yarn build && electron-builder -m",
},
"build": {
"appId": "appId",
"extends": null,
"files": [
"dist/**/*",
"build/**/*",
"node_modules/**/*",
"src/common/assets/**/*",
"public/*",
"electron/**/*"
],
"directories": {
"buildResources": "./src/common/assets"
}
},
"devDependencies": {
"electron": "^11.3.0",
"electron-builder": "^22.9.1"
The only thing I can confirm in dev is that running location.reload() successfully reloads the app.
Thanks :)
your url is not valid,
you should change this:
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: "file://../build/index.html"
});
to this
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: "file://${ __dirname}/build/index.html"
});

Building a React-Electron app using electron-builder, index.js loads inside pre tags

I have an app that I'm now trying to build to distribute for testing.
I'm using React and Electron with electron-builder to build the app itself. I'm not a web developer so I've been trying to keep things basic and just get something to work.
After about five hours I was finally able to get the app to build somewhat properly and launch, but when it loads index.js (the first page in the app) it displays the source for index.js instead of rendering the content. In the devtools everything is inside a pre tag.
I've already looked at this thread and tried that but it didn't change anything, and I'm not using service workers as far as I can tell.
What the actual Electron window displays after launching with the devtools alongside.
Here's the createWindow function from main.js.
I've tried doing all kinds of things to the pathname with no effect.
function createWindow() {
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: path.join(__dirname, '../src/index.js'),
protocol: 'file:',
slashes: true,
});
mainWindow = new BrowserWindow({
width: 800, height: 600, title: "Electron App", webPreferences: {
nodeIntegration: true
}
});
mainWindow.loadURL(startUrl);
mainWindow.on('closed', function () {
mainWindow = null;
});
}
Here are my scripts from package.json
"scripts": {
"start": "nf start -p 3000",
"start-electron": "set ELECTRON_START_URL=http://localhost:3000 && electron .",
"react-start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build-electron": "npm run build && electron-builder build --win"
}
Here's the build part too. To be honest, I don't really understand what this is or does but after a few hours of trial and error this is what gets me to the point I am now.
"build": {
"appId": "Test",
"extends": null,
"files": [
"./build/**/*",
"./electron/main.js",
"./src/**/*"
]
}
As far as I can tell, it has something to do with the Electron start URL, because when I removed that from const startUrl in createWindow, running the app using npm start did the same thing as the built Electron app, whereas before using npm would launch the app normally every time.
EDIT after solution:
Modified build in package.json to
"build": {
"appId": "Test",
"extends": null,
"files": [
"./build/**/*",
"./electron/main.js",
"./src/**/*"
],
"directories": {
"buildResources": "./public"
}
}
I haven't tested it without this modification so I'm not sure that it's actually necessary.
Start URL was changed to
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: path.join(__dirname, '../build/index.html'),
protocol: 'file:',
slashes: true,
});
You're supposed to set it up with an html file.
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: path.join(__dirname, '../src/index.html'),
protocol: 'file:',
slashes: true,
});
Your browser window should load the build/index.html on production mode
const isDev = require("electron-is-dev");
if (isDev) {
mainWindow.loadURL(process.env.ELECTRON_START_URL);
} else {
mainWindow.loadFile(path.join("build", "index.html"));
}

React Dev Tools Thinks My Site is in Dev Mode

I want to see how much of a speed boost I get from using the non dev version of everything so I built my site using my "production" webconfig. but dev tools still is telling me it is in "development" mode
This page is using the development build of React.
const merge = require("webpack-merge");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const common = require("./webpack.common.js");
module.exports = merge(common, {
// Provides process.env.NODE_ENV with value production.
// Enables FlagDependencyUsagePlugin, FlagIncludedChunksPlugin,
// ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin,
// SideEffectsFlagPlugin and UglifyJsPlugin.
mode: "production",
// see https://webpack.js.org/configuration/optimization/
optimization: {
// minimize default is true
minimizer: [
// Optimize/minimize CSS assets.
// Solves extract-text-webpack-plugin CSS duplication problem
// By default it uses cssnano but a custom CSS processor can be specified
new OptimizeCSSAssetsPlugin({})
]
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
// only use MiniCssExtractPlugin in production and without style-loader
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
},
plugins: [
// Mini CSS Extract plugin extracts CSS into separate files.
// It creates a CSS file per JS file which contains CSS.
// It supports On-Demand-Loading of CSS and SourceMaps.
// It requires webpack 4 to work.
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new BundleAnalyzerPlugin()
]
});
in my package.json
"scripts": {
"dev": "cross-env NODE_ENV=dev webpack-serve --config webpack.dev.js --open",
"prod": "cross-env NODE_ENV=prod webpack -p --config webpack.prod.js",
"qa": "cross-env NODE_ENV=QA webpack --config webpack.prod.js"
},
My confidence is growing that your problem stems from setting NODE_ENV to prod in your package.json. I think you should instead set it to production, or allow webpack to set it internally with the mode option in your webpack config.
The react-scripts package explicitly sets this value to production for building and searching for NODE_ENV in the facebook/react project in github project shows tons of checks for production as the value instead of prod.
Here's the index.js file for react-is, many other projects in the react source follow the same pattern:
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-is.production.min.js');
} else {
module.exports = require('./cjs/react-is.development.js');
}
I would try changing your build script to:
"prod": "cross-env NODE_ENV=production webpack -p --config webpack.prod.js",
or even let webpack -p set it automatically:
"prod": "cross-env webpack -p --config webpack.prod.js",

How to tell webpack dev server to serve index.html for any route

React router allows react apps to handle /arbitrary/route. In order this to work, I need my server to send the React app on any matched route.
But webpack dev server doesn't handle arbitrary end points.
There is a solution here using additional express server.
How to allow for webpack-dev-server to allow entry points from react-router
But I don't want to fire up another express server to allow route matching. I just want to tell webpack dev server to match any url and send me my react app. please.
I found the easiest solution to include a small config:
devServer: {
port: 3000,
historyApiFallback: {
index: 'index.html'
}
}
I found this by visiting: PUSHSTATE WITH WEBPACK-DEV-SERVER.
historyApiFallback option on official documentation for webpack-dev-server explains clearly how you can achieve either by using
historyApiFallback: true
which simply falls back to index.html when the route is not found
or
// output.publicPath: '/foo-app/'
historyApiFallback: {
index: '/foo-app/'
}
Adding public path to config helps webpack to understand real root (/) even when you are on subroutes, eg. /article/uuid
So modify your webpack config and add following:
output: {
publicPath: "/"
}
devServer: {
historyApiFallback: true
}
Without publicPath resources might not be loaded properly, only index.html.
Tested on Webpack 4.6
Larger part of config (just to have better picture):
entry: "./main.js",
output: {
publicPath: "/",
path: path.join(__dirname, "public"),
filename: "bundle-[hash].js"
},
devServer: {
host: "domain.local",
https: true,
port: 123,
hot: true,
contentBase: "./public",
inline: true,
disableHostCheck: true,
historyApiFallback: true
}
Works for me like this
devServer: {
contentBase: "./src",
hot: true,
port: 3000,
historyApiFallback: true
},
Working on riot app
My situation was a little different, since I am using the angular CLI with webpack and the 'eject' option after running the ng eject command. I modified the ejected npm script for 'npm start' in the package.json to pass in the --history-api-fallback flag
"start": "webpack-dev-server --port=4200 --history-api-fallback"
"scripts": {
"ng": "ng",
"start": "webpack-dev-server --port=4200 --history-api-fallback",
"build": "webpack",
"test": "karma start ./karma.conf.js",
"lint": "ng lint",
"e2e": "protractor ./protractor.conf.js",
"prepree2e": "npm start",
"pree2e": "webdriver-manager update --standalone false --gecko false --quiet",
"startold": "webpack-dev-server --inline --progress --port 8080",
"testold": "karma start",
"buildold": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"},
I agree with the majority of existing answers.
One key thing I wanted to mention is if you hit issues when manually reloading pages on deeper paths where it keeps the all but the last section of the path and tacks on the name of your js bundle file you probably need an extra setting (specifically the publicPath setting).
For example, if I have a path /foo/bar and my bundler file is called bundle.js. When I try to manually refresh the page I get a 404 saying /foo/bundle.js cannot be found. Interestingly if you try reloading from the path /foo you see no issues (this is because the fallback handles it).
Try using the below in conjunction with your existing webpack config to fix the issue. output.publicPath is the key piece!
output: {
filename: 'bundle.js',
publicPath: '/',
path: path.resolve(__dirname, 'public')
},
...
devServer: {
historyApiFallback: true
}
If you choose to use webpack-dev-server, you should not use it to serve your entire React app. You should use it to serve your bundle.js file as well as the static dependencies. In this case, you would have to start 2 servers, one for the Node.js entry points, that are actually going to process routes and serve the HTML, and another one for the bundle and static resources.
If you really want a single server, you have to stop using the webpack-dev-server and start using the webpack-dev-middleware within your app-server. It will process bundles "on the fly" (I think it supports caching and hot module replacements) and make sure your calls to bundle.js are always up to date.
For me I had dots "." in my path e.g. /orgs.csv so I had to put this in my webpack confg.
devServer: {
historyApiFallback: {
disableDotRule: true,
},
},
You can enable historyApiFallback to serve the index.html instead of an 404 error when no other resource has been found at this location.
let devServer = new WebpackDevServer(compiler, {
historyApiFallback: true,
});
If you want to serve different files for different URIs, you can add basic rewriting rules to this option. The index.html will still be served for other paths.
let devServer = new WebpackDevServer(compiler, {
historyApiFallback: {
rewrites: [
{ from: /^\/page1/, to: '/page1.html' },
{ from: /^\/page2/, to: '/page2.html' },
{ from: /^\/page3/, to: '/page3.html' },
]
},
});
I know this question is for webpack-dev-server, but for anyone who uses webpack-serve 2.0. with webpack 4.16.5; webpack-serve allows add-ons.You'll need to create serve.config.js:
const serve = require('webpack-serve');
const argv = {};
const config = require('./webpack.config.js');
const history = require('connect-history-api-fallback');
const convert = require('koa-connect');
serve(argv, { config }).then((result) => {
server.on('listening', ({ server, options }) => {
options.add: (app, middleware, options) => {
// HistoryApiFallback
const historyOptions = {
// ... configure options
};
app.use(convert(history(historyOptions)));
}
});
});
Reference
You will need to change the dev script from webpack-serve to node serve.config.js.

Resources