I am building a sass compiler with nodejs, electron, and node-sass.
There will be a config file that will describe some "sass compilers" for many projects and the user will have the ability to activate and deactivate them through a GUI.
I managed with "electron" to create the interface and with the use of electron`s "ipcmain" to initiate the compilers on demand.
To init a compiler, I spawn a child process which encloses the whole compiler.
The compilation is done with following code:
var result = this.sass.renderSync({
file: 'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\scss\\style.scss',
outFile: 'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\css\\style.css',
includePaths:[
'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\scss\\',
'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\scss\\foundation\\components\\'
]
});
I execute the compilation using absolute paths but the files us relative paths.
I run my program/gui and activated the compiler and I got a CSS file.
The problem is that some imports are missing.
My root folder is at 'C:\Users\George\Desktop\css_compiler_tests\test3\'.
I try to compile 'scss\style.scss' which imports 'scss_inculded-files.scss'.
The file 'scss_inculded-files' imports 'scss\foundation.scss' which imports form 'scss\foundation\components'.
Here is an example:
/*scss\style.scss*/
#import "included-files";
/*scss\_inculded-files.scss*/
#import
"includes/fonts",
"includes/custom-colors",
"includes/foundation-custom-settings",
"foundation/settings",
"foundation";
/*scss\foundation.scss*/
#import
"foundation/components/grid",
"foundation/components/accordion";
The content of the two last imports is missing.
Finaly I tried from command line and got the same error:
D:\mytests\nodejs\nodeSass> node_modules/.bin/node-sass C:\Users\George\Desktop\css_compiler_tests\test3\scss\style.scss -o C:\Users\George\Desktop\css_compiler_tests\test3\scss\ --include-path C:\Users\George\Desktop\css_compiler_tests\test3\scss\
Is there a way to include those missing files?
Thank you in advance.
Edit 1
After some experimentation I found out that the Mixins are the problem.
Let say I have a Mixin like that:
#mixin headline($size, $color: $base-color) {
color: $color;
font-size: $size;
}
It is compiled perfectly if I call it like that:
h1 {
#include headline($color: blue, $size: 12px);
}
If I don't call it isn't compiled.
I am using Foundation Zurb framework which I believe auto includes the mixins.
Related
I am developing a WordPress theme and I am trying to use sass from another file using the #use method but it doesn't seem to be working. How can I fix the problem since the #import rule method will be depreciated soon?
I have files
//_brand.scss
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
and then
//footer.scsss
#use 'brand' as b;
.footer{
padding: 0px 5%;
background-color: b.$base-color;
}
and I get this error when it's compiling
Compilation Error
Error: Invalid CSS after "...ground-color: b": expected expression (e.g. 1px, bold), was ".$font-size;"
on line 5 of sass/opt/lampp/.../sass/footer.scss
>> background-color: b.$base-color;
I am using "Live Sass Compiler" visual studio code extension to compile to CSS
If you want to use the variables you have defined within the brand.scss file across different files, you can use the #import directive. For using it, just add the line below to your footer.scss file:
#import "brand";
Source: https://www.w3schools.com/sass/sass_import.asp
I hope my answer will help you
I do already have SCSS variables defined in src/styles/settings/_variables.scss and I am importing them into src/styles.scss, but still these variables aren't available for every single component.
Is there any way to make a global file which holds all SCSS variables for the rest of my components? Because writing #import in every single component .scss file it is very frustrating, especially if I have many nested components.
I know, there is a lot of similar questions, but it seems like they're all outdated and do not relate to the recent versions of Angular.
I use Angular 7.3 with CLI.
You just need to add a little more config, so where you are declaring your global variables, you need to wrap it up in :root{}. So in src/styles/settings/_variables.scss.
:root
{
--blue: #00b; // or any global you wish to share with components
}
Then when you use them in the SCSS you will need to access them like so.
.example-class {
background-color: var(--blue)
}
To add to this regarding comments, this method can use mixins, #media and keyframes and is not limited to just colours / font. That was an example.
From my understanding you need a global file src/assets/style/global and then to import each scss file into there where you are defining them like so.
#import 'filename';
If you dont want global variables to be used in within a component look when you have the globals working. Look into ViewEncapsulation, as this can be used to ignore them.
Is there any ways to make global file with scss variables available for all components?
Without importing global file everytime in each component, you want those sass variables been available, it's not possible.
The way it works in SASS, if using partials to better organize code, you can apply #import directive for referencing. So if there're some sass variables in shared/_variables.scss:
$lightslategray: #778899;
$darkgray: #A9A9A9;
and these variables need to be used in another stylesheet, stylesheet with them must be #import-ed into it firstly:
// Shared
#import "shared/variables";
.content {
background: $lightslategray;
}
In Angular it works in a similar way (related referencing external stylesheet). So if you need some sass variables, mixins or functions to be used by a particular component.scss, there is no other clean way, but to reference them in that component.scss using #import directive. To ease the task, you can create a file src/_variables.scss and use syntax like this in your component.scss:
#import “~variables.scss”;
step one : go to custom scss file (shared/css/_variable.scss) and write this part
:root{
--color-text: red;
--color-btn-success: green;
}
after go to style.scss (this is main file) and import this file :
#import './shared/css/Variables';
now you can use variables in all components with this Syntax:
.sample{
color : var(--color-text);
}
Easily possibe to access sass style(s) from a global file with two steps.
Add folder path of the style files to includePaths array in angular.json file.
Import style file by file-name in any component.
let say your files and folder structures is as follows: src > my-styles-folder > var.scss
angular.json
"architect": {
"build": {
...
"options": {
"stylePreprocessorOptions": {
"includePaths": [
"src/my-styles-folder" // add path only, do not include file name
]
},
"styles": [
...
]
}
...
}
}
some-component.scss
#import "var"; // var.scss
mat-toolbar {
height: $toolbar-height;
}
In angular 8 work for me.
In your _variable.scss file you have to add:
:root{--my-var:#fabada}
After that go in your angular.json and add this in "styles":
{"input":"yourPath/_variables.scss"}
I'm struggling with the dotLESS #import to have a separate variables file; I just constantly get "variable is undefined".
If I browse to the variable config file it works; if I put the variables inline in the main stylesheet it works; but in an #import, no dice. I'm mapping .css as well as .less to the extension, however it also doesn't work if I use .less only.
The variables file LESS-config.less is:
/*
.LESS VARIABLES
*/
#mbw_dark_cyan: #1293b5;
#mbw_cyan: #11add4;
#mbw_magenta: #e935da;
#control_text: #ffffff;
#action_delete: #ff5400;
#section_level1_bg: #mbw_dark_cyan;
#section_level1_fg: #control_text;
#button_bg: #mbw_dark_cyan;
#button_fg: #control_text;
#button_icon: #control_text;
#data_table_header: #mbw_cyan;
.dummy {
color: #control_text;
}
Which renders as:
/*
.LESS VARIABLES
*/
.dummy {
color: #ffffff;
}
Calling stylesheet main.css is:
#import (less) '/css/LESS-config';
button {
background: #button_bg;
}
Which gives the error:
variable #button_bg is undefined on line 4 in file '/css/main.css':
[3]: button {
[4]: background: #button_bg;
----------------^
[5]: }
As I said, if I replace the import with the same variables copied and pasted, it all works fine.
I've tried saving without BOM as in another answer, but that doesn't help.
EDIT, I've tried:
Removing the (less)
Changing to double quotes
Using relative path LESS-config as opposed to virtual absolute as above
Adding logger="dotless.Core.Loggers.AspResponseLogger" log="debug" to
web.config (cache is already false)
Adding debug="1"
Adding
debug="true"
Absolutely no change in behaviour.
EDIT 2:
I created a cut-down css that only had the import statement in it; when I browse to it the imported styles are in there. However, on a refresh, I just get a blank response.
So it seems to be something to do with my IIS config / caching? I've turned off content compression but no joy; disabled all output caching for .less and .css, still no joy!
FIXED as per Toni's comment; https://stackoverflow.com/a/51754771/318411:
This turned out to be a dotLESS issue, tracked on GitHub here: https://github.com/dotless/dotless/issues/553
The complete fix was to:
Upgrade dotLESS to version 1.6.7
Downgrade Microsoft.Extensions.DependencyInjection to 1.1.1.0 due to Method
not found error
Change the file extension of the import from .css to .less
Now all working.
Please try version 1.6.7 which fixes an error that imports are only executed on the very first request.
I potentially see two problems that you have.
You are trying to call #import (less) in a css file. This is a syntax specific to less framework.
Your main.css is not a less file.
Change your main.css to a main.less file and now try generating your css from main.less as your root file.
Assuming your import url for LESS-config.less is correct.
The above mentioned corrections should probably do the trick.
#import (less, optional) "mystyle.css"; is Less syntax, you cannot use it in CSS (Less #import Rules).
If you want to use #import in your CSS, it should follow this syntax (See here)
#import url|string list-of-mediaqueries;
But, you cannot import a Less file inside your CSS anyways.
The way I would have done this:
Say you have 3 .less files: config.less, color.less, header.less
I would create a style.less file with the following content:
/*------------------------------------------------------------------------------*/
style.less
/*------------------------------------------------------------------------------*/
/* 01. config */
#import "config.less";
/* 02. color */
#import "color.less";
/* 03. header */
#import "header.less";
Then I would complie style.less which would produce, style.css and I would include style.css in my website.
I have my application sass (in scss files) in various subdirectories within my styles directory, some of which #extend sass styles from various vendors which, (via bower) are in various subdirectories under the vendor directory.
Unfortunately the sass task fails to pick up those vendor scss files and any #extend declarations I have fail as they can't find the sass they're trying to extend from, e.g.
Error in plugin 'sass'
Message:
styles/censum/censum.scss
Error: ".graph-row" failed to #extend ".row".
The selector ".row" was not found.
Use "#extend .row !optional" if the extend should be able to fail.
on line 2 of styles/censum/censum.scss
My minimised example is as follows.
gulp.task('sass', function () {
gulp.src('./styles/**/*.scss')
.pipe(gulpSass({ includePaths: ['./vendor'] }).on('error', gulpSass.logError));
});
I also tried adding the vendor directories to gulp.src and not using includePaths, e.g.
gulp.task('sass', function () {
gulp.src(['./vendor/**/*.scss', './styles/**/*.scss'])
.pipe(gulpSass().on('error', gulpSass.logError));
});
which does seem to reference the vendor files (as it drags everything in I guess), but I do get failures along the lines of:
Message:
vendor/bower/eonasdan-bootstrap-datetimepicker/src/sass/_bootstrap-datetimepicker.scss
Error: Undefined variable: "$btn-primary-bg".
on line 7 of vendor/bower/eonasdan-bootstrap-datetimepicker/src/sass/_bootstrap-datetimepicker.scss
$bs-datetimepicker-active-bg: $btn-primary-bg !default;
which is possibly an ordering issue?
What I'm sharing is based on my understanding of your question. I'll discuss it from the perspective of a new project, which seemed to work fine for me.
Let's assume we have a project called sassy and inside it is a package.json file created by running the following:
npm init -y
Then we are going to install Gulp and the SASS component like so:
npm install gulp gulp-sass -save-dev
Inside a Gulpfile.js at the root of our project we have the following code:
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('sass', function () {
return gulp
.src("./scss/**/*.scss")
.pipe(sass({includePaths: ['./vendor']}))
.pipe(gulp.dest("./dist"));
});
As you can probably guess from the above code, we have a vendor directory and a scss directory at the root of our project.
Since I don't know what is in your vendor directory, I've populated mine with randomness. Inside a vendor/colors.scss file I have the following:
.danger {
color: red;
}
.light {
color: silver;
}
I also have a nested file found at vendor/sizing/article.scss with the following code:
.title {
font-size: 22px;
}
Now let's take a look at what is inside my scss directory.
I have a scss/main.scss file with two import statements like follows:
#import "./sidebar/navigation";
#import "./content/blog";
Again, all of this project is randomness. I'm just trying to show the build process from all these files and directories.
I have two more SCSS files in my scss folder. I have a file scss/sidebar/navigation.scss with the following code:
nav {
padding: 10px;
}
Finally I have a file with a bunch of imports and extends. This file is scss/content/blog.scss and it contains the following:
#import "colors";
#import "sizing/article";
.title {
#extend .danger;
#extend .title;
font-weight: bold;
}
Because the Gulp script is including the vendors directory, we can use relative paths for any of the files. We import the two files from the vendor directory and then extend various classes where necessary.
Running gulp sass will build the CSS files in the project's dist directory. Since I only used scss/main.scss for imports, it will contain all our styles.
Is this what you were trying to do? If yes, run through everything I just shared and see if it works for you.
IncludePaths takes a string array.
Try updating to the following.
gulp.task('sass', function () {
gulp.src('./styles/**/*.scss')
.pipe(gulpSass({ includePaths: ['./vendor'] }).on('error', gulpSass.logError));
});
See docs:
https://github.com/sass/node-sass#includepaths
How can I reference a variable defined in a central variables.less file in an individual module.less file, when the module does not directly reference variables.less?
Here's the structure of my Styles folder:
Styles
_variables.less
Site.less
Modules
_forms.less
_navbar-top.less
_panels.less
_titlebar.less
Modules.less
Pages
_page1.less
_page2.less
Pages.less
The file Site.less basically looks like this:
#import "_variables.less";
#import "Modules/Modules.less";
#import "Pages/Pages.less";
(it only includes capitalized LESS files)
And Modules.less looks like:
#import "_forms.less";
#import "_navbar-top.less";
#import "_panels.less";
#import "_titlebar.less";
(it only includes underscore-prefixed files in the same folder)
Pages.less is structured the same way.
What I want to do is have the following in the Modules/_panels.less file:
.panel-form {
.panel-variant(1px; #text-color; #component-default-bg; 1px);
border-top: solid darken(#component-default-bg, 1px);
border-bottom: solid darken(#component-default-bg, 1px);
border-left: none;
border-right: none;
}
But of course my LESS compiler (Visual Studio Web Essentials 2013.5) is throwing an error and refusing to compile the file _panels.less because it is referencing a variable that does not exist in its scope.
Currently my workaround is to declare .panel-form in Site.css but that is a hack -- I don't want to start declaring an arbitrary number of modules there.
Is it possible to reference a variable like this and still compile to CSS, and if so how? If not, is there a better structure I should use?
Incidentally I noticed that the LESS compiler doesn't like Bootstrap either, because it raises errors if I type a single space into a Bootstrap LESS file e.g. navbar.less and try to save it, reporting that (for navbar.less) the mixin .clearfix() is undefined. Which of course it is, because navbar.less does not reference mixins.less, yet if it can compile from bootstrap.less downward then everything will work just fine...
I don't know what is your environment but with triple slash directives it usually works:
root
less
_vars.less
modules
someModule.less
Inside "someModule.less" you should try this:
/// <reference path="../_variables.less" />