Why webpack gives an error for about NODE_ENV? - node.js

I am using webpack+react+redux on a web application. And I am using webpack-dev-server to launch dev web server. When I access my application on a browser, it gives below error messages on the console:
Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster.
You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify to ensure you have the correct code for your production build.
Below is my webpack.config.js file. I didn't specify production mode, why webpack gives me such warning message? And how can I get rid of it?
const webpack = require('webpack');
const path = require('path');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const WebpackShellPlugin = require('webpack-shell-plugin');
var CompressionPlugin = require("compression-webpack-plugin");
const PATHS = {
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
app: path.join(__dirname, 'src'),
build: path.join(__dirname, './dist')
};
module.exports = {
entry: {
app: './app/index.jsx',
android: './app/utils/platform_android.js',
ios: './app/utils/platform_ios.js',
web: './app/utils/platform_web.js',
vendor: [
'axios',
'react',
'react-dom',
'react-redux',
'react-router',
'react-router-redux',
'redux',
'redux-thunk',
'react-alert',
'sha1',
'moment',
'nuka-carousel',
'react-cookie',
'material-ui',
'react-spinkit',
'react-tap-event-plugin',
'react-tappable',
],
},
output: {
path: PATHS.build,
filename: '[name].bundle.js',
},
watch: true,
devtool: 'source-map',
relativeUrls: true,
resolve: {
extensions: ['', '.js', '.jsx', '.css', '.less'],
modulesDirectories: ['node_modules'],
alias: {
normalize_css: __dirname + '/node_modules/normalize.css/normalize.css',
}
},
module: {
preLoaders: [
{
test: /\.js$/,
loader: "source-map-loader"
},
// {
// test: /\.js$/,
// exclude: /node_modules/,
// loader: 'jshint-loader'
// }
],
loaders: [
{
test: /\.html$/,
loader: 'file?name=[name].[ext]',
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets=es2015',
},
{
test: /\.less$/,
loader: "style!css!less",
},
{test: /\.css$/, loader: 'style-loader!css-loader'},
{test: /\.png$/, loader: "url-loader?limit=100000"},
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader?presets=es2015']
},
{
test: /\.svg$/,
loader: 'svg-sprite',
include: /public\/icons/
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
}),
new NpmInstallPlugin({
save: true // --save
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */["vendor"], /* filename= */"[name].bundle.js", Infinity),
],
devServer: {
colors: true,
contentBase: __dirname,
historyApiFallback: true,
hot: true,
inline: true,
port: 9093,
progress: true,
stats: {
cached: false
}
}
}
EDIT1:
I removed this line:
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
Then updated the NODE_ENV to development as below:
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("development")
}
})
Then I still got the same warning.
warning.js:14You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) to ensure you have the correct code for your production build.

I don't know how to say it more clear than webpack does...
You are not in a production build mode, but using a minified version of React. Use a non-minified one, so replace
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
with
react: path.join(__dirname, 'node_modules/react/dist/react.js'),
or whatever place where you have your react not minified.
And this is not an error - it is a warning, so you can still work with this one.
Just another thing by the way: path.join adds proper slashes for each operating system. What you do here is
path.join(__dirname, 'node_modules/react/dist/react.min.js')
when you should go with
path.join(__dirname, 'node_modules', 'react', 'dist', 'react.min.js')
This is how the path should be properly used

The warning you get now is because you are letting Webpack minify your build, but you are still setting NODE_ENV to development.
If you use UglifyJsPlugin you should always set NODE_ENV to production. If you're not building for production, remove UglifyJsPlugin to not get any warnings.
Webpack, React and Redux try to give you some best practice hints here. In development mode (NODE_ENV not set to production), they all give more warnings and have lower performance. When you minify them they assume you're running a production build. For production builds, they really expect NODE_ENV to be set correctly.
So in short:
Production builds: set NODE_ENV to production and use UglifyJsPlugin.
Dev builds: set NODE_ENV to development and don't use any minification plugins.

I fixed it by removing below configuration from webpack.config.js for development build. It seems that this plugin will compress the js code which is not suitable for development mode.
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
})

Related

Vite serves up jsx files in network traffic

I'm not sure what is going on but I have a very basic Vite setup, yet I'm seeing the local server serve up all my jsx files, which takes a good 10-15s when I do a fresh reload. At first I thought this just might be the way Vite works for development but even when trying to build for production it does the same thing and doesn't minimize or uglify the files but just serves the jsx as is.
enter image description here
The following is my vite.config.js. The commented out code is other things that I've tried with no success:
export default ({mode}) => {
return defineConfig({
root: 'app',
define: {global: 'window'},
// esbuild: {
// loader: "jsx",
// minify: true,
// minifySyntax: true,
// },
// optimizeDeps: {
// esbuildOptions: {
// minify: true,
// minifySyntax: true,
// loader: {
// ".js": "jsx",
// ".ts": "tsx",
// },
// },
// },
plugins: [react()],
// build: {
// outDir: '../dist',
// minify: true,
// },
server: {
host: '127.0.0.1',
port: 3000
}
})
};
I've tried numerous configuration options and tried every rollup/vite config option I could find on stack overflow and the internet. I'd expect vite to serve only the produced index.html and generated index.jsx file, not get all my source files as is.
This project originally did use webpack, but even then I wasn't doing anything special. Here is my webpack config incase that's helpful:
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
entry: [
'webpack-dev-server/client?http://vesta-dev.localhost.com:3000',
'webpack/hot/dev-server',
'react-hot-loader/patch',
path.join(__dirname, 'app/index.js')
],
output: {
path: path.join(__dirname, '/dist/'),
filename: '[name].[hash].js',
publicPath: '/'
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.DefinePlugin({
...
})
],
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
exclude: [/node_modules/, /__tests__/],
loader: 'eslint-loader',
options: {
configFile: path.resolve(__dirname, '.eslintrc'),
failOnWarning: false,
failOnError: false,
emitError: false,
emitWarning: true
}
},
{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
cacheDirectory: true,
plugins: ['react-hot-loader/babel']
}
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.scss$/,
use: ['style-loader','css-loader','sass-loader?modules&localIdentName=[name]---[local]---[hash:base64:5]']
},
{ test: /\.(jpe?g|png|gif)$/i, loader: 'file-loader' },
{
test: /\.woff(2)?(\?[a-z0-9#=&.]+)?$/,
loader: 'url-loader',
options: {
limit: '10000',
mimetype: 'application/font-woff'
}
},
{ test: /\.(ttf|eot|svg)(\?[a-z0-9#=&.]+)?$/, loader: 'file-loader' },
]
}
};
Looks like this is normal for when you use vite serve as that always serves the development environment, no matter what flags you set or command line options you pass in.
I thought it was interesting that no one talks about the jsx files actually being served in the network traffic and even with all my searching never came across anyone talking about this, nor in the Vite documents so I thought something was wrong.

NodeJS+Webpack+Docker project on WSL throwing errors with native 'fs' library

I have a NodeJS project that I'm building with Webpack and running inside a Docker container. This was being developed in a Linux environment, but I decided to try to move it to WSL (Windows subsystem for Linux) because that would make things easier for the dev team. Getting it to run on WSL has been difficult though.
Currently the project builds with no problems, and Docker also seems to be running smoothly. However, when I open the project on a browser, nothing loads. On the console is the following error message:
Uncaught TypeError: Cannot read property 'native' of undefined
at Object../node_modules/fs-extra/lib/fs/index.js (index.js:107)
at __webpack_require__ (bootstrap:19)
at Object../node_modules/fs-extra/lib/index.js (index.js:6)
at __webpack_require__ (bootstrap:19)
at Object.<anonymous> (RollingFileWriteStream.js:2)
at Object../node_modules/streamroller/lib/RollingFileWriteStream.js (RollingFileWriteStream.js:265)
at __webpack_require__ (bootstrap:19)
at Object../node_modules/streamroller/lib/index.js (index.js:2)
at __webpack_require__ (bootstrap:19)
at Object.<anonymous> (file.js:3)
When I check index.js:107, I see the following lines:
// fs.realpath.native only available in Node v9.2+
if (typeof fs.realpath.native === 'function') {
exports.realpath.native = u(fs.realpath.native)
}
However, all node versions I have running are 10+. My base image is node:12 (more specifically, version 12.13.0). Nodejs and npm versions on WSL are:
me#computer:.../addin$ nodejs --version
v12.11.1
me#computer:.../addin$ npm --version
6.12.0
And NodeJS on windows is:
PS H:\> node --version
v10.15.3
I'm not sure if this is relevant, but here are my webpack config files:
webpack.server.config.js:
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
module.exports = {
entry: {
server: './src/server/server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
fs: 'empty'
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
}
webpack.config.js:
const path = require("path")
const webpack = require('webpack')
const HtmlWebPackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
main: './src/js/index.tsx'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'web',
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.tsx', '.html', '.js']
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [
{
loader: "html-loader",
//options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/html/index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
And the build command is:
rm -rf dist && webpack --mode development --display-error-details --config webpack.server.config.js && webpack --mode development
I'm out of ideas on how to fix this. I have tried removing and reinstalling nodejs, deleting all docker images, etc. Any suggestions would be much appreciated.
Fixed by installing this npm package, importing it on server.js, and monkey-wrenching:
var rp = require('fs.realpath')
rp.monkeypatch()
Unfortunately fixing it didn' give me any more insight on what's wrong with WSL and node, but at least it works.
EDIT:
Since this question seems to be relevant to some, I have since discovered that the real problem is that I was trying to use fs in a class that was bundled with target: 'web' (the second config file I posted). This is another part of the code, and it didn't occur to me that this could be the problem.
The webpack.config.js I posted originally is for an expressJS server, while this other part of the code was for the frontend of the application.
From what I understand, target: 'web' tells Webpack not to bundle and NodeJS functions because this code will be run in a browser. target: 'node' is appropriate for code that will run in a node environment (i.e. an expressJS server, that will run on the backend)
I hope this helps people who are running into this problem.
Do you have jquery in your package.json? I remember getting that error with Create-React-App when I forget to add the jquery cdn to index.html

Webpack 2: can't resolve node.js native modules

After bundling I have following errors:
Module not found: Error: Can't resolve 'crypto' in //filePath
It can't resolve five modules: crypto, fs, path, vm and constants - from any file which requires them
I thought it could be because of nvm which I use, but I switched to system nodejs via nvm use system command and webpack still throws these errors.
I also thought it could be target property, so I changed it to node, but it didn't help too (anyway I need electron-renderer, not node).
Important note: I've just migrated from webpack 1. It all works well before I migrated. But these are the only errors I have. Moreover, webpack seems to work fine, it even watches files when I pass --watch option.
Here is my webpack.config.js:
const config = {
target: 'electron-renderer',
context: __dirname,
entry: { app: './app.js', vendor: [/*vendors*/]},
cache: true,
devtool: 'source-map',
watch: false
resolve: {
extensions: ['.js', '.json', '.jsx'],
modules: ["node_modules"]
},
module: {
rules: [
{test: /\.html/, loader: 'html-loader'},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader?sourceMap", "less-loader?sourceMap"]
})
},
{
test: /\.css/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader?sourceMap"
})
},
{test: /\.(jpg|png|gif|jpeg|svg|otf|ttf|eot|woff)$/, loader: 'url-loader?limit=10000'}
]
},
plugins: [
new ExtractTextPlugin('styles.[contenthash].css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['commons', 'vendor', 'manifest'],
minChuncks: Infinity
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
hash: false,
inject: 'head',
cashe: true,
showErrors: true
})
],
output: {
publicPath: './',
path: path.join(__dirname, 'dist'),
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].js'
}
};
module.exports = config;
The problem was in worker-loader, which is not in my webpack.config.js (I used it directly when importing file). See this issue for details (not fixed yet).

Webpack not including all our js and jsx file, even those in the same directory

We are trying to upgrade our React.js application which uses WebPack to build. In our upgrades we are moving from Webpack 1.0 to 2.0 and I have made the "necessary" changes for the upgrade. It is building, and compiling, however, when I look at the files included, it is a very smaller scale of the files it was including before.
For instance, we have 34 files in our React Flux Actions directory. Some files have .js extension some .jsx. However, of the 34 files, only 1 is showing up in the build. What happened to the other 33. This one has .js extension but there are more .js files in that directory too.
What am I missing?
This is our main config file.
var path = require('path');
var webpack = require('webpack');
var StringReplacePlugin = require("string-replace-webpack-plugin");
var Environment = require('./js/environment');
module.exports = {
entry: [
'./js'
],
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js',
},
plugins: [
new StringReplacePlugin(),
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: true,
failOnHint: true
}
}
})
],
resolve: {
extensions: ['*', '.js', '.jsx'],
modules: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'js'),
path.join(__dirname, 'jsx')
]
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel-loader' ]
},
{
test: /js\/constants.js$/,
loader: StringReplacePlugin.replace({
replacements: [{
pattern: /localhost/g,
replacement: Environment.getBackendURL
}]
})
}]
}
};
This is our hot reload local version, I think both files are used, the one above and this one. But I am only doing "npm run build" command right now, then running "npm run local"
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./js/index'
],
output: {
path: path.join(__dirname, 'build-hot'),
filename: 'bundle.js',
publicPath: '/build/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new webpack.NoErrorsPlugin()
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: true,
failOnHint: true
}
}
})
],
resolve: {
extensions: ['*', '.js', '.jsx'],
modules: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'js'),
path.join(__dirname, 'jsx')
]
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel-loader' ]
}]
}
};
Based on Michael's answer below, there is one I did find that is different and feels like could be the reason, but I did not see anything in Webpack2 for pre-loaders. Here is it.
preLoaders: [
{
test: /\.jsx?$/,
loader: "source-map-loader"
}
],
Webpack starts looking at your entry point(s) and only includes files that are being imported, it doesn't just include every file in your project (as described in Concepts - Entry of the official docs).
As your entry point is ./js it will start with ./js/index.js (that's how Node.js and therefore webpack handles importing Folders as Modules), so you're not including every file in that directory. And if you don't import them in ./js/index.js or in its dependencies, the files won't be included at all. Presumably you don't and that's why only this one file is being included in the bundle.
This behaviour hasn't changed from webpack 1 to webpack 2. It's rather surprising that it worked differently with webpack 1, but maybe you changed something in the migration process that you aren't aware of.

WebPack-Dev-Server error: require is not defined

Webpack itself is working fine, but the webpack-dev-server is not. Basically, webpack created 2 build files for me, a back-end bundle and a front-end bundle. So, I have a webpack-config.js for each of these. I want to develop my front-end code with webpack-dev-server, as you can see from my webpack-config file for my front-end-bundle.js below. When I run web-pack-dev server, it is able to find and build my front-end.js and index.html, but nothing renders in the console and it gives me a "Uncaught ReferenceError: require is not defined"
// var nodeExternals = require('webpack-node-externals');
var webpack = require('webpack');
module.exports = {
entry: './browser/entry.js',
output: {
path: './builds',
filename: 'frontend.js'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"development"'
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"development"'
}
})
],
module: {
loaders: [
{
test: [/\.es6$/, /\.js$/, /\.jsx$/],
exclude: 'node_modules',
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /\.html$/,
loader: 'html-loader'
},
]
},
resolve: {
extensions: ['', '.js', '.es6', '.json'],
root: '/Users/johnhenry/Desktop/GAMR/gamr/browser'
},
devServer: {
contentBase: 'builds/dev-build'
},
target: 'node',
// externals: [nodeExternals()]
}
The error is triggered by this in my front-end build (it is only in the dev server build, not in the non-dev-server webpack build):
function(module, exports) {
module.exports = require("url");
If anyone has insight into this, it would be much appreciated
Try adding:
target: 'web'
to your module block.
I had the same error and if anyone is still struggling with this, this solution also helped me:
... There are 2 ways to solve the issue:
1. (Recommended) Don't activate webpack-node-externals in your Webpack browser config, but let Webpack indeed bundle those modules
when targeting the web (this is probable what you want to do)
Have the external modules loaded in some other way in the browser, and add the appropriate importType flag to the webpack-node-externals configuration (either var for scripts or amd for AMD)
more details here: https://github.com/liady/webpack-node-externals/issues/17#issuecomment-284222729
I hit this issue when a webpack.config.js from a node app for the base of a react app.
I had the following:
target: 'web'
but still ran in to the same issue.
Removing reference to webpack-node-externals solved it, which does make sense when you think about what node-externals is actually doing.
I had below rule in my webpack.config.js
rules: [
{
test: /\.js$/,
use:['script-loader']
}
]
Removing above rule from webpack.config.js removed the error.
Hope this helps.

Resources