Skip to content

Commit

Permalink
Merge pull request #173 from kohlmannj/local-css
Browse files Browse the repository at this point in the history
feat: add support for `type: 'local-css'`
  • Loading branch information
glromeo authored Mar 7, 2024
2 parents 192f8ea + f64a360 commit 02fc7fb
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 3 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,27 @@ In all other cases `esbuild` won't process the CSS content which instead will be
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](https://esbuild.github.io/content-types/#local-css)).
Use this for lightweight Sass integration that then leverages esbuild's [built-in CSS processing features](https://esbuild.github.io/content-types/#css):

```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.
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {OnLoadResult} from 'esbuild'
import {StringOptions} from 'sass'
import {sassPlugin} from './plugin'

export type Type = 'css' | 'style' | 'css-text' | 'lit-css' | ((cssText: string, nonce?: string) => string)
export type Type = 'css' | 'local-css' | 'style' | 'css-text' | 'lit-css' | ((cssText: string, nonce?: string) => string)

export type SassPluginOptions = StringOptions<'sync'|'async'> & {

Expand Down
4 changes: 2 additions & 2 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ export function sassPlugin(options: SassPluginOptions = {}): Plugin {
}
}

return type === 'css' ? {
return type === 'css' || type === 'local-css' ? {
contents: cssText,
loader: 'css',
loader: type,
resolveDir,
warnings,
watchFiles
Expand Down
1 change: 1 addition & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export function makeModule(contents: string, type: Type, nonce?: string):string
case 'css-text':
return cssTextModule(contents)
case 'css':
case 'local-css':
return contents
default:
return type(contents, nonce)
Expand Down
29 changes: 29 additions & 0 deletions test/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,35 @@ describe('e2e tests', function () {
`)
})

it('local-css', async function () {
const options = useFixture('local-css')

await esbuild.build({
...options,
entryPoints: ['./src/index.js'],
outdir: './out',
bundle: true,
format: 'esm',
plugins: [
sassPlugin({
type: 'local-css'
}),
]
})

const bundle = readTextFile('./out/index.js')

expect(bundle).to.containIgnoreSpaces('class="${message} ${message2}"')

expect(bundle).to.containIgnoreSpaces(`
var message = "example_module_message";
`)

expect(bundle).to.containIgnoreSpaces(`
var message2 = "common_module_message";
`)
})

it('open-iconic (dealing with relative paths & data urls)', async function () {
const options = useFixture('open-iconic')

Expand Down
31 changes: 31 additions & 0 deletions test/fixture/local-css/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
### Example `build.js`
```javascript
const esbuild = require("esbuild");
const {sassPlugin, postcssModules} = require("esbuild-sass-plugin");

esbuild.build({
entryPoints: ["./src/index.js"],
outdir: "build/",
bundle: true,
format: "esm",
plugins: [
sassPlugin({
type: 'local-css'
}),
]
}).catch(() => process.exit(1));
```

### ...remember the dependencies in `package.json`
```json
"dependencies": {
...
"esbuild": "^0.12.20",
"esbuild-sass-plugin": "^1.5.0"
...
}
```

**Note**:

This project is slightly different from the example because it's part of the fixtures
17 changes: 17 additions & 0 deletions test/fixture/local-css/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const esbuild = require('esbuild')
const {sassPlugin} = require('../../../lib')
const {cleanFixture, logSuccess, logFailure} = require('../utils')

cleanFixture(__dirname)

esbuild.build({
entryPoints: ['./src/index.js'],
outdir: './out',
bundle: true,
format: 'esm',
plugins: [
sassPlugin({
type: 'local-css'
}),
]
}).then(logSuccess, logFailure)
11 changes: 11 additions & 0 deletions test/fixture/local-css/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bootstrap Example</title>
<link href="out/index.css" rel="stylesheet">
</head>
<body>
<script src="out/index.js" type="text/javascript"></script>
</body>
</html>
9 changes: 9 additions & 0 deletions test/fixture/local-css/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "local-css-fixture",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"build": "node ./build",
"serve": "node ../serve css-modules"
}
}
3 changes: 3 additions & 0 deletions test/fixture/local-css/src/common.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.message {
font-family: Roboto, sans-serif;
}
5 changes: 5 additions & 0 deletions test/fixture/local-css/src/example.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.message {
color: white;
background-color: red;
font-size: 24px;
}
6 changes: 6 additions & 0 deletions test/fixture/local-css/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { message } from "./example.module.scss";
import * as common from "./common.module.scss";

document.body.insertAdjacentHTML("afterbegin", `
<div class="${message} ${common.message}">Hello World</div>
`);

0 comments on commit 02fc7fb

Please sign in to comment.