If I use this to run:
webpack-dev-server --progress webpack.config.js
There are many errors like this:
ERROR in ./~/chokidar/lib/nodefs-handler.js
Module not found: Error: Cannot resolve module 'fs' in E:\study\s-webpack\node_modules\chokidar\lib
# ./~/chokidar/lib/nodefs-handler.js 3:9-22
However, if I use these to run:
webpack-dev-server --progress
webpack-dev-server --progress --color webpack.config.js
There is no error.
Here is the code repo: https://github.com/qlqllu/react-webpack-simple/tree/test
It's a very simple react and webpack project.
Please use:
npm run good
npm run good2
npm run bad
to test.
Just add this to your webpack config
node: {
fs: "empty"
}
Read more about webpack configuration here
Then it'll be like
module.exports = {
entry: './main.js',
output: { path: __dirname, filename: 'bundle.js' },
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
node: {
fs: "empty"
}
};
Related
EDIT: I have created a minimal repo here https://github.com/kuworking/workspace-test
git clone it
yarn
lerna bootstrap
npm run build
npm run start // this one works,only babel without webpack
npm run build-fail
npm run start-fail // this one fails, with webpack
.
The configuration that works builds the library with babel-preset-gatsby-package or it also works with ["#babel/preset-env", "#babel/preset-react"]
"build": "babel src --out-dir lib"
The configuration that doesn't work uses ["#babel/preset-env", "#babel/preset-react"] and webpack, and it gives a React Minified error (see comments from #Shlang
"build": "webpack --config ./webpack.config.js --mode=production"
// webpack.config.js
module.exports = (env, argv) => {
const mode = argv.mode || 'development'
const config = {
entry: './src/index.js',
output: {
path: `${__dirname}/lib`,
filename: 'index.js',
library: 'test-fail',
libraryTarget: 'umd',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
},
devtool: mode === 'development' ? 'cheap-module-eval-source-map' : false,
}
return config
}
How can it work with webpack?
I have a React project within a Spring project. I want to have a debug environment, where React files are watched, and are compiled & copied to the Spring project (different directory). I am using Webpack 4.8.
Currently I have to run npm run build:dev every time I make changes to the React code, correct bundle.js is created and is moved to the correct location. But running it every time is a hassle.
I've tried appending the script with --watch, and although it does create a new build, it isn't copied to the final location.
My package.json script
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node_modules\\.bin\\webpack-dev-server --config .\\webpack.dev.js",
"dev": "webpack --config .\\webpack.dev.js",
"build": "webpack --config .\\webpack.prod.js",
"copy:prod": "copy .\\dist\\bundle.js ..\\xxx\\src\\main\\resources\\static\\ /Y",
"copy:dev": "copy .\\dist\\bundle.js ..\\xxx\\build\\resources\\main\\static\\ /Y",
"build:dev": "npm run dev && npm run copy:dev",
"build:prod": "npm run build && npm run copy"
},
For anyone interested, this is my webpack.dev.js
const path = require("path");
const { resolve } = require("path")
const config = {
mode: "development",
entry: "./src/index.js",
stats: {
colors: true
},
devtool: "inline-source-map",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"]
}
}
}
]
}
};
module.exports = config;
Ideally, I'd like any changes to the React code to trigger a build, and copy the build to a different location. The current situation is that I am able to get the correct build using --watch but it's not being copied to the specified location.
Okay, so I used a library called copy-webpack-plugin.
And the updated webpack.dev.js file now looks like
const path = require("path");
const { resolve } = require("path");
const CopyPlugin = require('copy-webpack-plugin');
const config = {
mode: "development",
entry: "./src/index.js",
stats: {
colors: true
},
devtool: "inline-source-map",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"]
}
}
}
]
},
plugins: [
new CopyPlugin([
{ from: './dist/bundle.js', to: '../../xxx/build/resources/main/static/', force: true},
{ from: './dist/bundle.js.map', to: '../../xxx/build/resources/main/static/', force: true}
], { copyUnmodified: true })
]
};
module.exports = config;
And updated my npm script
"dev": "webpack --config .\\webpack.dev.js --watch",
Now when I run npm run dev I have the updated bundle.js copied in the desired location, and webpack also watches my React files.
My folder structure looks like this:
- src/internal-logic.js
- src/header.js
- src/footer.js
- package.json
Here is a section of my package.json
"scripts": {
"start": "npx babel --watch src --out-dir dist --presets react-app/prod",
"build": "npx babel src --out-dir dist --presets react-app/prod",
"minify": "npx terser -c -m -o dist/common.min.js -- dist/header.js dist/footer.js dist/internal-logic.js"
},
When deploying this code I run the following commands
npm run build
npm run minify
This generates a file called common.min.js which I use in a few projects.
What I would like to do is to make a single build command by using webpack. How can I go about doing that?
UPDATE
I have created the following webpack.config.js
const path = require('path');
module.exports = {
entry: {
'common.js': [
path.resolve(__dirname, 'src/internal-logic.js'),
path.resolve(__dirname, 'src/footer.js'),
path.resolve(__dirname, 'src/header.js')
]
},
output: {
filename: '[name]',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-react']
}
}
}
]
},
};
This works
I have cloned this repo for reactjs development with hot reloading enabled.
Its working fine, Problem is that, I want to run this app inside electron with hot reloading. So in my main.js file I pointed reactsjs index.html file. Its showing blank page. Though i can see tag contents "Welcome to react" on electron window, that means its pointed properly, but no contents are getting displayed.
I found out that electron is throwing error
Failed to load resource: net::ERR_FILE_NOT_FOUND app.js
I am pretty new to react development (started 3-4 days back only), so not sure how to I solve it. Below is my dir structure and webpack config
My app is running at http://localhost:8080/
Directory structure
project
---node_modules
---src
------index.js
------Components
*babelrc
index.html (used by react)
main.js (used by electron)
package.json
webpack.config.js
Webpack config
const webpack = require('webpack')
const path = require('path')
module.exports = {
devtool: 'source-map',
entry: {
'app': [
'babel-polyfill',
'react-hot-loader/patch',
'./src/index'
]
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
]
}
}
Ok finally I managed to solve it. Problem was with "webpack-dev-server", this command creates app.js bundle file but doesnt actually place it in your directory. It serves from memory, that's the reason it wasn't getting generated and my electron app wasn't able to find it. I am posting solution here in case any beginner faces the same.
Just go to package.json and replace webpack-dev-server with webpack with --watch param, they work almost the same. Difference is that webpack --watch will create a actual bundled file and will place it in directory you specified in config.
This doesnt work
"scripts": {
"build": "webpack-dev-server --hot --history-api-fallback --open",
"app": " ./node_modules/electron/dist/Electron.app/Contents/MacOS/Electron ."
},
Below works
"scripts": {
"build": "webpack --watch",
"app": " ./node_modules/electron/dist/Electron.app/Contents/MacOS/Electron ."
},
to run react-hot-loader you should add it in a module in webpack.config.js as the following
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: ['react-hot-loader/webpack','babel-loader']
}
]
},
also you shouldh add it in .babelrc as the following :
{
"presets": [
"es2015",
"react"
],
"plugins": [ "react-hot-loader/babel" ]
}
Following is the webpack.config.js file for my React app
module.exports = {
entry: 'index.js',
output: {
filename: 'bundle.js',
path: '/.'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react']
}
}
]
}
};
and the error I am getting on execution is following:
npm ERR! code ELIFECYCLE
npm ERR! errno 4294967295
npm ERR! loginpoc#1.0.0 start: `webpack-dev-server --hot`
npm ERR! Exit status 4294967295
npm ERR!
npm ERR! Failed at the loginpoc#1.0.0 start script 'webpack-dev-server --hot'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the loginpoc package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! webpack-dev-server --hot
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs loginpoc
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls loginpoc
npm ERR! There is likely additional logging output above
my package.json is as follows
{
"name": "loginpoc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --hot"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^15.5.3",
"react-dom": "^15.5.3",
"webpack": "^2.3.3",
"webpack-dev-server": "^2.4.2"
}
}
kindly let me know what do you suggest where am I going wrong?
There are some changes needed to make your config work. Since the error you posted is just the noise from npm, the actual error is above all that, I'll show you the actual errors you get and how you can fix them.
ERROR in Entry module not found: Error: Can't resolve 'index.js'
An entry point for webpack is just like a regular import. This is not a relative path, therefore webpack resolves it as a module, it looks for a module index.js in node_modules. Presumably you want it to be:
entry: './index.js'
After fixing that you'll run into the following error:
ERROR in Entry module not found: Error: Can't resolve 'babel-loader'
You're using babel-loader in your webpack config, but you don't have it installed. Well you might have it installed, but it's not in your package.json so you either have it globally installed or you forgot to add --save or --save-dev respectively on npm install. Either way it should be listed as a dependency in your package.json so it also works on another machine by simply running npm install.
The dependencies related to babel-loader would produce the same error, so you can install all of them at once:
npm install --save-dev babel-loader babel-core babel-preset-react
And finally the last error you might encounter is:
Error: EACCES: permission denied, open '/bundle.js'
You'll not get this, if you're executing it as root or your user is allowed to write to / (the root of your file system). Anyway you don't want that, because the generated bundle should be somewhere in the directory of the project, otherwise multiple projects would end up overwriting the same bundle. You've also set the output.path to /. so maybe it was a typo and you meant ./. That wouldn't be allowed, because output.path needs to be an absolute path. You can use path.resolve for that.
output: {
filename: 'bundle.js',
path: path.resolve(__dirname)
}
You generally want output.path to be a directory inside your project, e.g. dist so you can easily separate the output from your regular files.
Here is the full config with all the changes mentioned above:
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react']
}
}
]
}
};
Try using this as your configuration.
var path = require('path'),
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname + '/')
filename: 'bundle.js',
publicPath: '/'
},
devServer: {
contentBase: './',
inline: true,
hot: true,
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react']
}
}
]
}
};
What I have done here is add some missing configuration options according to this doc. configuration. Note my addition of the path import
I have also modified some of your configuration options slightly.