esbuild plugin for sass/scss files supporting both css loader and css result import (lit-element)
npm install esbuild-sass-plugin!cooltext394785080075403
!image
[![Build Status][travis-image]][travis-url]
A plugin for esbuild to handle Sass & SCSS files.
dynamic style to be added to the html page
embedded to true
console
$ npm i esbuild-sass-plugin
`
$3
Just add it to your esbuild plugins:
`javascript
import {sassPlugin} from 'esbuild-sass-plugin'
await esbuild.build({
...
plugins: [sassPlugin()]
})
`
$3
You can pass a series of options to the plugin that are a superset of Sass
compile string options. \
The following are the options specific to the plugin with their defaults whether provided:
| Option | Type | Default |
|---------------------|---------------------------------------------------------------------------------------------------|------------------------------------------|
| filter | regular expression (in Go syntax) | /\.(s[ac]ss|css)$/ |
| type | "css"
"style"
"lit-css"
"css-text"
(css:string,nonce?:string)=>string | "css" |
| cache | boolean or Map | true (there is one Map per namespace) |
| transform | function | |
| loadPaths | [string[]](https://sass-lang.com/documentation/js-api/interfaces/Options#loadPaths) | [] |
| precompile | function | |
| importMapper | function | |
| cssImports | boolean | false |
| nonce | string | |
| prefer | string | preferred package.json field |
| quietDeps | boolean | false |
| silenceDeprecations | [string[]](https://sass-lang.com/documentation/js-api/interfaces/deprecations/) | [] |
| embedded | boolean | false |
Two main options control the plugin: filter which has the same meaning of filter in esbuild
allowing to select the URLs handled by a plugin instance and then type that's what specifies how the css should be rendered and imported.
$3
The default filter is quite simple but also quite permissive. When specifying a custom regex bear in mind that this
is in Go syntax
> If you have URLs in your imports and you want the plugin to ignore them you can't just a filter expression like:
/^(?!https?:).\.(s[ac]ss|css)$/ because Go regex engine doesn't support lookarounds* but you can use
option to ignore these imports or try a solution like this one.
You can try to list multiple plugin instances in order so that the most specific RegEx come first:
`javascript
await esbuild.build({
...
plugins: [
sassPlugin({
filter: /\.module\.scss$/,
transform: postcssModules()
}),
sassPlugin({
filter: /\.scss$/
}),
],
...
})
`
$3
This option enables the usage of the faster sass-embedded and is false by default just for compatibility reason.
> Make sure that the sass-embedded has been installed as a peer dependency
> or add it manually to your project if your package manager doesn't do that for you
> then set this option to true and enjoy the speed boost!
$3
The example in Usage uses the default type css and will use esbuild CSS loader so your transpiled Sass
will be in index.css alongside your bundle.
In all other cases esbuild won't process the CSS content which instead will be handled by the plugin.
> if you want url() resolution or other processing you have to use postcss like in this example
NOTE: Since version 2.7.0 the css type works also with postcss, CSS modules and more in general
with any transformation function by keeping an internal cache of CSS chunks (virtual CSS files)
importing them in the module wrapping the contents
#### type: "local-css"
This mode uses esbuild's built-in CSS modules support (i.e. the local-css loader).
Use this for lightweight Sass integration that then leverages esbuild's built-in CSS processing features:
`javascript
await esbuild.build({
...
plugins: [
sassPlugin({
filter: /\.module\.scss$/,
type: 'local-css'
}),
sassPlugin({
filter: /\.scss$/
type: 'css'
}),
],
...
})
`
#### type: "style"
In this mode the stylesheet will be in the javascript bundle
and will be dynamically added to the page when the bundle is loaded.
#### type: "css-text"
You can use this mode if you want to use the resulting css text as a string import
`javascript
await esbuild.build({
...
plugins: [sassPlugin({
type: "css-text",
... // for the options availanle look at 'SassPluginOptions' in index.ts
})]
})
`
...and in your module do something like
`javascript
import cssText from './styles.scss'
customElements.define('hello-world', class HelloWorld extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.sheet = new CSSStyleSheet();
this.sheet.replaceSync(cssText);
this.shadowRoot.adoptedStyleSheets = [this.sheet];
}
}
`
#### type: "lit-css"
Or you can import a lit-element css result using type: "lit-css"
`javascript
import styles from './styles.scss'
@customElement("hello-world")
export default class HelloWorld extends LitElement {
static styles = styles
render() {
...
}
}
`
#### type: 'function'
You can now provide your own module factory as type. It has to be a function that receives 2 parameters
the css text and the nonce token and returns the source content to be added in place of the import.
Look in test/fixtures folder for more usage examples.
$3
The cache is enabled by default and can be turned off with cache: false.
Each plugin instance creates and maintain its own cache (as a Map) and this cache lives for the duration of the build.
If you want to pass a Map to preserve the cache amongst subsequent builds bear in mind that sharing the very same cache
between different instances might work just fine or it might lead to issues if the contents are incompatible.
> If you are not sure of what to do just keep a separate Map for each plugin instance.
$3
when this is set to true the plugin rewrites the node-modules relative URLs starting with the ~ prefix so that
esbuild can resolve them similarly to what css-loader does.
> Although this practice is kind of deprecated nowadays
> some packages out there still use this notation (e.g. formio)
> \
> so I added this feature to help in cases like this one.
$3
in presence of Content-Security-Policy
(CSP)
the nonce option allows to specify the nonce attribute for the dynamically generated