sass-loader not working with webpack + react + grommet - reactjs

I'm trying to get started with webpack and Grommet working together. I'm following this tutorial: https://github.com/grommet/grommet-standalone but I'm getting the following error:
ERROR in ./src/app/index.js
Module not found: Error: Can't resolve 'grommet/scss/vanilla/index' in '/home/john/Development/Work/Utilities/react_practice/test_app/src/app'
# ./src/app/index.js 31:0-37
# multi library
Clearly it's looking for the scss file files in the source directory rather than node_modules - but I have no idea whats causing the error or how to fix it.
I'm using this sass loader: https://github.com/jtangelder/sass-loader
And I'm using webpack 2.10 because of this: https://stackoverflow.com/a/39608145/1596288
Additionally, these are my webpack.config.babel.js and index.js files:
import webpack from 'webpack';
module.exports = {
entry: {
library: './src/app/index.js',
},
output: {
library: 'bundle',
libraryTarget: 'umd',
filename: 'bundle.js',
path: './public/dist'
},
devServer : {
inline: true,
contentBase: './public',
port: 8100
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.scss$/,
loader: 'style!css!sass?outputStyle=compressed'
}
]
},
sassLoader: {
sourceMap: true,
includePaths: [
'./node_modules',
'./node_modules/grommet/node_modules'
]
}
}
and ...
import Header from 'grommet/components/Header';
import Title from 'grommet/components/Title';
import Box from 'grommet/components/Box';
import Search from 'grommet/components/Search';
import Menu from 'grommet/components/Menu';
import Anchor from 'grommet/components/Anchor';
import Actions from 'grommet/components/icons/base/Actions'
import 'grommet/scss/vanilla/index';
import React from 'react'
import { render } from 'react-dom'
const TesterComponent = () => (
<Header>
<Title>
Sample Title
</Title>
<Box flex={true}
justify='end'
direction='row'
responsive={false}>
<Search inline={true}
fill={true}
size='medium'
placeHolder='Search'
dropAlign={{"right": "right"}} />
<Menu icon={<Actions />}
dropAlign={{"right": "right"}}>
<Anchor href='#'
className='active'>
First
</Anchor>
<Anchor href='#'>
Second
</Anchor>
<Anchor href='#'>
Third
</Anchor>
</Menu>
</Box>
</Header>
)
render (
<TesterComponent />,
document.getElementById('root')
)

Managed to fix the issue by firstly modifiying my webpack.config.babel.js to the following:
import webpack from 'webpack';
module.exports = {
entry: {
library: './src/app/index.js',
},
output: {
library: 'bundle',
libraryTarget: 'umd',
filename: 'bundle.js',
path: './public/dist'
},
devServer : {
inline: true,
contentBase: './public',
port: 8100
},
resolve: {
extensions: ['', '.js', '.scss', '.css']
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!sass-loader?outputStyle=compressed'
}
]
},
sassLoader: {
includePaths: [
'./node_modules',
'./node_modules/grommet/node_modules'
]
}
}
Make sure you have the following libs installed too:
sudo npm install style-loader --save-dev
sudo npm install css-loader --save-dev
sudo npm install sass-loader --save-dev

try this
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', "css-loader!postcss-loader!sass-loader")
},

Related

You may need an appropriate loader to handle this file type, loading image in react

I'm trying to load an image from my static/images file, but I get the error
Avatar.jpg:1 Uncaught Error: 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
webpkack.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": {
// This has effect on the react lib size
'process.env.NODE_ENV': JSON.stringify('production')
},
}),
],
};
Navbar.js
import React, {Component} from 'react';
import {AppBar, Typography, Toolbar, Box, IconButton} from '#material-ui/core';
import {ArrowBack} from '#material-ui/icons'
import Avatar from "../.././static/images/Avatar.jpg"
class Navbar extends Component {
render() {
return (
<>
<Box component="div">
<Avatar src={Avatar} alt=""/>
</Box>
<Box component="nav">
<AppBar position="static" style={{background: "#222"}}>
<Toolbar>
<IconButton>
<ArrowBack style={{color: "tomato"}}/>
</IconButton>
<Typography variant="h5" style={{color: "tan"}}>
Portfolio
</Typography>
</Toolbar>
</AppBar>
</Box>
</>
);
}
}
export default Navbar;
You are probably using webpack version prior to version 5. Webpack doesn't know how to parse the image files. Also you can notice that in your rules, you are asking webpack to use babel loader to parse javascript files but there isn't a module that handles .jpg files. In that case, consider using file-loader which is a module made just for that.
npm i --save-dev file-loader
then update your webpack bundle modules to this:
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.(png|jpe?g|gif)$/i,
exclude: /node_modules/,
use: {
loader: "file-loader",
},
},
],
},
For more options, you can check the docs for file-loader
Note that, webpack 5 deprecated the use of file-loader in favor of Asset Modules
Please add an appropriate loader for your file type. https://v4.webpack.js.org/loaders/file-loader/
For png specific you can use:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
exclude: /node_modules/,
use: [
{
loader: 'file-loader',
},
],
},
],
},
};
For example, for SVG icons we can have loader like:
module: {
loaders: [
{test: /\.svg$/, loader: 'svg-url-loader'}
]
}
The problem is that icons are svg and you need a config for that in the webpack configuration.
Please refer: https://www.npmjs.com/package/svg-url-loader

Module not found: Error: Can't resolve ' ' when trying to run webpack

I get this error when I try to run webpack but it doesnt really show me what module it cant find. I get this error 4 times in different files. I am starting webpack via commandline with "webpack". I dont see the point
ERROR in ./src/index.js
Module not found: Error: Can't resolve '' in 'C:\Users\topal\IdeaProjects\cts-abwesendheitstool\cts-abwesendheit-fe'
# ./src/index.js 4:0-21
This is my code in index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<App/>,
document.getElementById('root')
);
my webpack config
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [[
'#babel/preset-env', {
targets: {
esmodules: true
}
}],
'#babel/preset-react']
}
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader!',
},
{
test: path.join(__dirname, '.'),
exclude: /(node_modules)/,
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env',
'#babel/react', {
'plugins': ['#babel/plugin-proposal-class-properties']
}]
}
},
{test: /\.json$/, loader: 'json-loader'}
],
},
resolve: {
extensions: ['*', '.js', '.jsx','.ts', '.tsx'],
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
contentBase: path.resolve(__dirname, './dist'),
hot: true,
},
};
In a different file:
import "./App.css";
import Datagrid from "./pages/Datagrid"
import {React, useEffect, useState} from "react";
import * as config from "./config/config";
import DaterangePicker from "./components/DaterangePicker";
function App() {
const [data,setData]= useState([]);
useEffect(()=>{
const requestOptions = {
method: 'GET'
};
fetch(config.SERVER_URL + `/caldav/getEvents/${config.CALENDAR}`, requestOptions)
.then((response) => response.json())
.then(data => setData(data))
.catch(error => console.log(error));
},[data.length]);
return (
<div className="App">
<header className="App-header">
Abwesendheitscheckliste
</header>
<DaterangePicker/>
<Datagrid rows={data}></Datagrid>
</div>
);
}
export default App;
I get the same error:
ERROR in ./src/App.js
Module not found: Error: Can't resolve '' in 'C:\Users\topal\IdeaProjects\cts-abwesendheitstool\cts-abwesendheit-fe'
# ./src/App.js 2:0-19
# ./src/index.js
Can you try something like this in webpack
use: ["style-loader", "css-loader"],

Error in installing webpack on REACT: Invalid configuration object. Webpack has been initialised using a configuration object that

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
configuration.module has an unknown property 'loaders'. These properties are valid:
object { defaultRules?, exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, noParse?, rules?, strictExportPresence?, strictThisContextOnImports?, unknownContextCritical?, unknownContextRecursive?, unknownContextRegExp?, unknownContextRequest?, unsafeCache?, wrappedContextCritical?, wrappedContextRecursive?, wrappedContextRegExp? }
-> Options affecting the normal modules (NormalModuleFactory).
configuration.output.path: The provided value "dist/assets" is not an absolute path!
-> The output directory as absolute path (required).
In React Tutorial course("Building with webpack")
(I use of windows but course is on linux)
my webpack.config.js
var webpack = require("webpack");
module.exports = {
entry: "./src/index.js",
output: {
path: "dist/assets",
filename: "bundle.js",
publicPath: "assets"
},
devServer: {
inline: true,
contentBase: './dist',
port: 3000
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: ["babel-loader"],
query: {
presets: ["latest", "react", "stage-0"]
}
}
]
}
}
project directories
my index.js
const { createElement } = React
const { render } = ReactDOM
const style = {
backgroundColor: 'orange',
color:'white',
fontFamily: 'verdana'
}
const title = createElement(
'h1',
{id:'title', className:'header', style: style},
'hello world'
)
render(
<h1 id='title'
className='header'
style={{backgroundColor:'orange'}}>
hello world
</h1>,
document.getElementById('react-container')
)
my cmd with command "webpack" to convert index.js to bundle.js
tutorial's terminal that run webpack successfully!!
There are a few issues here:
You are using an invalid key, loaders. It should be rules.
This was changed from Webpack v2 onwards. See this page for more information:
https://webpack.js.org/migrate/3/#module-loaders-is-now-module-rules
query has been deprecated in favour of options:
https://webpack.js.org/configuration/module/#ruleoptions--rulequery
The value for the loader key should not be an array.
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: "babel-loader",
options: {
presets: ["latest", "react", "stage-0"]
}
}
]
}

toastr not showing when imported in a jsx file

I have a react app that uses webpack to bundle JS and CSS into 1 file and output it into a destination folder. I've recently added toastr to 1 of my jsx file:
import toastr from "toastr";
import "toastr/build/toastr.min.css"
Running the app and viewing the source, i've verified in the browser (viewing the source files) that toastr.min.js is included in the JS bundle and toastr.min.css is included in the CSS bundle. However, the toastr notification doesn't show. There is no error and a scrollbar appears in the right-side for a few seconds so I suspected the toastr code is working, just that the CSS is not properly styling for some reason.
I removed this line:
import "toastr/build/toastr.min.css"
and then directly added this to html
<link rel="stylesheet" type="text/css" href="~/css/toastr.min.css" />
and now it works. But I want to make it work where toastr.min.css is included in the bundle. Is there anything I'm missing?
webpack config
const path = require("path");
const webpack = require("webpack");
const miniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
home: "./Scripts/Components/Home/main.js",
login: "./Scripts/Components/Login/main.js",
vendor: [
"jquery",
"react",
"react-dom",
"react-router-dom",
"react-css-modules",
]
},
mode: "development",
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: "all",
name: "vendor",
test: "vendor",
enforce: true
}
}
}
},
output: {
publicPath: "/js/",
path: path.join(__dirname, "/wwwroot/js/"),
filename: "[name].bundle.js"
},
devtool: "source-map",
plugins: [
new miniCssExtractPlugin({
filename: "../css/[name].css"
}),
],
module: {
rules: [{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["env", "react"]
}
}
}, {
test: /\.css$/,
use: [{
loader: miniCssExtractPlugin.loader,
}, {
loader: "css-loader",
query: {
modules: true,
localIdentName: "[name]__[local]___[hash:base64:5]"
}
}]
}]
}
};

How to set a webpack 2 alias for a folder?

I have a react project that looks like the following:
app
|_ components
|_ containers
|_ actions
|_ reducers
|_ themes
|_ theme1
|_ index.jsx
|_ theme2
|_ index.jsx
package.json
webpack.config.js
My question is:
Is there any way to set an alias that allows me to call any file inside the themes folder?
I'm using webpack 2 and I found somethings like this:
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
Themes$: path.resolve(__dirname, 'src/themes/')
}
},
I would also like to import these files in the following way:
import * as Themes from 'Themes';
When I run my project, I get the following error:
4:1 error 'Themes' should be listed in the project's dependencies.
Run 'npm i -S Themes' to add it import/no-extraneous-dependencies
4:8 error 'Template' is defined but never used
no-unused-vars 4:23 error Multiple spaces found before ''Themes''
no-multi-spaces 4:23 error Absolute imports should come before
relative imports import/first
4:23 error Unable to resolve path to module 'Themes'
import/no-unresolved 4:23 error Missing file extension for
"Themes"
I found some examples in this documentation, but I am not able to figure out the right way to implement it. Can anyone show me how I can set my webpack config in the correct way?
Below is my webpack.config.js:
var path = require('path');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: ['babel-polyfill', './src/js/index.jsx'],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
enforce: "pre",
test: /\.jsx$/,
exclude: /node_modules/,
loader: "eslint-loader",
},
{
test: /\.jsx?$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'react', 'stage-0'] }
}]
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader'}
]
},
{
test: /\.less$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader'},
{ loader: 'less-loader' },
]
},
{
test: /\.(jpg|jpeg|png|gif|svg)$/i,
use: {
loader: 'url?limit=10000!img?progressive=true'
}
},
{ test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml' }
]
},
resolveLoader: { moduleExtensions: ["-loader"] },
devtool: 'source-map',
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
Themes$: path.resolve(__dirname, 'src/themes/')
}
},
plugins: [
new CopyWebpackPlugin([
{ from: './src/html' },
{ from: './src/img/favicon.ico', to: './img'}
])
],
devServer: {
inline: true,
hot: true,
contentBase: path.join(__dirname, 'dist'),
port: 5000
}
}
Try to change configuration to variant with alias look like here:
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
Themes: path.resolve(__dirname, 'src/themes/')
}
},
Then add to themes directory index.js (path: app/themes/index.js):
import * as theme1 from './theme1';
import * as theme2 from './theme2';
export default {
theme1,
theme2
}
File: app/themes/theme1/index.jsx should export object of all staff inside theme1 directory.
import Someting from './Someting';
import Anything from './Anything';
export default {
Someting,
Anything
}
Now you can try:
import * as MyThemes from 'Themes';
console.log(MyThemes.theme1.Someting);
console.log(MyThemes.theme1.Anything);
or
import MyFirstTheme from 'Themes/theme1';
console.log(MyFirstTheme.Someting);
console.log(MyFirstTheme.Anything);
all the same for theme2 directory.

Resources