Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Pass and convert data and functions between JavaScript and Sass. Supports both Node Sass and Dart Sass
npm install jsass
Since node-sass v3.0.0, the functions
option makes it possible to pass an Object of JS functions that may be invoked by the sass files being compiled (check node-sass
docs here for more information).
This gives the developers unlimited possibilities for processing Sass data during build-time, but since the connected JS functions receive their parameters and must return their return values in node-sass's own data types, this makes a bit more difficult to just use this feature out-of-the-box.
This package contains a class (JSFunctionsToSass), which acts like a middleware between node-sass and the connected JS function. It converts the received node-sass type arguments to their JS equivalents, and applies them as pure JavaScript types to the connected JS function. When the function returned what it has to be, JSFunctionsToSass converts the returned JS value back to its node-sass equivalent, and passes back to node-sass. So simple.
Both sync and async functions are supported.
str-replace
functionconst path = require('path');
const sass = require('node-sass');
const { JSFunctionsToSass } = require('jsass/dist/node');
const jsFunctionsToSass = new JSFunctionsToSass();
/**
* This example demonstrates the simplest usage of JSFunctionsToSass, adding a `str-replace` function to Sass
*/
sass.render({
file: path.resolve(__dirname, './str-replace.scss'),
functions: jsFunctionsToSass.convert({
'str-replace($string, $search, $replace: "")': function (string, search, replace) {
if (typeof string !== 'string') {
throw new Error('str-replace needs `$string` to be typeof string!');
}
return string.replace(new RegExp(search, 'g'), replace);
}
})
}, (err, result) => {
if (err) {
throw new Error(err);
}
console.log(result.css.toString());
});
str-replace.scss
.string-replace {
$string: 'The answer to life the universe and everything is 42.';
string: '#{$string}';
search: 'e';
replace: 'xoxo';
content-replaced: '#{str-replace($string, 'e', 'xoxo')}';
}
Output:
.string-replace {
string: "The answer to life the universe and everything is 42.";
search: 'e';
replace: 'xoxo';
content-replaced: "Thxoxo answxoxor to lifxoxo thxoxo univxoxorsxoxo and xoxovxoxorything is 42.";
}
const path = require('path');
const { JSFunctionsToSass } = require('jsass/dist/node');
const jsFunctionsToSass = new JSFunctionsToSass();
const _ = require('lodash');
/**
* This example implements an advanced `map-get` function in Sass, using lodash's `get()`, making it possible to get the value of a nested Map (or List) by its path (eg. `deeply.nested.value`).
*/
sass.render({
implementation: require('sass'), // Now we are using `dart-sass`
file: path.resolve(__dirname, './map-get-super.scss'),
functions: jsFunctionsToSass.convert({
'map-get-super($map, $path)': _.get
})
}, (err, result) => {
console.log(result.css.toString());
});
map-get-super.scss
$map: (
'deeply': (
'nested': (
'value': 'jSass'
)
)
);
.resolved {
map: '#{$map}';
path: 'deeply.nested.value';
content: '#{map-get-super($map, 'deeply.nested.value')}';
}
Output:
.resolved {
map: '("deeply": ("nested": ("value": "jSass")))';
path: 'deeply.nested.value';
content: "jSass";
}
const path = require('path');
const sass = require('node-sass');
const { JSFunctionsToSass } = require('jsass/dist/node');
const jsFunctionsToSass = new JSFunctionsToSass();
const urljoin = require('url-join');
/**
* This example adds a `url-join` function to Sass, using the `url-join` NPM package
*/
sass.render({
file: path.resolve(__dirname, './url-join.scss'),
functions: jsFunctionsToSass.convert({
'url-join($paths...)': urljoin
})
}, (err, result) => {
console.log(result.css.toString());
});
url-join.scss
.url-join {
content: '#{('https://', 'github.com', 'body-builder', 'jsass')}';
content-joined: '#{url-join('https://', 'github.com', 'body-builder', 'jsass')}';
}
Output:
.url-join {
content: "https://, github.com, body-builder, jsass";
content-joined: "https://github.com/body-builder/jsass";
}
jSass makes a good pair with sass-extract. We recommend using sass-extract to export your Sass project's variables to JS. Once you are installed it, why don't you query it easily right in your frontend JavaScript code? JSass
makes this task easy for you. It reads the output Object of sass-extract
, and converts it to simple JavaScript Strings, Arrays or Objects. You can
If you would like to share some of your CSS selectors with JS, JSass_mod_jQuery
makes it possible to use your Sass selectors directly in jQuery.
In addition to this, jSass's sass-extract plugin helps you to extract only the really important data to your bundle file.
Node-sass accepts a data
option as the source code to compile (check node-sass
docs here). This also makes it possible to pass for example Node.js variables to your Sass files. However, data
must be a string, containing syntactically valid raw Sass code. jSass helps you to stringify any general JavaScript types to their equivalent Sass variable type to raw Sass format. It supports both SCSS and SASS (indented) syntax as output type.
const { JSVarsToSassData } = require('jsass/dist/node');
const jsVarsToSassData = new JSVarsToSassData();
process.env.NODE_ENV = 'development';
const data = jsVarsToSassData.convert({
ENV: process.env.NODE_ENV,
DEV: process.env.NODE_ENV === 'development',
variable: 'variable',
importantList: ['some', 'important', 'value'],
importantMap: {
bool: true,
string: 'string',
variable: '$variable',
color: '#646e64',
unit: '12px'
},
nestedValues: {
array: ['some', 'important', 'value'],
map: {
bool: true,
string: 'string',
variable: '$variable',
color: 'rgba(100, 110, 100, 0.5)',
unit: '12px'
},
thatsAll: false
}
});
console.log(data);
Output:
$ENV: 'development';
$DEV: true;
$variable: 'variable';
$importantList: ('some', 'important', 'value');
$importantMap: ('bool': true, 'string': 'string', 'variable': $variable, 'color': rgb(100, 110, 100), 'unit': 12px);
$nestedValues: ('array': ('some', 'important', 'value'), 'map': ('bool': true, 'string': 'string', 'variable': $variable, 'color': rgb(100, 110, 100), 'unit': 12px), 'thatsAll': false);
Use it in node-sass
:
const fs = require('fs');
const path = require('path');
const sass = require('node-sass');
const { JSVarsToSassData } = require('jsass/dist/node');
const jsVarsToSassData = new JSVarsToSassData();
/**
* This example demonstrates how to inject JS variables to Sass using the `data` option of `sass.render()`
*/
const data = jsVarsToSassData.convert({
ENV: process.env.NODE_ENV,
DEV: process.env.NODE_ENV === 'development',
variable: 'variable',
importantList: ['some', 'important', 'value'],
importantMap: {
bool: true,
string: 'string',
variable: '$variable',
color: '#646e64', // By default we are using this value, just edit your `node_sass.scss` to see other injected values
unit: '12px'
},
nestedValues: {
array: ['some', 'important', 'value'],
map: {
bool: true,
string: 'string',
variable: '$variable',
color: 'rgba(100, 110, 100, 0.5)',
unit: '12px'
},
thatsAll: false
}
});
const file = fs.readFileSync(path.resolve('./node_sass.scss'), 'utf8');
sass.render({
data: [data, file].join('\n'),
}, (err, result) => {
console.log(result.css.toString());
});
node_sass.scss
.selector {
@if ($DEV == true) {
background-color: map_get($importantMap, 'color');
} @else {
background-color: white;
}
}
Output:
.selector {
background-color: #646e64;
}
Use jSass's jsVarsToDefinePlugin
to be able to safely share the same values with your JS and Sass files:
webpack.config.js
const webpack = require('webpack');
const jsVarsToDefinePlugin = require('jsass/dist/jsVarsToDefinePlugin');
module.exports = {
...,
plugins: [
new webpack.DefinePlugin(jsVarsToDefinePlugin({
ENV: process.env.NODE_ENV,
DEV: process.env.NODE_ENV === 'development',
variable: 'variable',
importantList: ['some', 'important', 'value'],
importantMap: {
bool: true,
string: 'string',
variable: '$variable',
color: '#646e64',
unit: '12px'
},
nestedValues: {
array: ['some', 'important', 'value'],
map: {
bool: true,
string: 'string',
variable: '$variable',
color: 'rgba(100, 110, 100, 0.5)',
unit: '12px'
},
thatsAll: false
}
}))
]
};
See other examples in the examples directory. ($ npm run start
in any folder.)
npm run build
npm run test
Sponsored by: SRG Group Kft.
1.1.0 (2019-10-30)
Changing the names (and file path) of many classes (adefaa71)
To be more straightforward, as we are supporting not exclusively node-sass
| Old name | New name | |---|---| | JSFunctionsToNodeSass | JSFunctionsToSass | | JSVarsToNodeSass | JSVarsToSass | | NodeSassVarsToJs | SassVarsToJS | | JSVarsToSassString | JSVarsToSassData |
(We should create a new major version in normal case, but since the package is quite new (1wo), we make an exception this time. Hopefully we will not have to change the API in the near future.)
FAQs
Share functions and variables between JS and Sass
The npm package jsass receives a total of 5 weekly downloads. As such, jsass popularity was classified as not popular.
We found that jsass demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.