SASS Module Error when trying to use #use rule - sass

I am new to SCSS and having an issue using the #use rule.
sass/helpers/_variables.scss
$companyColor: #d60048;
header/header.scss
#use '../sass/helpers/_variables' as variables;
.app-header {
background-color: variables.$companyColor;
}
I get an error:
ERROR in ./src/Header/Header.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--8-2!./src/Header/Header.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Invalid CSS after "...olor: variables": expected expression (e.g. 1px, bold), was ".$companyColor;"
on line 4 of C:\MyProject\Client\src\Header\Header.scss
>> background-color: variables.$companyColor;
-------------------------------^
Any help would be greatly appreciated.

The #use keyword is unfortunately not supported in node-sass (yet). Lets hope that they bring support in the near future. Till then, you can use the #import syntax.

I had same problem. I had to remove node-sass and sass (global). Then I installed sass (local). And you need to replace compiler
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// Prefer `dart-sass`
implementation: require('sass'),
},
},
],
},
],
},
};

Related

data option in sassOptions stopped working in gatsby-plugin-sass after upgrading to v3 and replaced node-sass with sass

I decided to remove node-sass from my gatsby project and use sass instead. I followed what is mentioned here for v3. I removed node-sass and now I have these versions in my package.json:
"gatsby-plugin-sass": "3.1.0",
"sass": "1.32.5",
I need to be able to write some #use or #import rules ONCE for global variables/mixins/functions so I can use them in all my scss files and so I won't have to repeat the same rules over and over again.
With node-sass something like this worked:
{
resolve: `gatsby-plugin-sass`,
options: {
includePaths: [`${__dirname}/src/styles`],
data: `#import "globals.scss";`,
},
},
After the upgrade, the includePaths attribute does work but the data does not and I get errors from my scss files about "missing" variables:
{
resolve: `gatsby-plugin-sass`,
options: {
sassOptions: {
includePaths: [`${__dirname}/src/styles`],
data: `#use 'globals' as *;`,
},
},
},
If I insert the rule #use 'globals' as *; in each scss file the errors disappear and everything works as expected but I don't want to insert this line and modify all my sass files.
I am pretty sure that the issue has to do with sass-loader and this statement (documentation) but I can't figure out how to make it work and why it worked before:
ℹ️ Options such as data and file are unavailable and will be ignored.
According to the changelog, data option has been renamed to prependData and then removed in favor of additionalData. So:
{
resolve: `gatsby-plugin-sass`,
options: {
additionalData: `#use 'globals' as *;`,
sassOptions: {
includePaths: [`${__dirname}/src/styles`],
},
},
},

Gatsby Develop Failing using gatsby-plugin-sass

After installing the gatsby-plugin-sass module:
When I try to run gatsby build, I get the following error:
ERROR
Unknown error from PostCSS plugin. Your current PostCSS version is 6.0.23, but autoprefixer uses 7.0.26. Perhaps this is the source of the error below.
ERROR #98123 WEBPACK
Generating development JavaScript bundle failed
Browser queries must be an array or string. Got object.
File: src/indexs.sass
failed Building development bundle - 9.200s
I have been working on a resolution to this for hours. I have tried:
custom webpack rules in gatsby-node.js for sass files
reading, re-reading, and re-re-reading the instruction on gatsby's site
updating PostCSS using npm in every way I know how
So far, nothing has worked.
Why is it so complicated to get sass working with gatsby? When the documentation on gatsby's site makes it seem so easy?
Any suggestions what I can do to get this working?
in gatsby-node.js:
exports.onCreateWebpackConfig = ({
stage,
rules,
loaders,
plugins,
actions,
}) => {
// console.log('rules',rules)
// console.log('rules.css',rules.css())
// console.log('rules',rules.postcss())
actions.setWebpackConfig({
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
plugins: [
plugins.define({
__DEVELOPMENT__: stage === `develop` || stage === `develop-html`,
}),
],
})
}
In gatsby-config.js:
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [require(`postcss-preset-env`)({ stage: 0 })],
},
},
`gatsby-plugin-sass`,
the sass import line in gatsby-browser.js:
import "./src/indexs.sass"
Using sass instead of node-sass saved my day.
remove node-sass
npm uninstall node-sass
or
yarn remove node-sass
and add sass aka dart-sass
npm install --save-dev sass
or
yarn add sass
then edit gatsby-config.js
plugins: [
{
resolve: `gatsby-plugin-sass`,
options: {
implementation: require("sass"),
},
},
]
now run gatsby develop
:)
I'm a bit late to the party but hopefully this might help someone.
I have Sass setup and working with Gatsby without to much extra config required.
Install both node-sass and gatsby-plugin-sass via npm.
npm install --save node-sass gatsby-plugin-sass
Include gatsby-plugin-sass in your gatsby-config.js file in plugins: [] as below with any other Gatsby plugins you maybe using.
module.exports = {
siteMetadata: {
title: `#`,
description: `#`,
author: `#`,
},
plugins: [
`gatsby-plugin-sass`,
],
}
Write your styles as .sass or .scss files and import your main styles.scss (or whatever you prefer to name it) either in your main Layout.js file or gatsby-browser.js file as below using the path to the location of your styles.scss file.
import "./src/styles/styles.scss"
I hope this works for you but if you have any other trouble add a comment and I'll try to reply back.
I hope someone chimes in on this to show how exactly to set up gatsbys sass plugin. I could not get it to work at all.
But I did find a workaround in my case:
I removed gatsby-plugin-sass from the plugins array in gatsby-config.js, turning it off (but I did not uninstall it using npm)
I installed postcss-node-sass and postcss
I added this info to the plugins array in gatsby-config.js:
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [
require(`postcss-preset-env`)({ stage: 0 }),
require(`postcss-node-sass`)(),
],
},
},
I added a custom rule for webpack in gatsby-node.js:
exports.onCreateWebpackConfig = ({
stage,
rules,
loaders,
plugins,
actions,
}) => {
// console.log('rules',rules)
// console.log('rules.css',rules.css())
// console.log('rules',rules.postcss())
actions.setWebpackConfig({
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
plugins: [
plugins.define({
__DEVELOPMENT__: stage === `develop` || stage === `develop-html`,
}),
],
})
}

How I can pass environment variables to scss/ sass file using laravel mix and webpack?

I have an environment variable CDN_URL and I want to send this variable to the SCSS file.
I am also tried prependData of sass-loader.
I have to use Laravel 5.7, Laravel Mix 4.1.2 and webpack 4.27.1
error: Invalid CSS after "...load the styles": expected 1 selector or at-rule, was "var content = requi"
Below is my 'webpack.mix.js' file code.
mix.webpackConfig({
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'vue-style-loader',
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
indentedSyntax: true,
prependData: '$cdn-s3-static-url: ' + process.env.CDN_S3_STATIC_URL + ';',
},
},
],
},
],
},
});
Below is my '_functions.scss' file code:
#function asset($type, $file) {
#return url('#{$cdn-s3-static-url}#{$asset-base-path}#{$type}/#{$file}');
}
In my case I was running a gatsby site. Before each build, it runs gatsby-config.js, which has access to environment variables.
So at the top of the .js file that builds, before module.exports, I put this:
if(process.env.NODE_ENV === 'development') {
fs.writeFileSync('./src/styles/build-style.scss','$root: "/development-path/";');
} else {
fs.writeFileSync('./src/styles/build-style.scss','$root: "/production-path/";');
}
This results in a file which looks like:
$root: "/development-path/";
Then in the SCSS files where I needed ENV-dependent behaviour, I have:
#import './build-style.scss';
#font-face {
font-family: "MyFontFamily";
src: url($root + "font/MyFontFamily.woff") format('woff');
}
And now my asset (font in this example) loads from different spots depending on my dev/production environment variable.
It feels like a big hack and I'm sure there's a more correct way somewhere, but this got me moving again after an hour stoppage and it is working so far. I will probably extend it in the future to have build-style-dev.scss, build-style-prod.scss, and just copy them into build-style.scss at compile time. Or research the correct way.
You can prepend data to SASS using sass-loader
For example to pass the CDN_URL from .env
Extend webpack.mix.js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
prependData: '$env: ' + process.env.CDN_URL + ';',
},
},
],
},
],
},
};
You may inject environment variables into Laravel Webpack Mix by prefixing a key in your .env file with MIX_. After the variable has been defined in your .env file, you may access via the process.env object.
So in your example, you should create a new variable in .env file like MIX_CDN_URL and inside webpack.mix.js you can access it using
process.env.MIX_CDN_URL
You can sass-loader that will achieve the results you desire.

How to import Foundation's SCSS with Webpack 2?

I'm trying to use Foundation with Webpack 2 using the sass-loader.
I'm importing Foundation with
#import 'foundation-sites/scss/foundation';
And get an import error as it can't find foundation. Reading the docs for sass-loader suggests that I should actually use:
#import '~foundation-sites/scss/foundation';
Which fixes the import error but creates a new problem.
The error I receive is
ModuleBuildError in
Module build failed:
#import "normalize";
^
File to import not found or unreadable: normalize
File to import not found or unreadable: normalize
Parent style sheet: ... /node_modules/foundation-sites/scss/foundation.scss
in ... /node_modules/foundation-sites/scss/foundation.scss (line 9, column 1)
In my webpack config file I'm also using the ExtractTextPlugin as below:
module: {
rules: [
{
test: /\.(scss|css)$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: [
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
query: {
includePaths: [path.resolve(__dirname, "./node_modules")]
}
}
]
})
}
]
},
resolve: {
modules: ['node_modules']
}
I believe this comes from the webpack isn't resolving to the node_modules folder for some reason but unsure where the cause comes from.
Try this, as that the only thing that worked for me.
new webpack.LoaderOptionsPlugin({
options: {
context: '/', // <- putting this line right under "options" did the trick
sassLoader: {
includePaths: [
path.resolve(__dirname, 'vendor/zurb/foundation/scss'),
]
}
}
})

Grunt sass #import not making css

I'm trying to use sass with grunt and I'm having a weird behavior.
If I create any file with underscore it doesn't work anymore, and it doesn't import either.
That is my Gruntfile, really simple:
module.exports = function(grunt) {
'use strict';
require('load-grunt-tasks')(grunt);
grunt.initConfig({
watch: {
sass: {
files: 'scss/**/*.{scss,sass}',
tasks: ['sass']
}
},
sass: {
example: {
options: {
outputStyle: 'expanded'
},
files: {
'public/css/app.css': 'scss/**/*.{scss,sass}'
}
}
}
});
grunt.registerTask('default', ['watch']);
};
If I create a file, for example, application.scss in scss/, it works and creates the file app.css in public/css, but if I create any file with underscore, for instance: _variables in scss/ it doesn't work anymore, it doesn't create the file or changes anything and it doesn't import either.
application.scss:
#import "variables";
body {
background-color: $bg-color;
}
_variables.scss:
$bg-color: red;
Files with names starting with an underscore are considered as partial in the eyes of SASS. This means that SASS would not make an actual css file out of them. To prevent this, either create an index.scss file and import your partials in it or remove the underscore from their names.
Official DOcs
I solved it by using:
files: [{
expand: true,
cwd: 'scss',
src: '**/*.{scss,sass}',
dest: 'public/css',
ext: '.css'
}]

Resources