@deanc/esbuild-plugin-postcss 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## Unreleased
6
+
7
+ ## 2.0.0 - 2026-02-08
8
+ ### Added
9
+ - Initial entry.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # esbuild-plugin-postcss
4
4
 
5
- ![Node.js CI](https://github.com/deanc/esbuild-plugin-postcss/workflows/Node.js%20CI/badge.svg)
5
+ ![CI](https://github.com/deanc/esbuild-plugin-postcss/actions/workflows/ci.yml/badge.svg)
6
6
 
7
7
  Plugin for [esbuild](https://esbuild.github.io/) to support PostCSS
8
8
 
@@ -15,6 +15,10 @@ or yarn
15
15
  ```bash
16
16
  yarn add esbuild @deanc/esbuild-plugin-postcss
17
17
  ```
18
+ or pnpm
19
+ ```bash
20
+ pnpm add esbuild @deanc/esbuild-plugin-postcss
21
+ ```
18
22
 
19
23
  ## Usage example
20
24
 
@@ -35,9 +39,9 @@ import "./test.css";
35
39
  Create file `build.js`:
36
40
 
37
41
  ```js
38
- const esbuild = require("esbuild");
39
- const autoprefixer = require("autoprefixer");
40
- const postCssPlugin = require("@deanc/esbuild-plugin-postcss");
42
+ import esbuild from "esbuild";
43
+ import autoprefixer from "autoprefixer";
44
+ import postCssPlugin from "@deanc/esbuild-plugin-postcss";
41
45
 
42
46
  esbuild
43
47
  .build({
@@ -46,7 +50,7 @@ esbuild
46
50
  outfile: "bundle.js",
47
51
  plugins: [
48
52
  postCssPlugin({
49
- plugins: [autoprefixer],
53
+ plugins: [autoprefixer()],
50
54
  }),
51
55
  ],
52
56
  })
@@ -60,3 +64,19 @@ node build.js
60
64
  ```
61
65
 
62
66
  File named `bundle.css` with appropriate postcss plugins applied.
67
+
68
+ ## Requirements
69
+
70
+ - Node.js 22+
71
+
72
+ ## Contributing
73
+
74
+ - This repo uses pnpm for CI. If you use pnpm locally, run `pnpm import` once to create `pnpm-lock.yaml`.
75
+
76
+ ## Releases
77
+
78
+ - The release workflow uses npm trusted publishing with provenance. Ensure trusted publishing is enabled for this package in npm before running the workflow.
79
+ - Release checklist:
80
+ 1. Ensure CI is green on `main`.
81
+ 2. Verify `CHANGELOG.md` has entries under `[Unreleased]`.
82
+ 3. Run the "Release package" workflow with the desired release type.
@@ -0,0 +1,6 @@
1
+ import { type AcceptedPlugin } from "postcss";
2
+ import type { Plugin } from "esbuild";
3
+ export interface PostCssPluginOptions {
4
+ plugins?: AcceptedPlugin[];
5
+ }
6
+ export default function postCssPlugin(options?: PostCssPluginOptions): Plugin;
package/dist/index.js ADDED
@@ -0,0 +1,47 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import postcss from "postcss";
4
+ export default function postCssPlugin(options = {}) {
5
+ const plugins = options.plugins ?? [];
6
+ return {
7
+ name: "postcss",
8
+ setup(build) {
9
+ build.onResolve({ filter: /\.css$/, namespace: "file" }, async (args) => {
10
+ // Use esbuild path resolution for node_modules, tsconfig paths, etc.
11
+ // https://esbuild.github.io/plugins/#resolve
12
+ const resolution = await build.resolve(args.path, {
13
+ resolveDir: args.resolveDir,
14
+ kind: args.kind,
15
+ });
16
+ if (resolution.errors.length > 0) {
17
+ return { errors: resolution.errors };
18
+ }
19
+ return {
20
+ path: resolution.path,
21
+ namespace: "postcss",
22
+ };
23
+ });
24
+ build.onLoad({ filter: /\.css$/, namespace: "postcss" }, async (args) => {
25
+ const sourceFullPath = args.path;
26
+ const css = await fs.readFile(sourceFullPath, "utf8");
27
+ if (plugins.length === 0) {
28
+ return {
29
+ contents: css,
30
+ loader: "css",
31
+ resolveDir: path.dirname(sourceFullPath),
32
+ watchFiles: [sourceFullPath],
33
+ };
34
+ }
35
+ const result = await postcss(plugins).process(css, {
36
+ from: sourceFullPath,
37
+ });
38
+ return {
39
+ contents: result.css,
40
+ loader: "css",
41
+ resolveDir: path.dirname(sourceFullPath),
42
+ watchFiles: [sourceFullPath],
43
+ };
44
+ });
45
+ },
46
+ };
47
+ }
package/package.json CHANGED
@@ -1,10 +1,25 @@
1
1
  {
2
2
  "name": "@deanc/esbuild-plugin-postcss",
3
- "version": "1.0.2",
3
+ "version": "2.0.0",
4
4
  "description": "Plugin for esbuild to support postcss",
5
- "main": "index.js",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "types": "./dist/index.d.ts",
14
+ "packageManager": "pnpm@10.0.0",
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "CHANGELOG.md"
19
+ ],
6
20
  "scripts": {
7
- "test": "tape 'tests/*.js' | tap-spec"
21
+ "build": "pnpm exec tsc -p tsconfig.json",
22
+ "test": "pnpm build && node --test tests/*.js"
8
23
  },
9
24
  "author": {
10
25
  "name": "Dean Clatworthy",
@@ -21,31 +36,18 @@
21
36
  "postcss"
22
37
  ],
23
38
  "dependencies": {
24
- "autoprefixer": "^10.2.4",
25
- "css-tree": "^1.1.2",
26
- "fs-extra": "^9.0.1",
27
- "postcss": "^8.2.4",
28
- "tmp": "^0.2.1"
39
+ "autoprefixer": "^10.4.22",
40
+ "postcss": "^8.5.6"
29
41
  },
30
42
  "peerDependencies": {
31
- "esbuild": "^0.8.32"
43
+ "esbuild": "^0.27.0"
32
44
  },
33
45
  "devDependencies": {
34
- "esbuild": "^0.8.32",
35
- "husky": "^4.3.7",
36
- "lint-staged": "^10.5.3",
37
- "prettier": "^2.2.1",
38
- "tap-spec": "^5.0.0",
39
- "tape": "^5.1.1"
40
- },
41
- "husky": {
42
- "hooks": {
43
- "pre-commit": "npx lint-staged"
44
- }
46
+ "@types/node": "^22.13.0",
47
+ "esbuild": "^0.27.0",
48
+ "typescript": "^5.7.3"
45
49
  },
46
- "lint-staged": {
47
- "*.js": [
48
- "npx prettier --write"
49
- ]
50
+ "engines": {
51
+ "node": ">=22"
50
52
  }
51
53
  }
@@ -1,30 +0,0 @@
1
- # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
-
4
- name: Node.js CI
5
-
6
- on:
7
- push:
8
- branches: [ main ]
9
- pull_request:
10
- branches: [ main ]
11
-
12
- jobs:
13
- build:
14
-
15
- runs-on: ubuntu-latest
16
-
17
- strategy:
18
- matrix:
19
- node-version: [10.x, 12.x, 14.x, 15.x]
20
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21
-
22
- steps:
23
- - uses: actions/checkout@v2
24
- - name: Use Node.js ${{ matrix.node-version }}
25
- uses: actions/setup-node@v1
26
- with:
27
- node-version: ${{ matrix.node-version }}
28
- - run: npm ci
29
- - run: npm run build --if-present
30
- - run: npm test
@@ -1,33 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v2
15
- - uses: actions/setup-node@v1
16
- with:
17
- node-version: 12
18
- - run: npm ci
19
- - run: npm test
20
-
21
- publish-npm:
22
- needs: build
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v2
26
- - uses: actions/setup-node@v1
27
- with:
28
- node-version: 12
29
- registry-url: https://registry.npmjs.org/
30
- - run: npm ci
31
- - run: npm publish
32
- env:
33
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- v10.16.0
package/.prettierrc.json DELETED
@@ -1 +0,0 @@
1
- {}
package/index.js DELETED
@@ -1,45 +0,0 @@
1
- const fs = require("fs-extra");
2
- const postcss = require("postcss");
3
- const util = require("util");
4
- const tmp = require("tmp");
5
- const path = require("path");
6
-
7
- const readFile = util.promisify(fs.readFile);
8
- const writeFile = util.promisify(fs.writeFile);
9
- const ensureDir = util.promisify(fs.ensureDir);
10
-
11
- module.exports = (options = { plugins: [] }) => ({
12
- name: "postcss",
13
- setup: function (build) {
14
- const { rootDir = options.rootDir || process.cwd() } = options;
15
- const tmpDirPath = tmp.dirSync().name;
16
- build.onResolve(
17
- { filter: /.\.(css)$/, namespace: "file" },
18
- async (args) => {
19
- const sourceFullPath = path.resolve(args.resolveDir, args.path);
20
- const sourceExt = path.extname(sourceFullPath);
21
- const sourceBaseName = path.basename(sourceFullPath, sourceExt);
22
- const sourceDir = path.dirname(sourceFullPath);
23
- const sourceRelDir = path.relative(path.dirname(rootDir), sourceDir);
24
-
25
- const tmpDir = path.resolve(tmpDirPath, sourceRelDir);
26
- const tmpFilePath = path.resolve(tmpDir, `${sourceBaseName}.css`);
27
- await ensureDir(tmpDir);
28
-
29
- const css = await readFile(sourceFullPath);
30
-
31
- const result = await postcss(options.plugins).process(css, {
32
- from: sourceFullPath,
33
- to: tmpFilePath,
34
- });
35
-
36
- // Write result file
37
- await writeFile(tmpFilePath, result.css);
38
-
39
- return {
40
- path: tmpFilePath,
41
- };
42
- }
43
- );
44
- },
45
- });
@@ -1,3 +0,0 @@
1
- body {
2
- border-radius: 1px;
3
- }
File without changes
@@ -1 +0,0 @@
1
- import "./example.css";
package/tests/basic.js DELETED
@@ -1,44 +0,0 @@
1
- const test = require("tape");
2
- const path = require("path");
3
- const autoprefixer = require("autoprefixer");
4
- const fs = require("fs-extra");
5
-
6
- const autoPrefixerPlugin = autoprefixer({
7
- browsers: ["last 2 versions", "chrome >= 4"],
8
- });
9
-
10
- process.chdir(path.resolve(__dirname));
11
-
12
- const postCssPlugin = require("../index.js");
13
-
14
- test("simplest case", function (t) {
15
- (async () => {
16
- fs.removeSync(".output");
17
-
18
- await require("esbuild").build({
19
- entryPoints: ["basic/index.js"],
20
- bundle: true,
21
- outfile: ".output/bundle.js",
22
- plugins: [
23
- postCssPlugin({
24
- plugins: [autoPrefixerPlugin],
25
- }),
26
- ],
27
- });
28
-
29
- t.ok(fs.existsSync("./.output/bundle.js"), "Bundled js file should exist");
30
- t.ok(
31
- fs.existsSync("./.output/bundle.css"),
32
- "Bundled css file should exist"
33
- );
34
-
35
- const fileContent = fs.readFileSync("./.output/bundle.css").toString();
36
-
37
- t.ok(
38
- fileContent.indexOf(`-webkit-border-radius`) !== -1,
39
- "Should contain prefixed selector"
40
- );
41
-
42
- t.end();
43
- })().catch((e) => t.fail(e.message));
44
- });