I am trying to use sass with react, but none of my sass files are loading. I did not use create-react-app to start this project, I started it from scratch using web pack and npm init.
When I try to use a variable, like $titleColor, I get an error,
"Uncaught ReferenceError: $titleColor is not defined".
There are no import errors, and all imported paths are successfully loaded. There are no compile errors either--if I don't try to access $titleColor, my app works fine.
Here is my code:
// index.html:
<link rel="stylesheet" href="/src/assets/styles/app.scss">
<link rel="stylesheet" href="/src/assets/styles/colors.scss">
// app.scss
#font-face {
font-family: "San Francisco";
font-weight: 400;
src: url("https://applesocial.s3.amazonaws.com/assets/styles/fonts/sanfrancisco/sanfranciscodisplay-regular-webfont.woff");
}
#import "./colors.scss"
// colors.scss
$titleColor: 'rgba(211,64,80,1.0)';
// menuSection.js, a React Component
import '../../assets/styles/colors.scss'
// web pack config
module: {
rules: [
{
test: /\.scss$/,
use: ["sass-loader"]
}
]
}
please try in this way,
1. install 'npm install node-sass --save'.
2. rename app.css file to app.scss
3. create a new file with name variable.scss and put your title color like
$titleColor: #aeaeae;
4. import this color in app.scss with #import "variables.scss".
5. then use your $titleColor like 'background-color: $titleColor'.
You cannot "attach" a SASS/SCSS file to an HTML document.
Try to compile into a CSS and attach that css file to HTML document
How to include SCSS file in HTML
and $titleColor error is because of global variables file is not included or global variable $titleColor is not defined in your project, search for $titleColor in your project and make sure it is included in your .scss file
Check the usage of SCSS variales
you installed only-sass loader. this just tells webpack to recognize .scss files. you have to tell webpack evrything step by step. I assume you already installed node-sass as well because sass-loader requires it.
you need to install css loader and style loader. css loader takes your css and turns it to javascript code inside the bundle.js. style loader will take that javacript code and inject it into the DOM. after you installed, add them to webpack.config.js like so:
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}, {
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}]
},
rules are the kinda to do list for webpack. each rule is defined in an object. test will tell webpack whenever it sees this type of file, do what loaders say. if you have only one loader u define just like loader:"". if you have an array of loaders u use use:[]. you have to be aware that there is an order to this array in .scss rule.
css-loader is translator, style-loader is injector. it seems like first you have to translate and add css-loader first. but actually they load in reverse order.
in your index.html you do not need to link any css file. style-loader will handle it.
Related
I'm having some issues with HMR where its successfully reloading every time I make changes to either one of my jsx files or even my css files. However, the reload loads the pages with none of my styling. Any help or suggestions are appreciated!
Can you provide some code? Because it might be that you forgot to import your styles into the index.js, or that you did not configure webpack to process your styles...
You can take a look at this repo and compare it against what you have: https://github.com/matheus4lves/react-pagination
Pay special attention to theses lines:
webpack.config.js
{
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",
],
},
index.js
import "./styles/styles.scss";
import "./styles/pagination.scss";
I am trying to build a monorepo for my React projects as most of the code is shared between a few of my projects. I am using Yarn workspaces and Lerna for this.
I have managed to get a basic example working where the React component is shared between two projects. In this working example, however, the stylesheet is a plain CSS stylesheet and is correctly imported.
I am using Babel to transpile the React and ES6 code.
lerna exec --scope shared -- babel src -d dist --copy-files
where shared is my package containing shared components. Above command puts the transpiled JS and CSS files in the dist folder.
However, I have .scss files in my actual code base. Hence trying to replace external CSS file with external SCSS file in the example project. However, it doesn't work. The stylesheet isn't applied.
I think I understand why it must not be working. In CRA project whenever we use .scss file I think Webpack preprocesses these into .css files. In this is not happening hence the issue. Correct me if I am wrong.
I tried using Webpack instead of Babel. However, the issue that I faced was Webpack bundled all files into a single file which is something I don't want. I want that the individual component file should be transpiled and kept in the same folder structure under dist. Please see the folder structure below. shared is the package with shared components and myapp package uses the shared components.
workspace
--packages
--shared
--dist
--components
--button
--Button.js
--Button.scss
--header
--Header.js
--Header.scss
--src
--components
--button
--Button.js
--Button.scss
--header
--Header.js
--Header.scss
---myapp
My webpack.config.js
// Webpack uses this to work with directories
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
// Path and filename of the result bundle.
// Webpack will bundle all JavaScript into this file
output: {
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs2'
//filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.(jpg|png|gif|svg|tiff)$/, use: 'file-loader' },
{ test: /\.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' }
]
}
};
I am stuck at this point as I am not sure how I can import SCSS file in my React component which can be shared.
I'm not sure if there is a way to tell Webpack and Babel to transpile the React files and just put them in the dist folder without bundling them into a single file and also to preprocess the .scss files and use them in the transpiled files.
I followed by instructions included in Bootstrap documentation https://getbootstrap.com/docs/4.0/getting-started/download/#npm and installed Bootstrap via Webpack.
Then I wanted to import css styles as here https://getbootstrap.com/docs/4.0/getting-started/theming/ AND
I'VE ENCOUNTERED A PROBLEM:
When I adding this import (#import "node_modules/bootstrap/scss/bootstrap";) to my custom.scss file and order sass --watch custom.scss:custom.css in the console I'm getting this two errors:
1) Error: Cannot find module
"-!../../node_modules/css-loader/index.js?{"importLoaders":1}!../../node_modules/postcss-loader/lib/index.js??postcss!../../node_modules/bootstrap/scss"
2)./src/tu_sassy/custom.css Module not found: Can't resolve
'../../node_modules/bootstrap/scss' in
'/home/zebra/Desktop/testowa/src/tu_sassy'
My file structure is similar as in Bootstrap documentation, included as screenshot below.
!For more I need to add that when I delete this import from custom.scss everything works like a charm ...AND is still reusable and non-corrupted to original Bootstrap stylesheet 'my own stylesheet' WHY ?
One quick tip up front. If you want to write inline-code within your StackOverflow post, use backticks (`) around the code. That makes reading your post much easier.
Sass has its own functionality to import from node modules. Webpack Sass loader provides the ~ (tilde) prefix as a way to tell the compiler that it should resolve the path out of the node_modules folder.
#import "~bootstrap/scss/bootstrap";
If you have a dependency tree of packages within node_modues that import sass files, you can also tell Webpack Sass loader to include node_modules for resolving paths:
{
loader: "sass-loader", // compiles Sass to CSS
options: {
includePaths: [
join(dirname(module.filename), 'node_modules')
]
}
So I've written a really simple React app, but didn't use the create-react-app setup. I wanted to learn on my own how something like CRA actually gets built. I basically just used webpack to build and bundle my React app. Currently, I have a Babel loader to translate my React/JSX, and an "html-loader", for my HTML I guess (I read a tutorial for Webpack that said I needed it, but I still don't understand why I have to translate my HTML? It's HTML, what does it even translate to)?
My project currently has no CSS styling yet, and I want to learn how to add it. But I'm confused as to what loaders I should use. I'm pretty sure I'll need a Less loader for my .less files, but the Less loader compiles Less to CSS. So would I then need a CSS loader for the compiled less files? And then would I need a style loader for the CSS?
You will need the following loaders :
style-loader
css-loader
less-loader
So basically a webpack config as follow :
module: {
rules: [
{
test: /\.less$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
},
{
loader: "less-loader"
}
]
}
]
}
Check this answer to know what each loader does.
You might want to consider https://www.styled-components.com/. This library allows you to locate your stylesheet alongside with your react components.
If I am correct, using this library won't change your current webpack config.
If you want a more "traditional" approach for styling your react application, you will need at least two loaders for your webpack config:
style-loader and css-loader.
less and sass loaders will be required if you intend to use css-preprocessors though.
When I create my production bundle I do not require any stylesheets in javascript, they are included in index.html. The stylesheets are compiled with a grunt watch from sass to a bundle.css.
While developing I use webpack dev server. Now I want to include the css in the javascript bundle for hot module replacement, but without changing any existing javascript files.
The dev server is using dedicated index.html and webpack.config files, so preferably that's where I include the css bundle. Is this possible?
Maybe it's worth mentioning that I'm using React.
Answer: It looks like you can change the entry[] of webpack.config (example), to access a different .js file. Try creating referencing two different .js entry files for your respective webpack.config files, to import a different CSS file or omit the import line entirely. This compromises DRY, but does what you want.
React shouldn't make any difference.
Hot module is a red herring; it's implemented as a plugin, independently of the above:
plugins: [
...
new webpack.HotModuleReplacementPlugin());
],
Omitting the CSS module loader in webpack.config.dev wouldn't work.
module: {
loaders: [
...
{test: /(\.css|\.scss)$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap']}
]
}
because it would cause a parse error in import 'path/to/my.css' in index.js