Compile Liquid in Sass to Css ( Gulp + Scss + Shopify ) - sass

I'm wondering if there is a workaround to :
Use Liquid in .scss files
Then compile all .scss files to .css
Right now, i'm using a custom theme starter that's using gulp to compile my .scss files to a unique theme.css file. I'd like to use liquid in my .scss files and then still compile all of this to .css.
For now, i can't add .scss.liquid to my files because if i do that, then the compiler freaks out as it obviously doesn't recognize .liquid extensions. I've found an article talking about how to compile files to .scss.liquid but that's not what i want since Shopify won't use Scss in the future. I'd like to compile directly to .css.
Here is what my current task looks like for my sass files :
const { src, dest } = require('gulp');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
sass.compiler = require('node-sass')
const styles = () => src('src/styles/theme.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write())
.pipe(rename('theme.css'))
.pipe(dest('dist/assets/'));
module.exports = styles;

There is an article that covers this issue here:
https://ablesense.com/blogs/news/using-gulp-to-compile-sass-liquid-tags
Effectively the solution to compiling liquid tags in SASS is to use the native feature in SASS that allows you to escape out strings #{' your escaped {{ liquid tags }} here '} which will allow linting & transpiling to CSS and then using PostCSS to reformat the output into clean liquid tags.
An arguably better option is to skip the issue entirely and use CSS variables in your SASS while adding your liquid variables into :root in the <head> of the layout.liquid
Your SASS:
btn.primary {
background-color: var(--color-btn-primary);
}
In the <head> of your liquid.layout:
{% style %}
:root {
--color-btn-primary: {{ settings.color_button }}
}
{% endstyle %}
This is covered in detail here:
https://www.shopify.com.au/partners/blog/deprecating-sass

Related

Customizing Vuetify theme doesn't work with Laravel Mix

I'm building an API interface in VueJS alongside Vuetify in a Laravel package. As per Vuetify docs, I've created a main.styl file containing the main theme stylus file (~vuetify/src/stylus/theme), my overrides and the include of the app file (~vuetify/src/stylus/main.styl) in that order. This should add my colour overrides, however this does not happen.
The stylus file is as follows:
#import url("https://fonts.googleapis.com/icon?family=Material+Icons");
#import "~vuetify/src/stylus/theme"
$material-theme.primary = #0078ff
$material-theme.secondary = #00437b
$material-theme.accent = #ee202e
$material-theme.background = #1a1a1a
$material-theme.bg-color = #1a1a1a
$material-theme.cards = #1a1a1a
$material-theme.picker.body = #1a1a1a
#import '~vuetify/src/stylus/main'
And my webpack.mix.js like so:
const path = require('path')
const mix = require('laravel-mix')
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
mix.setPublicPath(path.normalize('public'))
mix.webpackConfig({
output: {
path: path.resolve(__dirname, 'public'),
publicPath: 'vendor/my-package-name/'
},
plugins: [
new VuetifyLoaderPlugin()
],
resolve: { ... }
})
mix.stylus('resources/stylus/vuetify.styl', 'public/css')
mix.js('resources/js/app.js', 'public/js/app.js')
I've tried setting the (in the example set to) $material-theme variable to $material-dark and $theme as well, and neither did not work...
I have made sure to install the whole stylus plugin and such, and yarn does not complain at all when compiling the stylesheet (and it does if I purposely cause an error). However the compiled stylesheet does not contain my changed theme variables. Still, my customisations don't apply at all. The CSS file does not contain my custom colour codes and such.
Does anyone have any idea why this isn't working properly?
I also use Laravel, vue and vuetify framework and the entire process to override your default vuetify variables is quite easy if your understand the setup, in fact you seem to only complicate it with many unnecessary configuration. I rather use npm not yarn but that should make no difference.
So, I would rather do this:
main.styl file looking like:
#import url("https://fonts.googleapis.com/icon?family=Material+Icons");
$material-theme.primary = #0078ff
$material-theme.secondary = #00437b
$material-theme.accent = #ee202e
$material-theme.background = #1a1a1a
$material-theme.bg-color = #1a1a1a
$material-theme.cards = #1a1a1a
$material-theme.picker.body = #1a1a1a
#import "~vuetify/src/stylus/theme"
#import '~vuetify/src/stylus/main'
And this is my own webpack.min.js don't know why you have excess config!
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/main.scss', 'public/css')
.stylus('resources/stylus/main.styl', 'public/css');
To prevent Vuetify from writing inline styles that could override your main.css, do:
mix.options({
extractVueStyles: true, // Extract .vue component styling to file, rather than inline.
});
So, what changed?
You said you created main.style file but from your webpack.mix.js you are compiling vuetify.styl file into your css.
Your main.styl file should be saved in the path resources/stylus/main.styl
Note: You need to setup stylus-loader since Vuetify is built on top of stylus. If you havn't, in command line, run:
$ yarn add stylus stylus-loader style-loader css-loader -D
// OR
$ npm i stylus stylus-loader style-loader css-loader --save-dev
Also note: Default values for the stylus variables that you wish to change must be declared before the import
Didn't go through your variables list, should be okay though but confirm from this github page https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/stylus/settings/_variables.styl
Should be okay I believe

Gulp-sass fires but does not write output when saving partials

I work with gulp sass to compile, prefix and minify my scss to css and min.css, I use watch to fire compiling each time I save files but suddenly gulp-sass stopped writing the output files ONLY when saving partials, everything works fine when I save the main style.scss
This is the SASS log in my terminal on both cases, wether saving main file or partial scss files. As you can see it fires both times but only on the main files saving the output is generated and saved.
[11:54:50] Starting 'sass'...
[11:54:51] Finished 'sass' after 886 ms
[11:54:52] Starting 'sass'...
[11:54:53] Finished 'sass' after 809 ms
Gulp is installed globally and the Gulpfile.js below always worked until yesterday.
I tried to change the gulp.src path several times but without luck.
Obviously I still can compile everything saving the main style.scss but is really annoying when you work on several file simultaneously.
Another strange thing is that trying to change files path to compile the minified version wa reverted to an older date version; I thought it could be an NPM cache problem but I'm not really confident with node/npm, I use it just to compile SCSS and concatenate JS and that's it.
Thanks a lot in advance to anyone who could help me.
var themeurl = './';
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var rename = require("gulp-rename");
var watch = require('gulp-watch');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var cleanCSS = require('gulp-clean-css');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', function () {
return gulp.src(themeurl + '_sass/style.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
browsers: ['last 10 versions']
}))
.pipe(sourcemaps.write())
.pipe(gulp.dest(themeurl))
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(rename('style.min.css'))
.pipe(gulp.dest(themeurl));
});
gulp.task('scripts', function() {
gulp.src('_js/*.js')
.pipe(concat('scripts.js'))
.pipe(gulp.dest('assets/js'));
return gulp.src(themeurl + 'assets/js/scripts.js')
.pipe(uglify().on('error', function(e){
console.log(e);
}))
.pipe(rename('scripts.min.js'))
.pipe(gulp.dest(themeurl+'assets/js/'));
});
gulp.task('watch', function () {
gulp.watch(themeurl + '_sass/**/*.scss', gulp.series('sass') );
gulp.watch(themeurl + '_js/*.js', gulp.series('scripts') );
});
Have you solved your problem? I have the same issue.
My workaround is related how I write watch task. And I have to delete css bundle before every new compilation
// old
watch(`${paths.src}/sass/**/*.scss`, series(css, reload));
// workaround
watch(`${paths.src}/sass/*.scss`, series(delCSSbundle, css, reload));
The result is content of the CSS bundle is updated every compilation but date/time of the bundle remains the same.
Does it work when you replace the style with an * as shown in the code block below? The * tells gulp to search for all files ending with .scss in the folder.
gulp.task('sass', function () {
return gulp.src(themeurl + '_sass/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
browsers: ['last 10 versions']
}))
.pipe(sourcemaps.write())
.pipe(gulp.dest(themeurl))
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(rename('style.min.css'))
.pipe(gulp.dest(themeurl));
});
Thank you Remco , I tried already but unfortunately nothing changed.
As i described upon in the update the problem seems to be related to file's date/time and not on the compiling: the compiling is updated with all my modifications but the date/time is not.
Faced similar issue, gulp tasks were running error free but producing no results for only my styles and image assets (and I didn't add or remove any dependencies, change anything (configuration) or so).
In my case I was using | in src() to read multiple files such as src('src/styles/**/*.{sass|scss}') and src('src/images/*.{png|jpg|svg}') so it turned to be that this was causing my file to be ignored.
Changing | to , solved the issue for me
src('src/styles/**/*.{sass,scss}')
src('src/images/*.{png,jpg,svg}')

gulp.src is not writing destination files out

This is pretty weird. I have this output:
converting sass to css...
[18:36:00] gulp-debug: src/app/app.component.scss
[18:36:00] gulp-debug: src/app/pages/about/about.component.scss
[18:36:00] gulp-debug: src/app/pages/contact/contact.component.scss
[18:36:00] gulp-debug: src/app/pages/home/home.component.scss
[18:36:00] gulp-debug: src/app/pages/home/components/control-panel/control-panel.component.scss
[18:36:00] gulp-debug: 5 items
notify clients of css change
change /Users/alexamil/WebstormProjects/oresoftware/sumanjs/suman-chrome-extension/app/app.component.css
change /Users/alexamil/WebstormProjects/oresoftware/sumanjs/suman-chrome-extension/app/pages/home/home.component.css
change /Users/alexamil/WebstormProjects/oresoftware/sumanjs/suman-chrome-extension/app/pages/home/components/control-panel/control-panel.component.css
change /Users/alexamil/WebstormProjects/oresoftware/sumanjs/suman-chrome-extension/app/pages/about/about.component.css
change /Users/alexamil/WebstormProjects/oresoftware/sumanjs/suman-chrome-extension/app/pages/contact/contact.component.css
here is my code:
const gulp = require('gulp');
const gdebug = require('gulp-debug');
const sass = require('gulp-sass');
console.log('converting sass to css...');
gulp.src(path.resolve(root + '/src/**/**/*.scss'))
.pipe(gdebug())
.pipe(sass())
.pipe(gulp.dest('.'))
.once('finish', function () {
console.log('notify clients of css change');
notifyClients();
});
From the logs it looks like the files are being written out, but from my editor, there don't appear to be any new .css files in the filesystem, only .scss files. Anyone know what might be wrong?
Simply in case of dynamic src and you want respective same dest (as received in src) then you can use following
Example Suppose we have array of scss file:
var gulp = require('gulp');
var sass = require('gulp-sass');
var scssArr = [
'src/asdf/test2.scss',
'src/qwerty/test1.scss'
];
function runSASS(cb) {
scssArr.forEach(function(p){
gulp.src(p, {base:'.'})
.pipe(sass({outputStyle: 'compressed'}))//outputStyle is optional or simply sass()
.pipe(gulp.dest('.')); //if othe folder including src path then use '/folder-name' instead of '.', so output path '/folder-name/{src-received-path}'
})
cb();
}
exports.runSASS = runSASS; // gulp runSASS
Run command gulp runSASS This will create following files:
src/asdf/test2.css
src/qwerty/test1.css
Happy Coding..

Globally add selector to all my CSS selector with Webpack (at build time)

I would like to globally append a specific selector to all CSS selector used in my application.
I'm using React and those Webpack loaders post-css, css-loader, sass-loader and extract-text-webpack-plugin.
I don't want to edit all my classname within jsx files. I just want to append this specific selector at build time.
Is there a loader to achieve this? Or any other solution...
What I actually have:
.myClass {
...
&--blue { ... }
}
What I want after Webpack transpilation:
.specificClass .myClass { ... }
.specificClass .myClass--blue { ... }
Thanks
Gautier
PS: The reason I need this feature is to avoid CSS selector collision with the Website I'm integrating my application. I don't wan't to manually edit all my scss files to append the selector.
this should be solvable by in you main sass file:
.specificClass {
#import 'variables';
#import 'fonts';
// ... do more imports
}

Combine all sass files into a single file

Is there any option available in gulp-sass to combine sass files?
For example:
main.scss:
$var: red;
control.scss:
#import 'main';
.a{
color: $var;
}
The combined output file should be single scss file like below
$var: red;
.a{
color: $var;
}
Did you try something like this?
gulp = require('gulp');
concat = require('gulp-concat');
// the default task
gulp.task('default', function() {
return gulp.src('./*.scss')
.pipe(concat('all.scss'))
.pipe(gulp.dest('./dist/'));
});
This should produce a single combined scss in ./dist/all.scss.
I don't know if #import statements are handled correctly, but these
issues are usually handled by ad-hoc modules (for example, gulp-sass), which produce a .css output...
Here is solution, full proof solution. You need to use gulp-scss-combine as well.
(function(r){
const gulp = r('gulp');
const combine = r('gulp-scss-combine');
const concat = r('gulp-concat');
gulp.task('combine-scss', ()=>gulp.src('scss/**') // define a source files
.pipe(combine()) // combine them based on #import and save it to stream
.pipe(concat('style.scss')) // concat the stream output in single file
.pipe(gulp.dest('css')) // save file to destination.
);
})(require);
You can play with code here . code , basically doing same thing but not in gulp but a node.js standard application. just delete all.scss file or its content, then run the program. you will see the result.
You have to execute one file that imports all other scss files, but when you listen the changes, you have to listen the changes of all files in the scss directory.
gulp.task('sass', function() {
// You have to execute one file that import all other scss files
return gulp.src('src/scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('build/css'));
});
gulp.task('watch', function() {
// You have to listen the all files in the scss directory
gulp.watch('src/scss/**/*.scss',['sass']);
});

Resources