Combining Multiple SASS files into one SASS file - sass

Does anyone know if there is a way to combine multiple SASS/SCSS files into one SASS/SCSS file. I do mean "into one SASS/SCSS" and not into a CSS file.
For example, I have 3 scss files:
app.scss
base.scss
layout.scss
The app.scss file contains 2 imports to base.scss and layout.scss.
I would like to beable to generate 1 SCSS file that basically concatenates the files and does not process the sass.
It's fairly difficult to search for as everything that gets return is to do with combining into CSS.
Why would I want to do this? Basically, I'd like to easily reference a set of SCSS files from within a codepen (other online code editor).
Thanks

I analyze all files by the mask, find all imports inside and concatenate into one file. So I don't need one entry point
npm install -D bundle-scss
"script": {
"postbuild": "npm run themes",
"themes": "bundle-scss -m \"./src/**/*.theme.scss\" -d \"./dist/themes.scss\""
}

scss-bundle solves this problem
https://github.com/reactway/scss-bundle
Caution: Does not support newer module based imports. Issue #90

You could modify this for javascript. Kept it in typescript as I am currently solving this issue on my own (angular 6 library), and ran into this question.
According to the docs, angular material uses this implementation.
import * as path from 'path';
import { Bundler } from 'scss-bundle';
import * as fs from 'fs';
(async () => {
// Absolute project directory path.
// Assuming all of your scss files are in `./projects/my-library/src/styles`
const projectDirectory = path.resolve(__dirname, './projects/my-library/src/styles');
const bundler = new Bundler(undefined, projectDirectory);
// Relative file path to project directory path.
// The name of your file here would be `app.scss`
// Kept this here if anyone runs into this answer and wants to do this with the new angular 6 library.
const { found, bundledContent } = await bundler.Bundle('./_all-theme.scss');
if (found && bundledContent) {
// where you want to save the file, and what you would like it to be called.
const location = path.resolve(__dirname, '_theming.scss');
fs.writeFileSync(location, bundledContent);
}
})();

Related

How to include SCSS Glob in a Gatsby project?

I am currently working on setting up a boilerplate that uses Gatsby. Everything so far has been very simple and easy to use, but I can't seem to fix one problem, which is getting SCSS glob hooked up with my global SCSS styling.
I currently have localized SCSS styling for each component. However, I also have a styles directory for my global styles(variables, typography...ect). This is also using SCSS and is working great. Now the last thing I want to do is get SCSS glob working so I can do imports like /**/*.scss within my global styles.
Currently, I am using the gatsby-plugin-sass and have included globImporter as an option within my gatsby-config.js file. However, it does not seem to do it for me.
From what I read node-sass-glob-importer should be what I need but no luck so far.
My configuration looks like the following
{
resolve: `gatsby-plugin-sass`,
options: {
importer: globImporter(),
cssLoaderOptions: {
camelCase: false,
},
},
},
I then try to do a global import in my scss like so #import "./**/*.scss"; but I get the following error:
An #import loop has been found:
has anyone set up scss glob on gatsby or see anything wrong with my configurations.
Thanks
If you're still having this issue (or in case anyone else is), here's what worked for me:
options: {
importer: function(url, prev, done) {
// url is the path in import as is, which LibSass encountered.
// prev is the previously resolved path.
// done is an optional callback, either consume it or return value synchronously.
// this.options contains this options hash, this.callback contains the node-style callback
var result = globImporter();
return {file: result.path, contents: result.data};
}
},
It was inspired by the example code on in the node-sass repo.
Make sure to also include var globImporter = require('node-sass-glob-importer') at the top of your file.

Is it possible to write (via sass commands or compiler directives) code such that SASS will output the final values of all variables to a JSON file?

How can I compile a SASS file and have it output all the final values of every variable in a json file
I asked a similar question before and someone on here thought I was trying to get you guys to do my job. I'm just trying to see if it's possible at all before I go down a path that ultimately is a waste of time. If it is possible, I don't know the magic sauce to get started.
I have CMS themes that are built on bootstrap-sass, and other sass frameworks, and I'd like my CMS to be able to access variables that we use in the SASS files as well. Seems to me that if when I compiled the SAAS file, I got a CSS, MAP, and JSON file, I'd be all set.
I could write this as some kind of mixin, but even then, I'd need to be able to get
A list of all variables
a command to output json to the dist folder.
Any pointers on these items are appreciated.
If you're using Gulp to compile your SASS there is a plugin that accomplishes this.
https://www.npmjs.com/package/gulp-sass-json
After installing it, and given the following Gulpfile.js:
var sassJson = require('gulp-sass-json');
var paths = {
'json_root' : './bundles/theme/scss/variables/*.scss',
'json_dest' : './json'
};
var sassOptions = {
errLogToConsole: true,
outputStyle: 'expanded'
};
gulp.task('sass-json', function () {
return gulp
.src(paths.json_root)
.pipe(sassJson())
.pipe(gulp.dest(paths.json_dest));
});
gulp.task('default', ['sass-json']);
Given the SCSS file variables/colors.scss:
$red: #ed1414;
$blue: #0351e0;
$green: #259208;
Outputs the following json at ./json/colors.json
{
"red": "#ed1414",
"blue": "#0351e0",
"green": "#259208"
}
So in order to have it re-output it every time you compile, you can just create a task that encompasses this task as well as your normal style compile task.

How can I set a sass variable using an environment variable?

I'm using Gulp as my build system.
I need to identify links pointing to external websites with the scss following rule:
// Links to external websites
a[href*='//']:not([href*='example.com']) {
&::after {
content: ' \e895';
font-family: 'Material Icons';
}
}
OR
$baseURL: 'localhost:3000'; // Set this variable based on environment
a[href*='//']:not([href*='#{$baseurl}']) {
...
}
When I'm running a development server the address I'm serving files from is localhost:3000, not example.com. The result is that every single link on the website (on the dev server) has a small icon indicating the link goes to an external website, which is really distracting.
What's the best way to set a scss variable based on an environment setting?
Edit:
This solution works, but it introduces a temporary file, which I'm not wild about. I moved my _variables.scss into the scss root, I process this file and output it into the base subdirectory where it is used to compile the scss. I would then add scss/base/_variables.scss to my .gitignore to avoid committing to version control.
_variables.scss
$baseURL: '/* #echo PATH */';
Gulpfile.js
// Set baseurl as Sass variable -- used to identify external links
gulp.task('sass-vars', function () {
var baseURL = (config.production) ? 'example.com' : 'localhost:3000';
return gulp.src('./scss/_variables.scss')
.pipe($.preprocess({context: {PATH: baseURL}}))
.pipe(gulp.dest('./scss/base'));
});
Yes, it is possible to do that.
To get environment variables there's a package: gulp-env
To remove these links from static files: gulp-preprocess
But it's also important to check these changed files, not to commit them as a development version. Hooks to your VCS is an option.

Laravel elixir compile multiple less files

I have this two files in resources/assets/less folder style.less and admin/style.less. I want to compile this files to diffrent paths as the following:
style.less compiled to public/css/
and the other one compiled to public/admin/styles/
this is What i did in the gulpfile.js
elixir(function(mix) {
mix.less('style.less', 'public/css/');
mix.less('admin/style.less', 'public/admin/styles/');
});
but this compile only one file.
What is the problem and how can i fix this issue?
I have a project that compiles two different less files to two different css files.
The only difference that I see is that I specify the full destination path including the file name.
So, for your case, it will be:
elixir(function(mix) {
mix.less('style.less', 'public/css/style.css')
.less('admin/style.less', 'public/admin/styles/style.css');
});
I have not got the answer for this yet. But have tried some alternatives, thought will share.
I was thinking we can do like below
elixir(function(mix) {
mix.less('style.less', 'public/css/')
.less('admin/style.less', 'public/admin/styles/');
});
But according to the documentation we can't make multiple call to sass or less method. So it is only compiling the latest less file (which in this case admin/style.css).
We can do like this
elixir(function(mix) {
mix.less(['style.less', 'admin/style2.less'], 'public/css/');
});
but this will compile both into the same folder.
Hoping to know, how can we do it to different folders.
I tried copying the second file into a separate folder, but that also doesn't work
elixir(function(mix) {
mix.less(['style.less', 'admin/style2.less'], 'public/css/')
.copy('public/css/style2.css', 'public/admin/style.css');
});
Probably this is because each requests are async and when the copy is getting called, that time the style2.css is not ready yet.
mix.less('resources/assets/less/app.scss', 'public/css').
less('resources/assets/less/admin/style.less', 'public/admin/styles');

Laravel elixir - don't generate map files

The question is - how to force Laravel Elixir not to generate map files?
At the moment if I run gulp I will have generated app.css and app.css.map file. I don't know what for is this app.css.map file but I think it's not necessary for me at the moment. Question is - how to force gulp not to generate this file?
At the moment my gulpfile.js looks like this:
var elixir = require('laravel-elixir');
elixir(function(mix) {
mix.sass('app.scss', 'public/css/app.css');
});
This is no longer achievable via elixir.extend() syntax, instead the official documentation now suggests to use this:
elixir.config.sourcemaps = false;
Starting from Elixir 3.0 you can put a JSON object that will override the default configuration in elixir.json:
{
"sourcemaps": false
}
.map files are called source maps. Their purpose is to map the contents of a concatenated, minified file to it's original files to make debugging easier.
You can disable them by changing elixirs config using extend() in your gulpfile
elixir.extend('sourcemaps', false);
Note that source maps are disabled by default when running in production.

Resources