Skip to content

Commit ba8286c

Browse files
author
anonymous
committed
First commit
1 parent 9b5c652 commit ba8286c

14 files changed

Lines changed: 2771 additions & 283 deletions

README.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,52 @@
1-
# esbuild-plugin-sass
1+
(Huge thanks to https://github.com/koluch/esbuild-plugin-sass which this is based off)
22

3-
![Node.js CI](https://github.com/koluch/esbuild-plugin-sass/workflows/Node.js%20CI/badge.svg)
3+
# esbuild-plugin-postcss
44

5-
Plugin for [esbuild](https://esbuild.github.io/) to support SASS styles
5+
![Node.js CI](https://github.com/koluch/esbuild-plugin-postcss/workflows/Node.js%20CI/badge.svg)
6+
7+
Plugin for [esbuild](https://esbuild.github.io/) to support PostCSS
68

79
## Install
810

911
```bash
10-
npm i esbuild esbuild-plugin-sass
12+
npm i esbuild esbuild-plugin-postcss
1113
```
1214

1315
## Usage example
1416

15-
Create file `src/test.scss`:
17+
Create file `src/test.css`:
1618

17-
```scss
18-
body {
19-
&.isRed {
20-
background: red;
21-
}
19+
```css
20+
input[type="text"] {
21+
border-radius: 1px;
2222
}
2323
```
2424

2525
Create file `src/index.js`:
2626

2727
```js
28-
import './test.scss'
28+
import "./test.css";
2929
```
3030

31-
3231
Create file `build.js`:
3332

3433
```js
35-
const esbuild = require('esbuild');
36-
const sassPlugin = require('esbuild-plugin-sass')
34+
const esbuild = require("esbuild");
35+
const autoprefixer = require("autoprefixer");
36+
const postCssPlugin = require("esbuild-plugin-postcss");
3737

38-
esbuild.build({
39-
entryPoints: ['src/index.js'],
38+
esbuild
39+
.build({
40+
entryPoints: ["src/index.js"],
4041
bundle: true,
41-
outfile: 'bundle.js',
42-
plugins: [sassPlugin()],
43-
}).catch((e) => console.error(e.message))
42+
outfile: "bundle.js",
43+
plugins: [
44+
postCssPlugin({
45+
plugins: [autoprefixer],
46+
}),
47+
],
48+
})
49+
.catch((e) => console.error(e.message));
4450
```
4551

4652
Run:
@@ -49,10 +55,4 @@ Run:
4955
node build.js
5056
```
5157

52-
File named `bundle.css` with following content will be created:
53-
54-
```css
55-
body.isRed {
56-
background: red;
57-
}
58-
```
58+
File named `bundle.css` with appropriate postcss plugins applied.

index.js

Lines changed: 11 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
const fs = require("fs-extra");
2-
const sass = require("sass");
2+
const postcss = require("postcss");
33
const util = require("util");
44
const tmp = require("tmp");
55
const path = require("path");
6-
const csstree = require("css-tree");
76

8-
const sassRender = util.promisify(sass.render);
7+
const readFile = util.promisify(fs.readFile);
98
const writeFile = util.promisify(fs.writeFile);
109
const ensureDir = util.promisify(fs.ensureDir);
1110

12-
module.exports = (options = {}) => ({
13-
name: "sass",
11+
module.exports = (options = { plugins: [] }) => ({
12+
name: "postcss",
1413
setup: function (build) {
1514
const { rootDir = options.rootDir || process.cwd() } = options;
1615
const tmpDirPath = tmp.dirSync().name;
1716
build.onResolve(
18-
{ filter: /.\.(scss|sass)$/, namespace: "file" },
17+
{ filter: /.\.(css)$/, namespace: "file" },
1918
async (args) => {
2019
const sourceFullPath = path.resolve(args.resolveDir, args.path);
2120
const sourceExt = path.extname(sourceFullPath);
@@ -27,14 +26,15 @@ module.exports = (options = {}) => ({
2726
const tmpFilePath = path.resolve(tmpDir, `${sourceBaseName}.css`);
2827
await ensureDir(tmpDir);
2928

30-
// Compile SASS to CSS
31-
let css = (await sassRender({ file: sourceFullPath })).css.toString();
29+
const css = await readFile(sourceFullPath);
3230

33-
// Replace all relative urls
34-
css = await replaceUrls(css, tmpFilePath, sourceDir, rootDir);
31+
const result = postcss(options.plugins).process(css, {
32+
from: sourceFullPath,
33+
to: tmpFilePath,
34+
});
3535

3636
// Write result file
37-
await writeFile(tmpFilePath, css);
37+
await writeFile(tmpFilePath, result.css);
3838

3939
return {
4040
path: tmpFilePath,
@@ -43,76 +43,3 @@ module.exports = (options = {}) => ({
4343
);
4444
},
4545
});
46-
47-
async function replaceUrls(css, newCssFileName, sourceDir, rootDir) {
48-
const ast = csstree.parse(css);
49-
50-
csstree.walk(ast, {
51-
enter(node) {
52-
if (node.type === "Url") {
53-
const value = node.value;
54-
const stringValue = value.value;
55-
56-
let normalizedUrl;
57-
if (value.type === "String") {
58-
const match = stringValue.match(/^['"](.*)["']$/s);
59-
if (match) {
60-
normalizedUrl = match[1];
61-
} else {
62-
normalizedUrl = stringValue;
63-
}
64-
} else {
65-
normalizedUrl = stringValue;
66-
}
67-
68-
if (isLocalFileUrl(normalizedUrl)) {
69-
const resolved = resolveUrl(normalizedUrl, sourceDir, rootDir);
70-
const relativePath = path.relative(newCssFileName, resolved.file);
71-
72-
node.value = {
73-
...node.value,
74-
type: "String",
75-
// disable keeping query and hash parts of original url, since esbuild doesn't support it yet
76-
// value: `"${relativePath}${resolved.query}${resolved.hash}"`,
77-
value: `"${relativePath}"`,
78-
};
79-
}
80-
}
81-
},
82-
});
83-
84-
return csstree.generate(ast);
85-
}
86-
87-
function isLocalFileUrl(url) {
88-
if (/^https?:\/\//i.test(url)) {
89-
return false;
90-
}
91-
if (/^data:/.test(url)) {
92-
return false;
93-
}
94-
if (/^#/.test(url)) {
95-
return false;
96-
}
97-
98-
return true;
99-
}
100-
101-
function resolveUrl(url, originalFolder, rootDir) {
102-
const [_, pathname, query, hash] = url.match(/^(.*?)(\?.*?)?(#.*?)?$/);
103-
104-
let file = "";
105-
if (pathname.startsWith("/")) {
106-
file = path.resolve(rootDir, pathname.substring(1));
107-
// todo: resolve by root dir
108-
} else {
109-
file = path.resolve(originalFolder, pathname);
110-
}
111-
112-
return {
113-
file,
114-
pathname,
115-
query: query || "",
116-
hash: hash || "",
117-
};
118-
}

0 commit comments

Comments
 (0)