I am struggling to convert an Angular 2 project to Angular 4 using angular-cli and webpack. I am running into an issue accessing image assets from my scss files. I believe that my problem is being caused by the way that the directory structure of my scss files are being flattened. Within the src directory of my project I have a stlyes sub-directory and an assets sub-directory (which is a sibling of the styles directory). Both directories have nested child directories. My current belief in that the assets directory when packaged has keeps its sub-directory structure and the styles directory is flattened, thus causing relative references to assets from the flattened css to be incorrect.
For example /src/styles/partials/_sprite.scss:
.icon {
background: url("../../assets/images/sprite-svg-ui.svg") no-repeat;
}
Within my IDE this reference resolves correctly, but when built by the angular-cli I get the following error:
ERROR in ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader?{"ident":"postcss"}!./~/sass-loader/lib/loader.js?{"sourceMap":false,"precision":8,"includePaths":[]}!./src/styles/index.scss
Module not found: Error: Can't resolve '../../assets/images/sprite-svg-ui.svg' in 'C:\Users\jhart\Desktop\pascal.ui\src\styles'
# ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader?{"ident":"postcss"}!./~/sass-loader/lib/loader.js?{"sourceMap":false,"precision":8,"includePaths":[]}!./src/styles/index.scss 6:43140-43188
# ./src/styles/index.scss
# multi ./src/styles/index.scss
Here's my .angular-cli.json file:
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"project": {
"name": "ui"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets"
],
"index": "index.html",
"main": "index.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"./styles/index.scss"
],
"scripts": [
"dot.dot.dot.js"
],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {},
"serve": {
"port": 3000
}
}
}
Here's my index.scss file referenced within the within the apps\styles element of the .angular-cli.json file:
// globals
#import 'functions';
#import 'variables';
#import 'mixins';
#import 'base';
#import 'boxer';
// partials
#import 'partials/grid';
#import 'partials/sprite';
#import 'partials/typography';
#import 'partials/buttons';
#import 'partials/forms';
#import 'partials/tables';
#import 'partials/utility';
// vendors
// #import 'vendors/chosen';
#import 'vendors/chartist/chartist';
#import 'vendors/ng2-select';
// component (declarations)
#import 'partials/wrapper';
#import 'partials/header';
#import 'partials/navigation-primary';
#import 'partials/footer';
#import 'partials/upload-meter';
#import 'partials/pagination';
#import 'partials/breadcrumb';
#import 'partials/tabs';
#import 'partials/cards';
#import 'partials/badges';
#import 'partials/flyouts';
#import 'partials/comments';
#import 'partials/tutorial';
#import 'partials/year-selector';
#import 'partials/upload-window';
#import 'partials/panels';
#import 'partials/charts';
#import 'partials/lists';
#import 'partials/collapse';
#import 'partials/tooltips';
#import 'partials/login';
#import 'partials/settings';
#import '../app/modules/core/components/notification-banner/styles';
// component (declarations)
#import 'partials/cbcr-view';
// directives
#import '../app/modules/core/directives/menu/menu';
Update 1
I have discovered that referencing the image assets via an absolute path /app/assets/images/ allows build to resolve the image files, but now the reference to the image files within my IDE are invalid...
When running the application build with the absolute path /app/assets/images/ I get a 404 when loading an image file...
Update 2
I changed the prefix parameter in my .angular-cli.json to "" and then from my /src/styles/partials/_sprite.scss file I reference my image assets using an absolute path /assets/images/, for example:
.icon-close {
background: url("/assets/images/close.svg") no-repeat;
width: 24px;
height: 24px;
}
My IDE is still unable to resolve the images files... but at least it builds and executes.
I faced this problem and I solved it by putting the absolute path of the image depending on the location of the "index.scss" file in your case, not depending on the imported sub-sass file "_sprite.scss". This will give you an error a reference error from the IDE but it will work you won't get an error from webpack. I hope it helps.
Related
My _variables.scss and _mixins.scss partials do not seem to be picked up when I compile my Sass files. My _globals.scss and _header.scss are picked up fine, even though they are in the same directory and accessed the same way.
In my style.scss file:
#use "globals";
#use "header";
Terminal error messages:
Error: Undefined mixin.
#include breakpoint-down(medium){display: none;}
Error: Undefined variable.
color: $grayishBlue;
I used a package.json code to compile my sass, with a few tweaks. Here is what mine looks like:
{
"name": "project",
"version": "0.1.0",
"description": "SASS compile|autoprefix|minimize and live-reload dev server using Browsersync for static HTML",
"main": "public/index.html",
"author": "5t3ph",
"scripts": {
"build:sass": "sass --no-source-map src/sass:public/css",
"copy:images": "copyfiles -u 1 ./src/images/**/* public",
"copy:html": "copyfiles -u 1 ./src/*.html public",
"copy": "npm-run-all --parallel copy:*",
"watch:images": "onchange 'src/images/**/*' -- npm run copy:html",
"watch:html": "onchange 'src/*.html' -- npm run copy:html",
"watch:sass": "sass --no-source-map --watch src/sass:public/css",
"watch": "npm-run-all --parallel watch:*",
"serve": "browser-sync start --server public --files public",
"start": "npm-run-all copy --parallel watch serve",
"build": "npm-run-all copy:html build:*",
"postbuild": "postcss public/css/*.css -u autoprefixer cssnano -r --no-map"
},
"dependencies": {
"autoprefixer": "^10.4.2",
"browser-sync": "^2.27.7",
"copyfiles": "^2.4.1",
"cssnano": "^5.0.17",
"npm-run-all": "^4.1.5",
"onchange": "^7.1.0",
"postcss-cli": "^9.1.0",
"sass": "^1.49.8"
}
}
_globals.scss file:
#use "variables";
#use "mixins";
html {
font-size: 100%;
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
font-family: 'Public Sans', sans-serif;
font-size: 1.125rem;
font-weight: 300;
color: $grayishBlue; //if i comment out this line, i get an error //for mixins.
line-height: 1.3;
}
// and so on... until we get to the styles that use the mixin.
//Visibility
.hide-for-mobile {
// hide for mobile and tablet
#include breakpoint-down(medium){
display: none;
}
}
.hide-for-desktop {
//hide for desktop viewport widths
#include breakpoint-up(large){
display: none;
}
}
_header.scss file:
#use "variables";
.header {
nav {
padding: 24px;
}
//and so on... variables are used twice in this module.
File hierarchy in the sass folder is as follows:
- sass
- _globals.scss
- _header.scss
- _mixins.scss
- _variables.scss
- style.css
- style.css.map
- style.scss
As stated in the doc:
Members (variables, functions, and mixins) loaded with #use are only visible in the stylesheet that loads them. Other stylesheets will need to write their own #use rules if they also want to access them.
Which means that in order to read your variables and mixins, you need to import them directly in the files that use them and not on your global styles file.
On _globals.scss and _header.scss add:
#use "variables" as *;
#use "mixins" as *;
Additionally, if you don't want to import both files every time, you can create a new file that will forward them and then import only this file:
// _settings.scss (or any other name)
#forward "variables";
#forward "mixins";
// _globals.scss & _header.scss
#use "settings" as *;
When building my angular 12 solution for production, styles are not applied. Following online docs I have taken the following steps:
I have
"styles": [ "src/styles.scss" ]
in my angular.json file, and in styles.scss I import tailwind:
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
In my tailwind.config.js I have:
module.export = {
purge: {
enabled: true,
content: ["./src/**/*.{html,ts}"]
},
...
}
but styles are still not applied. What else do I need to do to get styles to apply correctly?
I have modular CSS (using Sass) and my webpack is throwing errors when I use Tailwind's #apply with some classes. Some of them works, some don't and I can't figure out why. It's working inline in HTML but not in CSS file.
gallery.scss
.c-gallery-thumbnails {
#apply space-x-3;
}
base.scss
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
import "gallery"
webpack
module: {
rules: [
{
test: /\.[ps]?css$/,
use: ExtractTextPlugin.extract({
use: [
'css-loader',
'resolve-url-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
],
},
},
'sass-loader',
],
}),
},
...
And error:
#apply cannot be used with .space-x-3 because .space-x-3 either cannot be found, or its actual definition includes a pseudo-selector like :hover, :active, etc. If you're sure that .space-x-3 exists, make sure that any #import statements are being properly processed before Tailwind CSS see
s your CSS, as #apply can only be used for classes in the same CSS tree.
Have a read of this: https://tailwindcss.com/docs/using-with-preprocessors/
For the most cohesive development experience, it's recommended that you use PostCSS exclusively.
Please try to import the .css file where space-x-3 css rule is defined in gallery.scss.
In my packages.json file by default I get:
"postcss": {
"plugins": {
"autoprefixer": {}
}}
When I add <style lang='scss'> It doesn't compile like magic like it does for Typescript support. I know I will need to specify some NPM package as devDependencies and specify something above in the postcss section to get scss to compile, but I can't find any documentation outside of webpack so I am lost.
See https://vue-loader.vuejs.org/guide/pre-processors.html.
For example, to compile our <style> tag with SASS/SCSS:
npm install -D sass-loader node-sass
In your webpack config:
module.exports = {
module: {
rules: [
// ... other rules omitted
// this will apply to both plain `.scss` files
// AND `<style lang="scss">` blocks in `.vue` files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
Now in addition to being able to import 'style.scss', we can use SCSS
in Vue components as well:
<style lang="scss"> /* write SCSS here */ </style>
Any content inside the block will be processed by webpack as if it's
inside a *.scss file.
I have a project where I use the ReactTS template of DotNet. I installed SCSS and everything works, except for backgrounds.
The images and scss are compiled to dist folder (scss in the style.css file). All images are compiled correctly and can be called using normal css, but the problem is the scss, as the url() also contains dist in front of the actual url, while the css file itself is already in the dist folder. This means that the css looks for an image inside of /dist/dist/{image}.png} instead of /dist/{image}.png}.
Since I can't just directly edit the dist/style.css file, how can I make sure the path will be the correct one?
Edit: After changing the URL in the inspector, I can confirm that /dist/{image}.png} would indeed work. The problem is that inside of the css, it sais background-image: url('dist/{image}.png), where it should only be url('{image}.png. This is inside the css file that is generated in the dist folder.
Edit 2:
Uncompiled site.scss
html {
background-image: url('../img/backgrounds/background1.jpg');
background-size: cover;
...
}
Compiled style.css
html {
background-image: url(dist/fc5316d2f76725be344cc36eb98c28f7.jpg);
background-size: cover;
}
Folder structure
├───ClientApp
│ ├───css
| | └───site.scss
| └───img
| └───background1.jpg
└───wwwroot
└───dist
├───style.css
└───fc5316d2f76725be344cc36eb98c28f7.jpg
Edit 3:
webpack.config.js
...
output: {
path: path.join(__dirname, bundleOutputDir),
filename: '[name].js',
publicPath: 'dist/'
},
module: {
rules: [
...
{ test: /\.s?css$/, include: /ClientApp/, use: ExtractTextPlugin.extract({ use: ['css-loader', 'sass-loader'] }) },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url-loader?limit=25000' }
]
},
plugins: [
...
new ExtractTextPlugin({
filename: 'style.css'
})
]
...