Apparently the way to declare the default stylesheet extension changed from Angular 6 onwards. The styleExt property in the angular.json is not recognised any longer.
For new projects this can be set with an option on the CLI --style=scss on the new command.
However, how do you change this for exsting projects that I migrate from Angular <5 or if you forgot to do this during project creation?
This question is meant to be strictly related to the breaking changes by the version 5 to 6 of Angular.
The position on which this is set changed in the angular.json. There are 2 ways to set this option now.
Via the Angular CLI:
ng config schematics.#schematics/angular:component.styleext scss
Directly in the angular.json:
"schematics": {
"#schematics/angular:component": {
"styleext": "scss"
}
}
Angular 9 Update:
Note that from Angular 9 onwards styleext is renamed to style. So we end up with:
ng config schematics.#schematics/angular:component.style scss
and
"schematics": {
"#schematics/angular:component": {
"style": "scss"
}
}
To go from css to scss for an existing project, follow these steps:
In angular.json file
In build part and in test part, replace:
"styles": ["src/styles.css"], by "styles": ["src/styles.scss"],
Replace:
"schematics": {}, by "schematics": { "#schematics/angular:component": { "style": "scss" } },
Using ng config schematics.#schematics/angular:component.styleext
scss command works but it does not place the configuration in the
same place.
In your project rename your .css files to .scss
Related
I want sass linter in Gatsby's project
plugins: [
`gatsby-plugin-styled-components`,
{
resolve: `gatsby-source-contentful`,
options: {
},
},
{
resolve: "gatsby-plugin-eslint",
options: {
},
},
`gatsby-plugin-sass`
],
How to include it?
I want to detect incorrect CSS rules etc...
ESlint is a JavaScript linter, so it can't analyze nor lint your Sass code.
However, you can use Stylelint to parse SCSS, Saas, or CSS files.
You can follow the default configuration steps in their GitHub:
Install it by:
npm install --save --dev #primer/stylelint-config
Add a stylelintrc.json file in the root of your project (it can be a .yml or .js format too if needed)
Add your configuration rules. You can inherit from the default ones by using the extends rule as:
{
"extends": "stylelint-config-standard",
"rules": {
"indentation": "tab",
"number-leading-zero": null
}
}
Customize your commands to trigger your lint rules (change the file extension accordingly):
npx stylelint "**/*.css"
Resources:
https://stylelint.io/user-guide/get-started
https://dev.to/stories_of_ren/switching-from-sass-lint-to-stylelint-5f8c
I have deployed my application to aws and I see that the application renders fine, except that the syncfusion controls do not render correctly. Google chrome console does not show any errors.
The application renders correctly in my local machine.
To fix this, it was suggested I move the import '#syncfusion/**/styles/material.css' statements in the individual vue component to App.vue (as documented here). I however get a "Failed to resolve loader: sass-loader, You may need to install it" error(the application has node-sass, sass-loader installed already).
How should I include css files along with scss files, in my application?
Before: vocabulary.vue:
<script>
import '#syncfusion/ej2-base/styles/material.css';
import '#syncfusion/ej2-vue-inputs/styles/material.css';
package.json:
"devDependencies": {
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
}
vue.config.js:
module.exports = {
publicPath: '/',
transpileDependencies: [
'vue-echarts',
'resize-detector'
],
configureWebpack: {
devtool: 'source-map',
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
}
App.Vue:
<style>
#import "../node_modules/#syncfusion/ej2-base/styles/material.css";
#import "../node_modules/#syncfusion/ej2-vue-inputs/styles/material.css";
</style>
Deleting the npm packages and re-installing them again fixed the issue.
I created a react setup for a little project and decided to add tailwind. It was successful but when I add the class to the components, I don't see any change.
This is the link to the repository
Everything seems fine. Once delete the node modules and package.lock.json file and install node modules then start the server.
Also, there is no need to import tailwind.css in App.js.
Just main.css is enough as we are already appending all the styles to main.css (check scripts in package.json)
I found the problem. It was from my webpack config for CSS loader. I noticed when I added my own stylesheet, not all the rules were applied.
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
sourceMap: true
}
}
I had to remove all the options. I don't even know why I added it at first. Tailwind CSS now works.
If you know that you've configured Tailwind and added the right settings and presets, maybe you need to add this:
module.exports = {
content: [
'./public/index.html', <-
],
}
or this, if you're using ReactJS:
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}'
],
// ...
}
Within your tailwind.config.js file.
You also can learn/read more about it on: https://tailwindcss.com/docs/content-configuration, that worked perfectly for me!
I was trying to add global styles in the same way like in angular app, but it totally does not work.
My libraries' name is example-lib, so I added styles.css to /projects/example-lib/. I added styles in main angular.json file:
...
"example-lib": {
"root": "projects/example-lib",
"sourceRoot": "projects/example-lib/src",
"projectType": "library",
"prefix": "ngx",
"architect": {
"build": {
"builder": "#angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "projects/example-lib/tsconfig.lib.json",
"project": "projects/example-lib/ng-package.json",
"styles": [
"projects/example-lib/styles.css" <!-- HERE
],
},
...
But when I tried build library using command:
ng build example-lib
I got error:
Schema validation failed with the following errors:
Data path "" should NOT have additional properties(styles)
I guess that is the other way to add global styles in separate library. Anyone can help me?
I have a workaround for this. Just create the root component of your library without view encapsulation and all its styles will be then global.
my-library.component.ts
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'lib-my-library',
templateUrl: './my-library.component.html',
styleUrls: ['./my-library.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class MyLibraryComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
my-library.component.html
<!-- html content -->
my-library.component.scss
#import './styles/core.scss';
Now your my-library.component.scss and core.scss are global
styles/core.scss
body {
background: #333;
}
core.scss is optional, I just like to keep the root files clean.
Update: In case you want your mixins and variables too, then follow this answer.
As #codeepic already pointed out, there is currently a standard solution.
In ng-package.json add
"assets": ["./styles/**/*.css"]
The provided paths should be the paths to your files. At the same time, they will be the paths inside your /dist folder.
On build, the files will be copied to /dist. Users of your library will be able to add them to their global styles as follows.
/* styles.css */
#import url('node_modules/<your-library-name>/styles/<file-name>');
This way you can copy any type of files.
P.S. When used with CSS, do not forget that you can create an index.css file that can be imported just like node_modules/<your-library-name>/styles.
From Compiling css in new Angular 6 libraries:
install some devDependencies in our library in order to bundle the css:
ng-packagr
scss-bundle
ts-node
Create css-bundle.ts:
import { relative } from 'path';
import { Bundler } from 'scss-bundle';
import { writeFile } from 'fs-extra';
/** Bundles all SCSS files into a single file */
async function bundleScss() {
const { found, bundledContent, imports } = await new Bundler()
.Bundle('./src/_theme.scss', ['./src/**/*.scss']);
if (imports) {
const cwd = process.cwd();
const filesNotFound = imports
.filter(x => !x.found)
.map(x => relative(cwd, x.filePath));
if (filesNotFound.length) {
console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
throw new Error('One or more SCSS imports failed');
}
}
if (found) {
await writeFile('./dist/_theme.scss', bundledContent);
}
}
bundleScss();
Add _theme.scss inside the /src directory of the library that actually contains and imports all the css that we want to bundle.
Add postbuild npm script to run the css-bundle.ts
Include it in the styles tag in your Application in the angular.json
From this issue solution
Install cpx and scss-bundle as Dev dependencies to your package.json. Then add the following entries in your package.json "scripts" property:
"scripts": {
...
"build-mylib": "ng build mylib && npm run build-mylib-styles && npm run cp-mylib-assets",
"build-mylib-styles": "cpx \"./projects/mylib/src/lib/style/**/*\" \"./dist/mylib/style\" && scss-bundle -e ./projects/mylib/src/lib/style/_style.scss -d ./dist/mylib/style/_styles.scss",
"cp-mylib-assets": "cpx \"./src/assets/**/*\" \"./dist/mylib/assets\"",
...
}
Replace "mylib" with your real library name and then just run in your terminal build-mylib. That would compile your scss assets to your dist folder.
You use this global styles in your actual Angular project just import them in your angular.json file within your project settings:
"styles": [
"src/styles.scss",
"dist/my-shiny-library/_theme.scss"
],
(use dist if your project is in the same workspace, or node_moduled if its an imported library)
1- be sure you are putting your styles inside the library
example:
projects/your-lib-name/assets/styles.css
2- then in your ng-package.json (in the lib for sure) put the assets rule
{
"$schema": ... ,
"dest": ... ,
> "assets": [
> "./assets/*"
> ],
"lib": ...
}
3-
in your application, you can use this asset
"styles": [
"../your-lib-name/assets/styles.css"
]
this is a tutorial
I have a project that bundles the client-side files using Webpack. We are bundling the CSS using the ExtractTextWebpackPlugin. The problem is when I edit a javascript file the CSS bundle always gets re-built despite there being absolutely no changes to the CSS state.
How can I bundle CSS but only when there are changes to the CSS files?
Extracted from my webpack config:
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader'
})
},
...
plugins: [
new ExtractTextPlugin(isDebug ? '[name].css' : '[name].[chunkhash].css')
],
whenever ExtractTextPlugin sees a import statement with css extension it will automatically extract the text contant of that css file whethere it changes or not
if you are using it to debug then use style-loader and HMR(Hot Module Replacement) for better experence something like this
isDebug
? {
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
: {
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: "css-loader"
})
}
if you want to use current configration and don't want ExtractTextPlugin to build css file and you are importing them in your javascript file using import then somehow you have to remove import statement for css files when there is no change in that css file
and if you are adding css file in your webpack config entry section then it would be easy because webpack allow custom command argument and you can do this by exporting a function in your webpack config file insted of object
//webpack.config.js
module.exports = function(env) {
return {
entry: {
main: env.includeCss
?
["./src/index.js", "./src/main.css"] //build with css
: ["./src/index.js"] //build without css
},
.
.
.
.
}
}
you can pass env.includeCss by command argument like this
webpack --config ./webpack.config.prod.js --env.includeCss
//notice --env.includeCss witch will set env.includeCss as true
run with --env.includeCss normally and without --env.includeCss when you dont want to compile css file
Not directly related to your question but I noticed you use [chunkhash] for extracted CSS. This will make your css name change even if you haven't change content in you CSS files.
Use [contenthash] instead.
https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/#setting-up-hashing
If you are using ExtractTextPlugin, you should use [contenthash]. This way the generated assets get invalidated only if their content changes.