'Is it possible to build an Angular app without embedded styles?
My company is going through a re-branding and it involves some color changes to our app. Most of this is just tweaking SCSS variables, but i'd like to be able to demo the app with a 'theme-switcher', where I can toggle between 2 stylesheets.
I built the app twice - once with the old SCSS variables, and one with the new. However, when switching between the two stylesheets, the changes are not totally reflected due to embedded styles in the <head>
I searched around a lot and it seems like no one else is asking this question. Does anyone know how to get rid of these and have them included inside the stylesheets instead (using --extract-css
during the build), or even why some styles are extracted to the stylesheet and why some are included in embedded styles?
The relevant part of my angular.json is below, if needed.
"projects": {
"cd": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/cd",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"styles": [
"src/styles.scss",
{
// I put this in here thinking I could re-declare all the color variables in newtheme.scss and when the bundle was created it would rewrite all of the styles that used those variables too. No dice.
"input": "src/assets/css/newtheme.scss",
"bundleName": "newtheme",
"inject": false
}
],
"stylePreprocessorOptions": {
"includePaths": ["src/assets/css"]
},
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
},
Solution 1:[1]
I realized my app was doing the same thing.
I've had a couple issues related to using scss/sass and getting different outcomes than desired.
- References to
/assets/*
results in the build sometimes placing these in the root of thedist/project/
folder. This also seems to cause a duplication with files already present. My take away from this is since CSS is loaded in the root of the HTML it should have a./asset
relative path to the folder not '/asset' root linux server or depending on how the app is hosted ends up causing some issues.--base-href=./
at least in my build did nothing for these final css results. I think they may have done this for cache-busting. But any/asset
reference for me causes things like Fonts loading etc if the site happens to be more portable in sub directories etc. - (Your issue) There was an optimization/tree-shaking option further in the documents that doesn't come out-of-the-box. See https://angular.io/guide/workspace-config#optimization-configuration
angular.json
...
"outputHashing": "all",
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false <---- this
},
"fonts": true
}
...
This solved the inline duplication of <styles>
in the <head>
, but I still have several images get hashed in the root of the project. (opinion) Is it the end of the world - No. Is is cluttered. Yes.
One workaround I performed was changing the /asset
references to ^asset/
since I mainly use S3/CloudFront and invalidate caches.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |