create-react-app webpack configuration file - reactjs

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.

Related

How can I resolve this issue about Storybook and Sass?

I have an issue about Storybook. I can't start storybook and I have an error about my SCSS file.
Here is the error:
ModuleParseError: Module parse failed: Unexpected token (1: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
.h1 {
| color: red;
| }
at handleParseError (/myproject/node_modules/#storybook/builder-webpack4/node_modules/webpack/lib/NormalModule.js:469:19)
I mean this is juste a simple class. But when the file is empty, the compilation is okay, so I don't understand how I can resolve this.
My SCSS file
.h1 {
color: red;
}
My Webpack file
const webpack = require('webpack');
const path = require('path');
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, './src/index.js'),
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.scss?$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|jpe?g|gif)$/i,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
contentBase: path.resolve(__dirname, './dist'),
hot: true,
},
};
My main.js file in the .storybook folder
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)",
"../src/**/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
]
}
Is anyone has a solution please?
Thanks by advance
Finally, I have solved my problem, so here is how I did it.
First of all, I uninstalled the storybook (How to remove storybook from the react project), then the reinstalled via webpack (https://storybook.js.org/blog/storybook-for-webpack-5/).
For once with Webpack it works whereas installing it with NPM (or Yarn for my part) brought me to the complications that I had posted above. My guess is that it works for Webpack 5, whereas with NPM, I was getting an error about the css-loader loader that told me about Webpack 4.
Storybook worked, but I was still worried about .scss files. My terminal told me that I did not have a specific loader. So I took a loader for this type of file by adding a webpack.config.js in the .storybook folder created when we install Storybook. I used the instructions found here: https://storybook.js.org/docs/react/configure/webpack
About Sass files: Storybook is case sensitive, and also doesn't take into account files starting with _, so not possible to use partials
I hope you don't have this kind of problem, but if you do, maybe these answers will help you ^^

How to use google fonts in manually created React app?

I created React app manually (not create-react-app) one by one such as index.js, App.js, index.css, components folder etc because I am using React app as a separate app in the Django project.
And in order to use google fonts, I followed this answer.
But when I write #import url('https://fonts.googleapis.com/css?family=Josefin+Sans') in the index.css, it is giving me this error.
ERROR in ./src/index.css 1:0
Module parse failed: Unexpected character '#' (1: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
> #import url('https://fonts.googleapis.com/css?family=Josefin+Sans');
|
# ./src/index.js 4:0-21
webpack 5.15.0 compiled with 1 error in 999 ms
I think this error is related to webpack.config.js and it seems I need to add some rules in the module section related to css-loader, file-loader, or something else, but I am not sure how to write.
This is just my thought, I have no idea why this is happening.
webpack.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./static/frontend"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
optimization: {
minimize: true,
},
plugins: [
new webpack.DefinePlugin({
"process.env" : {
NODE_ENV: JSON.stringify("production"),
}
})
]
};
How to solve this issue? (This issue has happened when I tried to use react-toastify also. So I removed it and used another alternative package.) How to use fonts in the non create-react-app based project?

Images not loading in React app with Webpack despite having file loaders (url-loader)

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!

Webpack: Can I get a source map for after babel, before minification?

I have a fairly basic webpack setup that runs babel and out comes my minified js with a source map.
Now when I run my source map in chrome I get the js before babel and before minification. However I would often like to have my source map after babel but before minification. Is this possible?
TL;DR I want source map to post-babel pre-minifcation. Possible?
For completeness
I run babel-loader 8 with webpack 4
Here is a screenshot from chrome showing the problem. As you can see the Dropzone tag indicates this is jsx (and so before babel)
Secondly here is my webpack config (not that it actually matters for my question).
const path = require('path');
module.exports = {
context: path.join(__dirname, 'Scripts', 'react'),
entry: {
client: './client'
},
output: {
path: path.join(__dirname, 'Scripts', 'app'),
filename: '[name].bundle.min.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [require('#babel/plugin-proposal-object-rest-spread')],
presets: ["#babel/es2015", "#babel/react", "#babel/stage-0"]
}
}
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
},
devtool: 'source-map'
};
Running webpack with -d gives a second set of source maps in chrome that does the trick.

Unexpected token - Webpack 2.2.0 and SCSS

For some reason my yarn run dev command is failing due to the following:
SyntaxError: /src/components/home/index.scss:Unexpected token (1:0)
> 1 | .home {
...
I'm using webpack 2.2.0 which is setup like so:
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
include: path.resolve(__dirname, 'src'),
}, {
test: /\.(scss)/,
include: path.resolve(__dirname, 'src'),
use: [
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]__[hash:base64:5]',
'sass-loader',
{
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')
]
}
}
}
],
include: path.resolve(__dirname, 'src')
}
]
}
And all I'm doing in my index.js component is import s from './styles.scss'. If I remove the import statement and allow the app to boot and then put the import statement back in while the app is running and refresh the page then the styles are present... I find this extremely odd and haven't encountered this issue before...
That thread explains the reason why you are getting this error:
I think I found out why it didn't work on the first place. Though Webpack allows requiring static assets on the client side, babel, which compiles the server code, fails to do so as on the server side Node's require understands only JS files. This means that server side rendering is not possible with the default Webpack and babel.
There are several solutions to solve that issue, more or less complex to put in place.
The easiest one, is to ignore .scss on the server as so:
I added a run-server.js file to the project
require('babel-core/register')({
presets: ['es2015-node5', 'stage-0'],
plugins: ['transform-decorators-legacy'] //was needed to support decorators
})
require.extensions['.scss'] = () => {
return;
}
require.extensions['.css'] = () => {
return;
}
require('./server')
Run that with instead:
"cross-env NODE_ENV=development node ./run-server.js"
Added to your project:
npm install babel-preset-es2015-node5 babel-plugin-transform-decorators-legacy -D

Resources