Trying to add SASS to a React application - css

I created a brand new React application with create-react-app and now I want to add SASS to it.
I followed the instructions here. Basically I run
npm install node-sass --save-dev
and then added these two lines to my package.json file:
"scripts": {
"build-css": "node-sass src/ -o src/", # Line 1
"watch-css": "npm run build-css && node-sass src/ -o src/ --watch --recursive", # Line 2
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
This should do the job, according to the documentation, but when I complete the process doing
mv src/App.css src/App.scss
and then
npm run watch-css
the script just won't finish by itself. I always have to use Ctrl-C to finish it and I believe this is not normal.
My questions are:
Is this normal?
Have I missed something?
If so, what have I missed?

You need to transpile the scss to css for this you can use Webpack or Gulp. I will show you an example for Webpack as I prefer this more. Webpack it takes a while to config you can watch tons of internet tutorials.
In order to transpile scss into css you need to write a loader, in Webpack will be something like this:
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract(
'style', 'css!sass'
)
},
]
},
This are the packages for the loader, install with npm --S -D sass-loader style-loader into package.json file.
Now in order for Webpack to see the scss files you need to import those files into a js/jsx file for example App.jsx. But to not have a lot of imports you can have a base.scss and you will import other scss fils into it
example import './assets/stylesheets/scss/base.scss';
base.scss contains import to other scss files.
This is just a small introduction to what you must do. You need a little bit more to config Webpack you can search on youtube for that or This github link will help you alot!
Gulp is similar you write tasks, as far as I know there is gulp-scss package.

Related

.babelrc breaking semantic-ui and next app

I am not sure what went on, but whenever I wanted to add unit testing to my app, I had to add .babelrc file with just the following code:
{
"presets": [
"es2015",
"next/babel"
]
}
Prior to that, I did not need the file and it was just an nextjs app with semantic. So far, so good. Until I decided to rebuild my semantic-ui theme which turned out to be a massive mistake!
This was what I ran: cd semantic && gulp build
This caused my app to stop working whenever .babelrc is present.
These are my package.json scripts:
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"semantic": "cd semantic && gulp build",
"test": "mocha --require babel-core/register --watch-extensions js **/*.test.js"
},
If I attempt to run the next related scripts, I get the following error:
Error: Plugin/Preset files are not allowed to export objects, only functions. In /Users/theJuls/Workspace/cbt/client/node_modules/babel-preset-es2015/lib/index.js
If I try to run my unit tests, I get
Error: Plugin 0 specified in "/Users/theJuls/Workspace/cbt/client/node_modules/next/babel.js" provided an invalid property of "default" (While processing preset: "/Users/theJuls/Workspace/cbt/client/node_modules/next/babel.js")
If I remove .babelrc, all the next scripts run normally, however I completely lost my unit tests. Why is this happening? What can I do to fix this?
I am not sure if this is relevant but here is my current file structure:
api/
components/
config/
lib/
pages/
semantic/
store/
.babelrc
package-lock.json
package.json
semantic.json
I am not sure why it suddenly broke, but I have figured out a way around it which is also the more up to date way to do it, as my previous one was deprecated.
First off I had to install the following modules: #babel/core and #babel/register
Changed the .babelrc file to as follows:
{
"presets": [
"#babel/preset-env",
"next/babel"
]
}
Finally, in package.json just slightly change the test command to:
"test": "mocha --require #babel/register --watch-extensions js **/*.test.js"
Since we are now using #babel/register
This made everything come back to normal.

Node-Sass compile multiple files in a single directory to one file

I need to compile multiple scss files into a single css file using node-sass.
My structure looks like this:
/
/scss
app.scss
/components
header.scss
/css
app.css
In my app.scss file I import all my other files. So watching just that file doesn't work like this example I tried:
"watch": "node-sass -w scss/app.scss css/app.css"
It did work as long as I put all the code in that file and didn't import anything else or manually compiled that each time, but the watching didn't work.
So I tried this as well to no avail:
"watch": "node-sass -wr scss/* app.css"
You could use the onchange npm package. You can watch globs and run scripts when any of them change.
"watch": "onchange 'scss/**/*.scss' -- npm run compile",
"compile": "node-sass scss/app.scss css/app.css"

Using Sass in angular 2

I'm trying to setup Sass in my Angular 2 project. Basically as I understand there are two ways to create an angular 2 project
1) Using angular-cli (https://github.com/angular/angular-cli)
I referred answer mentioned in https://stackoverflow.com/a/41541042/2868352 & I could successfully use scss files in angular 2 project, everything worked great but I couldn't locate the generated css file from scss file in project folder. Could anyone explain the reason why no css file was generated but still it worked?
2) Using quickstart seed (https://angular.io/guide/quickstart)
I couldn't get any information about how to set up sass in quickstart project. Does anyone have any idea about using sass in the quickstart project provided by angular?
Thanks in advance!
[Check edited part at end of this answer in case you are using angular cli]
Explaining how to use sass in 'quickstart seed'(https://angular.io/guide/quickstart)
(https://angular.io/guide/setup#download)
Please follow these simple steps:
Step 1: Setup the quickstart seed
Use the below commands to setup
npm install
npm start
you will see 'Hello Angular' on browser.
Step 2: Install node-sass and sass-loader
Use the commands mentioned below to install
npm i node-sass -S
npm i sass-loader -S
Now you can see both of these added in your 'dependencies' inside 'package.json' file.
Step 3: Create 2 folders for Sass code and Css code
Create two folders with any name in "quickstart-master" folder. In this case for example:
"sass_folder" and "css_folder". Now create a demo file 'demo.sass' and put it inside 'sass_folder'. You can put a simple sass code in this .sass file. It will look like this:
$font-stack: Helvetica, sans-serif
$primary-color: #000
body
font: 100% $font-stack
color: $primary-color
Step 4: Make changes in 'package.json' file
Add scripts to Build and Watch Sass code present in "sass_folder". After compilation, The resulting css code should be stored in "css_folder". After changes the "Scripts" in 'package.json' file should look like this:
"scripts": {
"build": "tsc -p src/",
"build:watch": "tsc -p src/ -w",
"build:e2e": "tsc -p e2e/",
"serve": "lite-server -c=bs-config.json",
"serve:e2e": "lite-server -c=bs-config.e2e.json",
"prestart": "npm run build",
"start": "concurrently \"npm run build:watch\" \"npm run serve\" \"npm run watch:sass\"",
"pree2e": "npm run build:e2e",
"e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
"preprotractor": "webdriver-manager update",
"protractor": "protractor protractor.config.js",
"pretest": "npm run build",
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
"pretest:once": "npm run build",
"test:once": "karma start karma.conf.js --single-run",
"lint": "tslint ./src/**/*.ts -t verbose",
"build:sass": "node-sass sass_folder/ -o css_folder",
"watch:sass": "npm run build:sass && node-sass sass_folder/ -wo css_folder/"
}
Have a look at 'start', 'build:sass' and 'watch:sass' only.
Step 5: Run the application
Now you can run the app by using below command:
npm start
You will see the compiled css code in "css_folder" with the same file name 'demo.css'. It will look like this (In this case):
body {
font: 100% Helvetica, sans-serif;
color: #000; }
Now if you make any change in .sass file it will be reflected to .css file dynamically as the script is watching the code.
If it shows error, Close the .css file when you make any change in .sass file.
Note: For scss code you can follow the same steps. You just have to put .scss file in "sass_folder" in this case.
[edited]
In case you want to use Angular CLI:
At the time of creation of new Angular project use below mentioned cmnds:
For sass:
ng new Demo_Project --style=sass
For scss:
ng new Demo_Project --style=scss
To change the existing style:
ng set defaults.styleExt scss
After this you can use Cli normally.
I can explain you the first one.
If you are using ng serverthe compiled files are saved in a hidden folder in your project.
If you are using ng build, you can see your compiled files in the /dist folder. In this folder you can found your general styles in the file styles.[hashversion].css, but local component styles are included inside main.[hashversion].js by Webpack.
Angular-cli uses webpack, and if you want to learn more about, see Webpack Docs
UPDATE
In the second case, you have to compile sass manually. In the app folder un have a app.component.ts that will be compiled in the same folder to app.component.js by Typescript Compiler. So you have to do the same with sass.
Import the CSS file in the component.
#Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`,
stylesUrl: ['app/app.component.css']
})
export class AppComponent { name = 'Angular'; }
Noticed that you cannot use relative path cause everything will be requested from root directory.
Create an app.component.sass and put your styles inside.
Then execute the sass compiler that compiles the app.component.sass to app.component.css
Run the server and it will work.
There are two main scenarios here.
When creating a new Angular CLI project, use CLI command
ng new my-angular-app --style=scss
When an Angular CLI project has already been set up, use CLI command
ng set default.styleExt scss
In case 2, you need to manually convert existing .css files. You can use also use sass or less instead of scss
Check out the full article here.
Using SCSS/SASS/LESS in Angular CLI Project

laravel mix sass images not found/hash

I am working for the first time with Laravel. With the 5.4 version they introduced the laraval mix. I tried to paste my SASS of the static website (I compile this with gulp) into sass files in the resources folder. This goes all well, my SASS will be compiled to the app.css file in the public map.
I have 1 main problem. All images in the sass files (resources/assets/images) are not compiling as I would like to have.
Code in SASS file (resources/assets/SASS/banners.scss)
section.module.parallax-1 {
background-image: url('../images/banner1.jpg');
}
Compiled with mix in (app.css)
section.module.parallax-1 {
background-image: url(/images/banner1.jpg?ef4f135bad144d886f07c8b65f757a85);
}
So instead of compiling the url to css like I have it in my SASS file, it compiles it to something different with the hash at the end. Also, after compiling the sass it generates a images map with the images I used in my SASS files. My images map originally is located at resources/assets/images.
I don't know what I am doing wrong. I've tried to change the url in my sass files but this will not help. Is there someone who can help me out? Or is there a other solution for this?
webpack.mix code / js
const mix = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
I had the same issue right now. As far as I can see this is no longer the case in the newest laravel mix version. But since its not yet up on npmjs
You can use the following fix:
in webpack.mix.js add
mix.options({
processCssUrls: false // Process/optimize relative stylesheet url()'s. Set to false, if you don't want them touched.
});
Then copy node_modules/laravel_mix/setup/webpack.config.js to your root directory.
(Same as where the webpack.mix.js is)
Find and remove this string from your new webpack.config.js file
{ loader: 'resolve-url-loader' + sourceMap },
When thats done you have to update your npm scripts to use your webpack.config.js file.
In your package.json use these scripts instead
"scripts": {
"dev": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules",
"watch": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules",
"hot": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot",
"production": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules"
},

Node-sass creates extra files in watch mode

I import all my SCSS styles into a index.scss file using #import. This works fine when I build css manually using npm run build-css:
"scripts": {
//Other scripts
"build-css": "node-sass src/scss/index.scss -o dist/css/",
}
When I run node-sass in watch mode it updates the /dist/css/index.css just fine but also creates the css in the dist folder for the original scss file that I edited and imported in the src/scss/index.scss
"scripts": {
//Other scripts
"build-css": "node-sass src/scss/index.scss -o dist/css/",
"watch-css": "npm run build-css && node-sass src/scss/index.scss -o dist/css/ -w src/scss/**/*.scss --include-path src/scss/imports/*.scss"
}
My src/scss/index.scss looks as follows:
#import "./imports/bootstrap.min";
#import "./imports/contacts";
So, if I edit contacts.scss in watch mode node-sass updates the ./dist/css/index.css but also creates an extra contacts.css in the dist/css folder.
Is there a way I can have node-sass update only the dist/css/index.css and not build the imports into the dist folder?
Change the filename contacts.scss to _contacts.css; the compiler ignores the underscored files.

Resources