epegzz / sass-vars-loader Goto Github PK
View Code? Open in Web Editor NEWUse Sass variables defined in Webpack config or in external Javascript or JSON files
License: MIT License
Use Sass variables defined in Webpack config or in external Javascript or JSON files
License: MIT License
First off, thanks for a really useful loader!
I came across an issue this morning where if I use CSS color names as my JSON keys, e.g.
{
"colors": {
"fg": {
"default": "#2c2c2c",
"pink": "#ffabab"
}
}
...and then use map-deep-get
(source) to extract the values, like this:
.button {
background: map-deep-get($colors, 'fg', 'pink');
}
...that despite my quoting the keys in the latter fragment, I found that CSS color names (e.g. pink
) don't work (returning nothing), while custom names (e.g. default
) do. What I think is happening is that when sass-vars-loader
converts my JSON, the color names in my JSON file become unquoted and are then interpreted as colour objects by SASS. So when I use map-deep-get
to look up the colour, it returns nothing (because my string lookup doesn't match the color object) and so that property doesn't get written into my CSS.
I found I could fix the issue by double-quoting the names in m JSON, e.g.
{
"colors": {
"fg": {
"'default'": "#2c2c2c",
"'pink'": "#ffabab"
}
}
Is it possible to force sass-vars-loader
to quote all keys when it creates maps from JSON? Either way, I thought I had better report this in case anyone else has the same issue.
Hello - trying this out but running into this issue.
Used yarn add @epegzz/sass-vars-loader --dev
Trying to use Option 2.
/Users/danielcrabbe/Sites/foundlocations.co.uk/wp-content/themes/found-theme-sage-test/resources/assets/build/webpack.config.js:124
],
^
SyntaxError: Unexpected token ']'
// assets/vars.json
{
"colors": {
"primary": "#2c97de"
}
// assets/build/webpack.config.js:124
{
loader: "@epegzz/sass-vars-loader", options: {
syntax: 'scss',
files: [path.resolve(__dirname, '../../vars.json')] // tried a few variations always same error.
},
:124 ],
Do I need to declare '@epegzz/sass-vars-loader' anywhere?
Many thanks, Dan.
What do you think of readVarsFromTypescriptFiles?
Hi there,
First of all, thank you for writing this great plugin!
I'm currently moving all of our variables to a constants file where I want to optimize it as much as possible. I'm currently facing an issue where functions are not being called and just showing up as strings. Below is an example of the code that I am using.
Example:
module.exports = {
colors: {
red: "#abc",
blue: "#def",
}
styles: {
border: "1px solid color(red)",
}
}
@function color($color, $shade:false) {
@if map-has-key($colors, $color) {
$color: map-get($colors, $color);
@if $shade {
@return rgba($color, $shade);
} @else {
@return $color;
}
}
@error "\"#{$color}\" is not a valid color.";
}
When calling border: map-get($styles, border)
the string border: 1px solid color(red)
is being returned, which makes total sense, so when replacing color(red)
with #{color(red)}
the output remains the same.
Do you have any idea on how to fix this? Or is it simply not possible to call sass functions within the constants.js
file?
Thanks for your help!
trying to import a JSON file ,it works great except the strings are not quoted so if JSON has a property
"typography": {
"font-family": "Arial, -apple-content, BlinkMacSystemFont"
}
it gives an error as it gets imported without quotes and build fails.
I see there are some call backs I can send in options will that help in keeping the quotes of values returned ? if so can someone help me with an example pls.
Note: I cannot change to double quote the values.
Webpack cannot find the module after installing
Module not found: Error: Can't resolve 'sass-vars'
Not sure why. Any Ideas?
its in node_modules/@epegzz/sass-vars-loader
Using "webpack": "^2.1.0-beta.25",
For the latest version (4.1.0), you're missing dependencies typescript
and require-from-string
. See https://github.com/epegzz/sass-vars-loader/blob/184ab81ea5c8e246196fc7788f36f8f18dd0c028/src/utils/readVarsFromTypescriptFiles.js - you're requiring them during runtime but you'll notice that you have those 2 modules as dev dependencies in your package.json.
Here's the failing logs:
Module build failed (from ./node_modules/@epegzz/sass-vars-loader/src/sassVarsLoader.js):
Error: Cannot find module 'typescript'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (C:\Users\334835170\SrcCode\pi-frontend\node_modules\@epegzz\sass-vars-loader\src\utils\readVarsFromTypescriptFiles.js:2:12)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (C:\Users\334835170\SrcCode\pi-frontend\node_modules\@epegzz\sass-vars-loader\src\sassVarsLoader.js:4:37)
We were using a setup similar to below:
const BUILD_ID = "012345"; // (generated git hash)
options: {
vars: {
version: BUILD_ID
}
}
The issue we were running into was that upon using $version
in our sass files, the leading 0
was being removed from the string which was causing our assets to look at the wrong path on our server.
I was able to "solve" this by setting version to
`"${BUILD_ID}"`
so that the string value we were sending in included double quotes around it. This solved our problem but figured 1) you may want to know about this in case someone else raises the issue and 2) it's probably a good idea to handle that scenario by default.
Line 22 of convertJsToSass.js
could be altered to:
if (typeof value === 'string') {
return `"${value}"`;
}
I'm not totally sure if this creates other problems, but just throwing it out there!
Currently, the files passed as option are ordered by type. But this is not obvious to the user and should hence be changed.
Hello. Thank you for this work :)
I try to use it with Vue-CLI through vue.conf.js
with next config:
chainWebpack: config => {
config.module
.rule('scss')
.use('sass-vars-loader')
.loader('sass-vars-loader')
.options({
loader: 'sass-vars-loader',
options: {
syntax: 'scss',
files: [
path.resolve(__dirname, '@/assets/styles/contracts/variables.json'),
],
},
})
},
But when project starts I have error in console for every using Vue-component:
Module build failed (from ./node_modules/sass-vars-loader/index.js):
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
at assertPath (path.js:39:11)
at Object.join (path.js:1155:7)
at read (/Users/netstuff/Sites/bspb/ui/node_modules/fs-readdir-recursive/index.js:11:18)
at requireFresh (/Users/netstuff/Sites/bspb/ui/node_modules/require-fresh/index.js:67:21)
at Object.SassImports (/Users/netstuff/Sites/bspb/ui/node_modules/sass-vars-loader/index.js:39:46)
What I do wrong?
I am trying to pass the application version to the SCSS so that i can add it to the comments in the CSS file along with other useful info, but it gets translated from "4.2.0" into "4.2 0" is there a way to disable this auto transformation/parsing?
{
test: /\.(sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
{
loader: "@epegzz/sass-vars-loader",
options: {
vars: {
appVersion: `4.2.0`,
},
},
},
],
},
After updating 2.2.0 to 3.0.0:
Module build failed: TypeError: files.forEach is not a function
at exports.default (C:\Source\node_modules\@epegzz\sass-vars-loader\dist\utils\watchFilesForChanges.js:6:9)
at Object.exports.default (C:\node_modules\@epegzz\sass-vars-loader\dist\sassVarsLoader.js:13:38)
The file exists, but webpack cannot resolve it. Is there a breaking change?
The variables that I'm declaring in sassVars do not seem to be getting injected.
It just says "Undefined Variable"
Here is a part of my webpack config.
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test : /\.css$/,
loaders: ['style', 'css', 'resolve-url']
},
{
test: /\.scss$/,
loaders: ['style', 'css', '@epegzz/sass-vars-loader', 'resolve-url', 'sass?sourceMap'],
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /\.(woff2?|ttf|svg|eot|jpe?g)$/,
loader: 'ignore-loader'
},
],
},
sassVars: {
vars: {
favouriteColor: 'red',
}
},
Hello! I use sass-vars-loader
with Vue Cli 3 and I try to move common scss-files to app config:
const path = require('path');
module.exports = {
chainWebpack: (config) => {
const moduleTypes = ['vue-modules', 'vue', 'normal-modules', 'normal'];
moduleTypes.forEach(moduleType =>
config.module
.rule('scss')
.oneOf(moduleType)
.use('@epegzz/sass-vars-loader')
.loader('@epegzz/sass-vars-loader')
.options({
syntax: 'scss',
files: [
path.resolve(__dirname, 'src/assets/styles/contracts/variables.json'),
path.resolve(__dirname, 'src/assets/styles/contracts/icons.json')
],
})
)
},
css: {
loaderOptions: {
sass: {
data: `
@import '~@/assets/styles/vars';
@import '~@/assets/styles/util';
@import '~@/assets/styles/func';
@import '~@/assets/styles/mixins';
@import '~@/assets/styles/colors';
`,
},
},
},
}
But on app loaded I have got an error: "Undefined variable: $palette".
It works properly, when I importing common scss-files directly, but I want to import it all in one place.
Can you help me?
Hello.
I wrote some useful code for this library (netstuff/sass-vars-loader) and want to commit changes to new branch to create a pull-request for you. But on committing to I get an error:
prettier-eslint [ERROR]: There was trouble creating the ESLint CLIEngine.
prettier-eslint-cli [ERROR]: There was an error formatting "src/sassVarsLoader.test.js":
AssertionError [ERR_ASSERTION]: 'basePath' should be an absolute path.
at new IgnorePattern (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js:178:9)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/config-array-factory.js:651:49)
at _normalizeObjectConfigDataBody.next (<anonymous>)
at ConfigArrayFactory._normalizeObjectConfigData (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/config-array-factory.js:594:20)
at _normalizeObjectConfigData.next (<anonymous>)
at createConfigArray (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/config-array-factory.js:338:25)
at ConfigArrayFactory.create (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/config-array-factory.js:393:16)
at createBaseConfigArray (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js:96:48)
at new CascadingConfigArrayFactory (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js:211:30)
at new CLIEngine (/Users/netstuff/Sites/forks/sass-vars-loader/node_modules/eslint/lib/cli-engine/cli-engine.js:563:36)
which repeats 25 times!
Please help me to resolve this issue!
I tried to do npm install, but got this:
npm ERR! Invalid name: "@epegzz/sass-vars-loader"
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR! <https://github.com/npm/npm/issues>
npm ERR! Please include the following file with any support request:
npm ERR! /Users/SeanYang/workspace/video-discovery-web/npm-debug.log
➜ video-discovery-web git:(re-branding) ✗ npm install @epegzz/sass-vars-loader
npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "@epegzz/sass-vars-loader"
npm ERR! node v6.5.0
npm ERR! npm v2.14.7
npm ERR! Invalid name: "@epegzz/sass-vars-loader"
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR! <https://github.com/npm/npm/issues>
Hello I like to use your solution for import json vars into sass, that give me opportunity to use it also in js in my Vue.js project but, I am using indented sass syntax not scss.
I have error in each my sass file like this expected 1 selector or at-rule, was "{}"
So I clone your project and rewrite scss file to sass syntax and change webpack.config.js and index.js import to include sass and have same issue here is the error from terminal
Version: webpack 2.7.0
Time: 318ms
Asset Size Chunks Chunk Names
bundle.js 16.2 kB 0 [emitted] main
[0] ./src/styles.sass 1.28 kB {0} [built]
[1] ./~/css-loader!./~/sass-loader/lib/loader.js?{"includePaths":["app/styles.sass"]}!./~/@epegzz/sass-vars-loader/dist/sassVarsLoader.js?{"vars":{"greenFromWebpackConfig":"green"},"files":["/home/struers/sass-vars-loader/example/config/sassVars.json","/home/struers/sass-vars-loader/example/config/sassVars.js"]}!./src/styles.sass 256 bytes {0} [built] [failed] [1 error]
[2] ./~/style-loader/addStyles.js 8.51 kB {0} [built]
[3] ./~/style-loader/fixUrls.js 3.01 kB {0} [built]
[4] ./src/index.js 141 bytes {0} [built]
ERROR in ./~/css-loader!./~/sass-loader/lib/loader.js?{"includePaths":["app/styles.sass"]}!./~/@epegzz/sass-vars-loader/dist/sassVarsLoader.js?{"vars":{"greenFromWebpackConfig":"green"},"files":["/home/struers/sass-vars-loader/example/config/sassVars.json","/home/struers/sass-vars-loader/example/config/sassVars.js"]}!./src/styles.sass
Module build failed:
body
^
Invalid CSS after "...ckConfig:green;": expected 1 selector or at-rule, was "{}"
in /home/struers/sass-vars-loader/example/src/styles.sass (line 1, column 31)
@ ./src/styles.sass 4:14-202
@ ./src/index.js
Can you help me somehow.
Do you counting with this possibility or is possible to add it?
{
"loader": "@epegzz/sass-vars-loader",
"options":
{
"vars": {
"greyScaleColor5": "#000"
}
}
}
Hello 👋
Im hoping this package can be upgraded to webpack 5 :)
Passing in a variable via query parameters will break if the object is already object.
webpack.config.js
loader: 'style!css?modules=true!sass!@epegzz/sass-vars-loader?' +JSON.stringify({vars: [config.sassVars]}),
config.dev.js
module.exports = {
target: 'dev',
sassVars: {
color: 'orange'
},
ERROR in .//css-loader?modules=true!.//sass-loader!./~/@epegzz/sass-vars-loader?{"vars":{"color":"orange"}}!./src/styles/modal.scss
Module build failed: SyntaxError: Unexpected token o
at Object.parse (native)
at Object.content (/Users/brandonp/Sites/Nifti/nna-geolocation/node_modules/@epegzz/sass-vars-loader/index.js:33:32)
@ ./src/styles/modal.scss 4:14-224 13:2-17:4 14:20-230
I got the following error when running the sample code posted in the readme file (js or json Option 3 the Pro Tip sample).
ModuleParseError: Module parse failed: Unexpected token (2:24)
File was processed with these loaders:
$lightTheme: (background: white, color: black);
| $darkTheme: (background: black, color: gray);
Not sure if this is because of the symlinked package, or just because it is from inside node_modules.
Reproduction:
https://github.com/reproducing/reproduce-sass-var-loader
The documented config means that the scssVars.json
file would be included for every loaded SCSS file and always at the start.
Is there a way to declare the loader inline so you can control when and where it is imported? So something like:
sass1.scss
@import "./fileA.scss";
@import "./fileA.scss";
sass2.scss
@import "./fileC.scss";
@import "@epegzz/sass-vars-loader!variables.json";
@import "./fileD.scss";
In this instance sass1.scss
would not have access to the variables.json
file. However sass2.scss
will and the declarations will be made after fileC
but before fileD
is imported.
I'm not actually sure whether it's possible to use inline-loaders through the SCSS import statement. I'm curious to know if it's possible or if there is a way to make it possible.
After I got the issue resolved in #18, now the variables are not getting passed to any .scss files.
Undefined variable: "$env".
sass-js-vars.js
module.exports = {
env: METADATA.ENV, // doesnt work even thought this value exists
};
scss file
// Set the default environment for all scss files to refer to
$dev: false;
// Env variable - coming from Sass-Vars-Loader
@if $env == 'development' {
$dev: true;
}
Worked fine in 2.x, not 3.x
If i switch to
const sassVarsConfig = {
syntax: 'scss',
vars : {
env: METADATA.ENV,
}
};
The error is the same, for some reason its not getting passed into my scss files. Any ideas?
doing a map-get from a map inside js file is broken as most likely 4.3.0
currently i'm backing to 4.0.0 to get rid of this issue.
module.exports = {
lightTheme: {
background: 'white',
color: "#000",
},
}
@function color($map, $key, $alpha: 1) {
$color: map-get($map, $key);
@if $alpha == 1 {
@return rgba($color, $alpha);
}
@else {
@return $color;
}
}
body {
background-color: color($lightTheme, color);
}
background-color: color($lightTheme, color);
returns background-color: "#000"; and therefore doesn't work..
i could do unqote(map-get($map, $key)
but that doesn't work if i want to do rgba
Hi,
The refactors that happened after 3.2.0 broke the distribution package.
dist
dir is missing in the 3.2.2
As mentioned by @franciscolourenco in #32 🙏 the documentation could use some update to include the recommended way of configuring webpack with vue.js.
// vue.config.js
module.exports = {
chainWebpack: config => {
const moduleTypes = ['vue-modules', 'vue', 'normal-modules', 'normal']
moduleTypes.forEach(type =>
config.module
.rule('scss')
.oneOf(type)
.use('@epegzz/sass-vars-loader')
.loader('@epegzz/sass-vars-loader')
.options({
syntax: 'scss',
files: [path.resolve(__dirname, './src/styles/colors.js')],
})
)
},
}
Originally posted by @franciscolourenco in #32 (comment)
I have a situation where I want to read the variable from a global JSON file & I want the file to be watched as well. I think it would be great if we could have a function to passed as option that will transform the JSON content to something the loader could handle
Hey again, it seems that when updating the values in a .js or .json file, webpack-dev-server triggers the incremental recompile, but Hot Module Replacement doesn't kick in and update the module with the new .scss.
Is it compatible with HMR? It's not a major need, rather cool to have feature. Just wondering.
webpack2 does not allow custom properties
thx @IAMtheIAM for pointing this out!
DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see webpack/loader-utils#56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.
Trace -
at Object.parseQuery (/home/ubuntu/toppr-web-v4/client/node_modules/loader-utils/index.js:78:3)
at Object.exports.getLoaderConfig (/home/ubuntu/toppr-web-v4/client/node_modules/loader-utils/index.js:121:22)
at Object.loader (/home/ubuntu/toppr-web-v4/client/node_modules/@epegzz/sass-vars-loader/index.js:12:30)
at LOADER_EXECUTION (/home/ubuntu/toppr-web-v4/client/node_modules/loader-runner/lib/LoaderRunner.js:119:14)
at runSyncOrAsync (/home/ubuntu/toppr-web-v4/client/node_modules/loader-runner/lib/LoaderRunner.js:120:4)
at iterateNormalLoaders (/home/ubuntu/toppr-web-v4/client/node_modules/loader-runner/lib/LoaderRunner.js:229:2)
at Array.<anonymous> (/home/ubuntu/toppr-web-v4/client/node_modules/loader-runner/lib/LoaderRunner.js:202:4)
at Storage.finished (/home/ubuntu/toppr-web-v4/client/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:40:15)
at /home/ubuntu/toppr-web-v4/client/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:77:9
at /home/ubuntu/toppr-web-v4/client/node_modules/graceful-fs/graceful-fs.js:78:16
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)
Currently if you use webpack to watch files, when there are any changes in the javascript which sass-vars-loader
is used, it will not tigger the rebuild or when it is triggered, it still return the old values.
I am wondering if this is something sass-vars-loader
can handle so that webpack watch can work properly.
Many thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.