I'm having a bit of trouble adding react to a legacy application. While I found plenty of materials on getting started, I ran into a bunch of issues related to my particular configuration and exacerbated by my utter lack of webpack knowledge (so much time relying on react cli tools makes one lax).
My configuration:
./docs/jslib = my node_modules, that's where yarn installs modules
./docs/jscripts = my general js folder, various js scripts go there
./docs/jscripts/mini = my dist folder, some things get built/packed by gulp and end up here. This is where the built things are expected to go
./docs/jscripts/react(/react.js) = my desired root for react things, where the react.js is the entrypoint for DOM selection and rendering (at least for the first attempt).
My webpack config:
const path = require("path");
module.exports = {
entry: "./docs/jscript/react/react.js",
output: {
path: path.resolve(__dirname, "./docs/jscript/mini"),
filename: "react.js"
},
resolve: {
extensions: [".js", ".jsx"],
modules: [
path.resolve(__dirname, "./docs/jslib")
],
alias: {
'babel-loader': path.resolve(__dirname, "./docs/jslib/babel-loader")
}
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: [
path.resolve(__dirname, "./docs/jscript/react")
],
exclude: [
path.resolve(__dirname, "./docs/jslib")
],
use: {
loader: "babel-loader"
}
}
]
}
};
The error I get on running webpack:
yarn run v1.21.1
$ ./docs/jslib/babel-loader/node_modules/.bin/webpack --mode production
Insufficient number of arguments or no entry found.
Alternatively, run 'webpack(-cli) --help' for usage info.
Hash: 210250af48f3cf84fa4a
Version: webpack 4.41.6
Time: 75ms
Built at: 02/14/2020 9:23:09 AM
ERROR in Entry module not found: Error: Can't resolve 'babel-loader' in '/var/www/html'
I have webpack-cli, I can run webpack straight, I can run it from the modules bin folder, it's all the same problem - it can't find babel-loader even though babel-loader brings its own webpack script which I use, so the loader is obviously there in the "node_modules" that's actually on a different path.
From what I gathered, all I had to do was to add my custom node_modules path to the webpack config under the resolve settings, which has solved my initial errors related to packages not found (yet webpack still can't find the loader).
Note: if I symlink my ./docs/jslib as ./node_modules, it works as expected.
Is there something I'm missing?
Thanks!
After some digging, I found a solution and some details that other might want to keep in mind when configuring webpack in a rather non-standard context:
resolve: points to modules that are directly required in various scripts
resolveLoader: should point to the same, for the purpose of accessing loaders (which is what I needed)
Solution:
resolveLoader: {
extensions: ['.js', '.json', '.jsx'],
modules: [
path.resolve(__dirname, "./docs/jslib")
],
mainFields: ['loader', 'main']
}
Related
I have created a new react app using npx create-react-app and now I want to integrate a webpack.config.js file. I know I don't have to but it is a necessary step for an assignment.
I have tried many tutorials an articles but I can't seem to make it work. All I need is to include all the css related loaders (sass, css etc) and babel.
This is my webpack.config.js file:
const path = require('path');
module.exports = {
mode: "development",
entry: path.join(__dirname,'./src/index.js'),
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader"
]
}
]
},
resolve: {
extensions: ["*", ".js", ".jsx"]
},
output: {
path: path.join(__dirname,'public'),
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname,'public')
}
};
And I get this error:
ERROR in ./src/index.js 7:16
Module parse failed: Unexpected token (7:16)
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
| import * as serviceWorker from './serviceWorker';
|
> ReactDOM.render(<App />, document.getElementById('root'));
|
| // If you want your app to work offline and load faster, you can change
There're some alternatives that can override webpack config without ejecting the CRA project:
Alternatives You can try customize-cra for a set of CRA 2.0 compatible
rewirers, or any of the alternative projects and forks that aim to
support 2.0:
Rescripts, an alternative framework for extending CRA configurations
(supports 2.0+).
react-scripts-rewired for a fork of this project that
aims to support CRA 2.0
craco
add config-overrides.js in the route and add your webpack changes as:
const { addWebpackModuleRule } = require('customize-cra')
module.exports = {
webpack: override(
addWebpackModuleRule({
issuer: {
test: /\.sass?$/,
},
loader: 'file-loader',
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
}))
}
Answering this just because it kills me to see 10 page Medium articles as an answer when it can be answered in 1 sentence.
Enter your project dir and run npm run eject
This will extract all of the configuration files for you to edit, including webpack.config.js, to a folder called "config". Enter config/webpack.config.js, find the "return" statement, and inside there is a "resolve" configuration option. Add the following to that object:
symlinks: false
Boom. Saved you a stupidly long Medium article.
I have a React app that uses Webpack and Babel. I am trying to load an image anyway possible (svg, png...) but I keep getting the error "Unexpected character '�' (1:0) > 1 | �PNG". I installed url-loader (npm install url-loader --save-dev) which is supposed to help load images when using Webpack. Nothing has changed.
This is my webpack.config.js:
const {NODE_ENV} = process.env;
module.exports = {
mode: NODE_ENV === 'production' ? NODE_ENV : 'development',
entry: ['./client/index.js'],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 25000
}
}
]
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js',
},
};
This is how I was trying to load my image:
import hiker from './hiker.png';
<img src={hiker} />
Any help would be greatly appreciated, thank you.
Several issues here. First, you're using babel-node that's pointing to the index.js. If you want it to point to your webpack config, then you'll need to remove index.js from the package.json's dev scripts:
"dev": "nodemon --exec babel-node",
And rename webpack.config.js to babel.config.js.
Unfortunately, there's also quite a bit more work required to get your project up-and-running. It appears that this setup uses some server-side-rendering configuration. Admittedly, I've never used koa, so I can't be of much help here.
It also appears to be a bit outdated, and someone updated it and included a walkthrough.
That said, I'd recommend steering toward a new-developer friendly boilerplate if you're just learning.
I'd suggest starting with create-react-app, which obscures a lot of this webpack configuration.
Or, you can download my react-starter-kit, which has an exposed webpack configuration that you can play around with (if desired) and utilizes webpack-dev-server for development and webpack with a very simple express configuration for production.
Up to you.
Good luck!
I have found numerous posts about the Webpack error:
Uncaught ReferenceError: process is not defined
most of which suggest adding a plugin to the webpack.config.js:
plugins: [
// ...
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
}
}),
// ...
]
however this does not seem to do the trick in my case.
To make things easy, I have created a repo with the bare minimum to setup SemanticUI-React with Webpack, which should be straightforward to navigate. My config in webpack.config.js is heavily inspired from this recent tutorial which seems to have a lot of positive comments.
To reproduce the error, just clone the repo on your machine (I use yarn, but this should work with npm too):
git clone https://github.com/sheljohn/minimal-semantic-react
cd minimal-semantic-react/
yarn install
yarn run serve
which opens at localhost:3000, and the error can be seen in the developer console.
As far as I understand, it seems that when React loads, it is looking to determine whether production or development mode is set, using the variable process.env.NODE_ENV, which is undefined in the browser.
This might be related to the target field in the Webpack config (set to web by default); but since React is loaded from CDN, prior to the bundle, I guess it doesn't know about what WebPack is doing, which makes me perplex as to why adding a plugin in the config would change anything...
Hence my question: is it possible to use semantic-ui-react by declaring the big libs (React, ReactDOM, semantic) as externals? Everything works fine if I bundle them, but the bundle ends up around 4MB, which is quite big.
Additional Details
Error as seen in Chrome (OSX High Sierra, v66.0.3359.181, dev console):
react.development.js:14 Uncaught ReferenceError: process is not defined
at react.development.js:14
(anonymous) # react.development.js:14
and code excerpt at line 14:
if (process.env.NODE_ENV !== "production") {
File webpack.config.js
const path = require("path");
const webpack = require("webpack");
const publicFolder = path.resolve(__dirname, "public");
module.exports = {
entry: "./src/index.jsx",
target: "web",
output: {
path: publicFolder,
filename: "bundle.js"
},
devServer: {
contentBase: publicFolder,
port: 3000
},
externals: {
'jquery': 'jQuery',
'lodash': '_',
'react': 'React',
'react-dom': 'ReactDOM',
'semantic-ui-react': 'semantic-ui-react'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
}
}),
new webpack.HotModuleReplacementPlugin()
]
};
File .babelrc
{
"presets": ["env", "react"]
}
I think I finally solved this:
Mistake #1: I was using cjs versions of the React libs from cdnjs, when I should have been using umd instead. Although UMD style is ugly, it seems to work fine within browsers, whereas CommonJS uses require for example. See this post for a comparison of AMD / CommonJS / UMD.
Mistake #2: in webpack.config.js, the "name" for the external semantic-ui-react should be semanticUIReact (case sensitive). This is what is defined in the window global when the script is loaded from the CDN (e.g. like jQuery or React).
I updated the repository with these fixes, and you should be able to reproduce that working example on your machine. This repository contains the bare minimum needed to get SemanticUI, React and Webpack working together. This would have saved me a lot of time, so hopefully other people get to benefit from that!
Everything works fine if I bundle them, but the bundle ends up around 4MB, which is quite big.
It's because you bundle them in "development" mode. Try using "production" in your script instead, it will be much smaller.
"build": "webpack --mode production"
If you bundle everything in production, without specifying external, it will be better for a standalone app.
I'm making a react app using Babel and Webpack and I want to use the file-exists package from npm. I already installed and saved the package as a dependency for my project. After running npm start I get this error:
ERROR in ./~/file-exists/index.js
Module not found: Error: Cannot resolve module 'fs' in C:\GitHub\CryptoPrices\node_modules\file-exists
# ./~/file-exists/index.js 3:9-22
file-exists uses fs as a dependency but for some reason it is not working. Npm starts and runs without any issues if I don't require file-exists anywhere.
here is my webpack config file:
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: __dirname,
publicPath: '/',
filename: 'bundle.js'
},
module: {
loaders: [{
// exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
}
};
I'm new to Webpack and Babel so I'm a little bit lost.
It looks like you're calling the fs file-exists method in your index.js file. I'm not sure in what context you're calling the method, but this looks like a client-side call to a server-side method. I ran into a similar issue just recently.
From what I understand, the main issue seems to be that you can't call server-side (Node) methods in browser-interpreted client-side (front end) code. You have to call them from a server.
Webpack can load the fs module code into your front end, but the browser can't actually interpret those Node methods and run them; only a Node environment can do that. (more here)
You could fix the core issue by modifying the call to fs methods to happen somewhere server-side, or by finding an equivalent browser-supported package that offers the same functionality as the fs methods you need but that can be run in a browser.
A quick search for "fs module for browser" brings up a variety of options that might work for what you need, like fs-web, browserify-fs or filer.
Here is a similar question with some insight.
Use fs module in React.js,node.js, webpack, babel,express
node: {
fs: 'empty'
}
try to add the code above to your webpack config file and the error should disappear.
I am writing an external module that I would like to require in my project (react-list)
my module is a react component and obviously I have this in top of my file
var React = require('react');
I'm using npm link, and in my project I'm getting an error from webpack that react doesn't exist inside the node_modules directory INSIDE the external module
ERROR in /web/react-list/dist/List/List.js
Module not found: Error: Cannot resolve module 'react' in /web/react-list/dist/List
why isn't it requiring the react component from my projects node_modules directory?
edit: added my webpack, had to redact the files and directories
'use strict';
module.exports = {
context: __dirname,
entry: {
....
},
output: {
path: '../public/js/pages',
filename: "[name].js"
},
devtool: 'source-map',
resolve: {
modulesDirectories: ["node_modules", ......],
extensions: ['', '.js', '.jsx']
},
plugins: [],
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ["react", "es2015-loose"]
}
}
]
}
};
edit 2: I found a workaround without using npm link, and simply installing the required package using npm install and then removing the dist directory and replacing it with a soft link on my own without npm's help. Obviously this isn't an ideal way to develop.
edit 3: I reach the dreaded refs must have owner issue https://facebook.github.io/react/warnings/refs-must-have-owner.html error if I try to install the dependencies on my package directory, so its either this package doesn't find a react directory or it does but with another react version and nothing works...