For the first time I've ran npm run build and uploaded to my server.
I realised that there wasn't any styling being pulled through very quickly and that it isn't even being referenced in my index.html file.
This is all working great on my dev setup when I run npm start
This is my production config and I'm wondering if there is anything obvious to why this isn't running.
https://jsfiddle.net/vmt20f8w/
I should point out that I am using SCSS files instead of css and importing them into my component js files. I thought the webpack.config.prod.js would have then taken all of these scss files and compile them down to one css file?
Update
I've now updated my config with the below code and it still isn't compiling the scss.
{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader",
options: {
includePaths: ["absolute/path/a", "absolute/path/b"]
}
}]
},
To make this even more clear I've actually got a public repo in which people can view all my code to understand the problem:
https://github.com/maximus-lynn/react-portfolio
You are using a loader for css files, but not for your scss files. Install sass-loader and change your config to look something like this:
test: /\.scss/,
loader: 'style-loader!css-loader!sass-loader'
Related
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 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.
I created an app with react-create-app, which generated a webpack config. But now, I would like to exclude a component of the bundle webpack because this component contains config info that must be modified. I read a lot about externals and exclude config with webpack but unfortunately none seems to work for me. In my case, here is my src folder:
-views
-config
|-ConfigCtl.js
-App.js
...
I want to exclude the file ConfigCtl.js. I tried to put this in the webpack.config.dev.js file at the modules.export section:
externals: {
"./src/config/ConfigCtl.js": "ConfigCtl"
}
But the ConfigCtl file is always packed in the bundle...
Is not a duplicate of other subject. I've tried the solution proposed in this subject but without efficiency...
Any suggestions ?
If you are using react with webpack go to your webpack config file and in the rule that test for /.js$/ there is a section to exclude dir or files from the bundle.Once this is done the file will be excluded from the bundle.
module:{
rules:[
{
test: /\.js$/,
exclude: /node_modules/,"./src/config/ConfigCtl.js"
use: {
loader: "babel-loader"
}
}
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.
I started my Angular 2 Webpack project from this official guide.
I went ahead and ran npm install --save-dev node-sass sass-loader resolve-url-loader. That went well.
My component is sitting at root/src/app/mycomponent/mycomponent.ts, and I'm referencing my scss in the heading this way:
#Component({
selector: 'home',
templateUrl: './mycomponent.html',
styleUrls: ['./mycomponent.scss']
})
The scss file is at root/src/app/mycomponent/mycomponent.scss and I have the following SASS in there:
p{
color: blue;
background-image: url('./background.jpg');
}
That image is sitting at root/src/app/mycomponent/background.jpg.
In webpack.common.js I have the following rule for .scss files:
{
test: /\.scss$/,
exclude: 'node_modules',
loaders: ['style-loader','css-loader','resolve-url-loader','sass-loader?sourceMap']
}
as recommended by resolve-url-loader documentation.
I keep on getting this error:
ERROR in ./~/css-loader!./~/resolve-url-loader!./~/sass-loader/lib/loader.js?sourceMap!./src/app/mycomponent/mycomponent.scss
Module not found: Error: Can't resolve './background.jpg'
I even tried loaders: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader!sass-loader?sourceMap!resolve-url-loader'}) and I'm still getting the same error.
For the life of me, I can't figure out what I did wrong. I was under the impression that resolve-url-loader will let me put a location in SASS url() relative to the .scss file it's declared in! That background.jpg sits in the same folder as my .scss file, so I think I referenced the path correctly.
I searched SO and the web and nobody seems to have the right solution. Is there any other code I need to show? Please help! And please, I don't want to import or require image files from .ts.
Update
It turns out that I misspelled the name of the image's file name. Now, I don't get that "module not found" error.
HOWEVER I now get the error in the browser's console output: Expected 'styles' to be an array of strings. This is with the configuration
loaders: ['style-loader','css-loader','resolve-url-loader','sass-loader?sourceMap']
Still stuck.
According to the error message, Angular is expecting assets to be strings while resolving the code. Thus in this situation, we need another loader here:
npm install --save-dev css-to-string-loader
Then in your webpack config file:
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['css-to-string-loader', 'css-loader', 'resolve-url-loader', 'sass-loader?sourceMap']
},
It should be good to go now.
I managed to get passed this issue by using 'exports-loader' instead of 'style-loader'
eg:
'exports-loader?module.exports.toString()'