How to use google fonts in manually created React app? - reactjs

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?

Related

Webpack unable to find babel-loader

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']
}

create-react-app webpack configuration file

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.

Import line getting error in Firefox

I have a React project that uses OverlayLoader library. Although code runs just fine on Chrome, it gets "TypeError: can't convert null to object" in firefox. After taking some time tracking down the error, I found that it comes from import line where I import OverlayLoader library
import OverlayLoader from 'react-overlay-loading/lib/OverlayLoader';
There's also "Source map error: request failed with status 404". But that shouldn't matter though. Why this error only occurs in Firefox?
EDIT : This is content of webpack.config.js
var dotenv = require('dotenv').config({path: __dirname + 'path'});
var webpack = require('webpack');
module.exports = {
entry: ["./js/app.jsx", "./css/custom.scss", "./css/main.scss"],
output: {
path: "public/js",
publicPath: "/js",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.jsx?|\.js$/,
exclude: /(node_modules|bower_components|neal-react)/,
loader: "babel-loader",
},
{
test: /\.scss$/,
loader: "style!css!sass"
}
]
},
resolve: {
alias: {
querystring: 'querystring-browser'
}
},
plugins: [
new webpack.DefinePlugin({
"process.env": dotenv.parsed
})
]
};
Two things you can check:
Do you have a libraryTarget in your webpack config? If you, could you try and remove that?
Are you using externals in your webpack configuration? If so, the package will not be bundles and the browser might not have access to it.
Hope it helps.
EDIT:
Seems like it's a source-map issue. I thought that it might be in your configuration but it isn't. Usually a source-map error is because the browser can't find the source-map I think this is an issue you can report with the repo. It's not your configuration.

Importing materialdesignicons package in ReactJS & Webpack

I am trying to add material design icons into my project via the npm "mdi" package. but I have issues.
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'src/public');
var APP_DIR = path.resolve(__dirname, 'src');
var config = {
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080/',
APP_DIR + '/index.jsx'
],
output: {
path: BUILD_DIR,
filename: 'bundle.js',
publicPath : '/'
},
devServer : {
historyApiFallback: true,
contentBase: 'src/public/'
},
module: {
loaders : [
{
test : /\.jsx?/,
include : APP_DIR,
loader : ['react-hot-loader', 'babel-loader']
},
{
test: /\.s?css$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(eot|svg|ttf|woff|woff2)(\??\#?v=[.0-9]+)?$/,
loader: 'file-loader?name=/fonts/[name].[ext]',
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
}
};
//dev server
module.exports = config;
my App components calls the main scss file
import './scss/App.scss';
then in that App.scss file, I import a settings.scss and the materialdesignicons.scss file
settings.scss
$mdi-font-path: "fonts/";
App.scss
#import "./settings.scss";
#import '~mdi/scss/materialdesignicons.scss';
the project is imported via the main.scss file.
settings.scss
$mdi-font-path: "fonts/";
whenever I try to build, I get an error with it trying to figure out how to handle the webfont items.
ERROR in ./~/css-loader!./~/sass-loader!./src/scss/App.scss
Module not found: Error: Can't resolve './fonts//materialdesignicons-webfont.eot?v=1.9.32' in '/<path>/app/src/scss'
# ./~/css-loader!./~/sass-loader!./src/scss/App.scss 7:129-189
# ./src/scss/App.scss
# ./src/App.jsx
# ./src/index.jsx
# multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server webpack-dev-server/client?http://localhost:8080/ ./src/index.jsx
I thought that the file-loader would handle those files. It seems that maybe since it's importing the scss file, it doesn't use the file loader part, and instead tries to use the sass/css loaders.
I'm trying to figure out how this should be done.
My approach consists of three steps:
to install material-design-icons package
npm install material-design-icons
to import material-icons.css file into .less or .scss file/ project
#import "~/node_modules/material-design-icons/iconfont/material-icons.css";
to include recommended code into the reactjs .js file/ project
<i className='material-icons' style={{fontSize: '36px'}}>close</i>
The file-loader does hadle those files. The Issue you have is that the file could not be found, and therefore it never gets to the file-loader.
materialdesignicons-webfont.eot is part of your node_modules, but when I think right now it is expected to be at ./app/src/scss/fonts/materialdesignicons-webfont.eot
I would expect this to work if you just remove your own definiton of $mdi-font-path.
UPDATE:
$mdi-font-path: '~mdi/fonts/';
#import '~mdi/scss/materialdesignicons';

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