sass-to-string
is a set of helper tools that allow your Web application to leverage SASS files as JavaScript strings so you can use them the way you want afterwards. This is especially useful for Web Components that need to inject their stylesheets directly in the template.
sass-to-string
provides two different approaches
- A Webpack loader that transforms SASS files to native JavaScript strings
- A
sass-to-string
command that transforms yourscss
files to a native JavaScript string at build time
First install the module with your favorite loader
# With NPM
npm install sass-to-string --save-dev
# With Yarn
yarn install sass-to-string -D
In your webpack.config.js
, add the following rule.
module.exports = {
module: {
rules: [
{
test: /\.styles.scss$/,
exclude: /node_modules/,
use: [
"sass-to-string",
{
loader: "sass-loader",
options: {
sassOptions: {
outputStyle: "compressed",
},
},
},
],
},
],
},
};
Chances are you already have a SASS config in your webpack config and the above code just broke it. To fix this, add .styles.scss
in the exclude
of the rule.
See the exclude part in the following example
module.exports = {
module: {
rules: [
{
// Your new shiny sass-to-string config
},
{
test: /\.(scss|css)$/,
// Excluding the `.styles.scss` extension
exclude: [/\.styles.scss$/, /node_modules/],
use: [
"style-loader",
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
},
],
},
];
}
}
Now that Webpack is configured, you can access your compiled SCSS code in a JS module.
Say we have this SCSS
section {
p {
font-family: "Comic Sans MS";
}
}
sass-loader
will resolve it to this value:
section p {
font-family: "Comic Sans MS";
}
Awesome! Not let's pull this in a tractor.js
javascript module
import styles from "./tractor.styles.scss";
// Outputs : section p{font-family:"Comic Sans MS"}
console.log(styles);
The motivation behind this package was to be able to use SASS inside Web Components. Here's an example of doing such
import styles from "./tractor.styles.scss";
class TractorViewer extends HTMLElement {
constructor() {
super();
const style = document.createElement("style");
// styles equals "section p{font-family:"Comic Sans MS"}"
style.textContent = styles;
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(style);
}
}
Note that this module needs webpack
and the magic from sass-loader
in order to do its job properly
If you face typings errors in your IDE, add this line to your local typings file
import "sass-to-string/index";
// Any other type declarations you might have
It should solve the IDE error
We also expose a sass-to-string
command that will transform your SASS files in a JavaScript string. Here's a quick example.
Pretend you have this SCSS file called demo.styles.scss
body {
p {
color: red;
}
}
And this JavaScript import statement alongside
import styles from "./demo.styles.scss";
When running the command, it'll create a demo.styles.scss.js
file in the right directory under dist
.
const styles = `body p {
color: red;
}`;
export default styles;
As you guessed it, you can run it alongside tsc
a fully working app using SASS and only bundled with Typescript.
Here's an example on how you could run a build
command in your package.json
{
"scripts": {
...
"build": "tsc && sass-to-string"
}
}
You can also provide some command options to sass-to-string
like such
{
"scripts": {
...
"build": "sass-to-string --dist=lib"
}
}
If you prefer, you can also create a .sass-to-string.js
file at the root of your project
module.exports = {
dist: "lib",
// Replaces bootstrap imports by resolving node_modules
prepare: (scss) =>
scss.replace(/@import "bootstrap/g, `@import "node_modules/bootstrap`),
};
Option | Default value | Description |
---|---|---|
dist |
dist |
Name of the directory to copy the newly created files |
src |
src |
Name of the directory to look for files |
verbose |
<null> |
If you want sass-to-string to be verbose |
prepare |
(scss) => scss |
JavaScript function that receives the SASS content, and returns a modified version of it |
Note that this module requires a peerDependency
on fs-extra
and sass
in order to work properly
Of course you do! Thinking and coding this package implied quite a lot of coffee. If you want, you can buy me one! ☕️