Skip to content

Commit fa43c59

Browse files
authored
chore: Rework WASM (#301)
* chore: Rework WASM * chore: update * chore: update everything * chore: update everything * chore: update * chore: update * chore: update * chore: update
1 parent 320f71b commit fa43c59

38 files changed

Lines changed: 3386 additions & 3605 deletions

.github/dependabot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ updates:
2121
schedule:
2222
interval: "daily"
2323
- package-ecosystem: "cargo"
24-
directory: "/bindings/wasm"
24+
directory: "/bindings/javascript"
2525
schedule:
2626
interval: "daily"

.github/workflows/build.yml

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ jobs:
8787
- run: cargo fmt --all -- --check
8888
working-directory: ./bindings/ruby
8989

90-
- run: cargo fmt --all -- --check
91-
working-directory: ./bindings/wasm
92-
9390
clippy:
9491
name: Clippy
9592
runs-on: ubuntu-22.04
@@ -107,7 +104,6 @@ jobs:
107104
bindings/javascript
108105
bindings/python
109106
bindings/ruby
110-
bindings/wasm
111107
bindings/c
112108
bindings/profiler
113109
@@ -131,10 +127,6 @@ jobs:
131127
run: cargo clippy -- -D warnings
132128
working-directory: ./bindings/ruby
133129

134-
- name: WASM
135-
run: cargo clippy -- -D warnings
136-
working-directory: ./bindings/wasm
137-
138130
- name: C
139131
run: cargo clippy -- -D warnings
140132
working-directory: ./bindings/c
@@ -403,41 +395,23 @@ jobs:
403395
working-directory: ./bindings/ruby
404396

405397
test-wasm:
406-
name: Tests for WASM crate
398+
name: WASM module tests
407399
runs-on: ubuntu-22.04
408400
steps:
409401
- uses: actions/checkout@v4
410402

411-
- uses: dtolnay/rust-toolchain@stable
412-
413-
- uses: Swatinem/rust-cache@v2
414-
with:
415-
workspaces: bindings/wasm
416-
cache-all-crates: "true"
417-
418-
- name: Install wasm-pack
419-
uses: actions-rs/cargo@v1
403+
- name: Setup node
404+
uses: actions/setup-node@v4
420405
with:
421-
command: install
422-
args: wasm-pack
423-
424-
- name: Run tests
425-
run: wasm-pack test --node --release
426-
working-directory: ./bindings/wasm
427-
428-
test-wasm-typescript:
429-
name: TypeScript tests for WASM crate
430-
runs-on: ubuntu-22.04
431-
steps:
432-
- uses: actions/checkout@v4
406+
node-version: "20"
407+
cache: yarn
408+
cache-dependency-path: bindings/javascript/yarn.lock
433409

434410
- uses: dtolnay/rust-toolchain@stable
435411

436412
- uses: Swatinem/rust-cache@v2
437413
with:
438-
workspaces: |
439-
css-inline
440-
bindings/wasm
414+
workspaces: bindings/javascript
441415
cache-all-crates: "true"
442416

443417
- name: Install wasm-pack
@@ -446,20 +420,20 @@ jobs:
446420
command: install
447421
args: wasm-pack
448422

449-
- name: Build package
450-
run: wasm-pack build -t nodejs
451-
working-directory: ./bindings/wasm
452-
453423
- name: Install dependencies
454-
run: npm install
455-
working-directory: ./bindings/wasm
424+
run: yarn install
425+
working-directory: ./bindings/javascript
456426

457-
- name: Run tests
458-
run: npm run test
459-
working-directory: ./bindings/wasm
427+
- name: Build Wasm
428+
run: yarn build:wasm
429+
working-directory: ./bindings/javascript
430+
431+
- name: Test Wasm
432+
run: yarn test:wasm
433+
working-directory: ./bindings/javascript
460434

461435
test-c:
462-
name: Tests for C crate
436+
name: C bindings tests
463437
runs-on: ubuntu-22.04
464438
steps:
465439
- uses: actions/checkout@v4

.github/workflows/javascript-release.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,52 @@ jobs:
148148
path: bindings/javascript/${{ env.APP_NAME }}.*.node
149149
if-no-files-found: error
150150

151+
artifacts-wasm:
152+
runs-on: ubuntu-22.04
153+
steps:
154+
- uses: actions/checkout@v4
155+
156+
- name: Setup node
157+
uses: actions/setup-node@v4
158+
with:
159+
node-version: "20"
160+
cache: yarn
161+
cache-dependency-path: bindings/javascript/yarn.lock
162+
163+
- uses: dtolnay/rust-toolchain@stable
164+
165+
- uses: Swatinem/rust-cache@v2
166+
with:
167+
workspaces: bindings/javascript
168+
cache-all-crates: "true"
169+
170+
- name: Install wasm-pack
171+
uses: actions-rs/cargo@v1
172+
with:
173+
command: install
174+
args: wasm-pack
175+
176+
- name: Install dependencies
177+
run: yarn install
178+
working-directory: ./bindings/javascript
179+
180+
- name: Build Wasm
181+
run: yarn build:wasm
182+
working-directory: ./bindings/javascript
183+
184+
- name: Upload artifacts
185+
uses: actions/upload-artifact@v4
186+
with:
187+
name: bindings-wasm32
188+
path: bindings/javascript/wasm/dist/*.wasm
189+
if-no-files-found: error
190+
151191
release:
152192
name: Release
153193
runs-on: ubuntu-22.04
154194
needs:
155195
- artifacts
196+
- artifacts-wasm
156197
if: "startsWith(github.ref, 'refs/tags/')"
157198
steps:
158199
- uses: actions/checkout@v4
@@ -181,6 +222,9 @@ jobs:
181222
with:
182223
path: artifacts
183224

225+
- name: Move Wasm artifacts
226+
run: mv -f ./artifacts/wasm32/*.wasm ./wasm
227+
184228
- name: Move Node.js artifacts
185229
run: yarn artifacts
186230
working-directory: bindings/javascript
@@ -189,6 +233,8 @@ jobs:
189233
run: |
190234
echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" >> ~/.npmrc
191235
npm publish --access public --provenance
236+
cd wasm
237+
npm publish --access public
192238
env:
193239
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
194240
NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ repos:
1717
rev: v3.1.0
1818
hooks:
1919
- id: prettier
20-
exclude: index.d.ts|index.js|README.md|example.html
20+
exclude: index.d.ts|index.js|README.md|example.html|index.min.js|index.mjs|index_bg.wasm|js-binding.*
2121

2222
- repo: https://github.com/jorisroovers/gitlint
2323
rev: v0.19.1

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ into:
4040
- Resolves external stylesheets (including local files)
4141
- Works on Linux, Windows, and macOS
4242
- Supports HTML5 & CSS3
43-
- Bindings for [Python](https://github.com/Stranger6667/css-inline/tree/master/bindings/python), [Ruby](https://github.com/Stranger6667/css-inline/tree/master/bindings/ruby), [WebAssembly](https://github.com/Stranger6667/css-inline/tree/master/bindings/wasm) and [C](https://github.com/Stranger6667/css-inline/tree/master/bindings/c)
43+
- Bindings for [Python](https://github.com/Stranger6667/css-inline/tree/master/bindings/python), [Ruby](https://github.com/Stranger6667/css-inline/tree/master/bindings/ruby), [JavaScript](https://github.com/Stranger6667/css-inline/tree/master/bindings/javascript), [C](https://github.com/Stranger6667/css-inline/tree/master/bindings/c), and [WebAssembly](https://github.com/Stranger6667/css-inline/tree/master/bindings/javascript) module to run in browsers.
4444

4545
## Installation
4646

bindings/javascript/Cargo.toml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
[package]
2-
edition = "2021"
32
name = "css-inline-js"
43
version = "0.11.2"
4+
authors = ["Dmitry Dygalo <dmitry@dygalo.dev>"]
5+
edition = "2021"
6+
readme = "README.md"
7+
description = "High-performance library for inlining CSS into HTML 'style' attributes"
8+
repository = "https://github.com/Stranger6667/css-inline"
9+
keywords = ["css", "html", "email", "stylesheet", "inlining"]
10+
categories = ["web-programming"]
11+
license = "MIT"
12+
rust-version = "1.65"
13+
include = ["src/*.rs", "LICENSE", "README.md", "CHANGELOG.md"]
514

615
[lib]
716
crate-type = ["cdylib"]
817

9-
[dependencies]
18+
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
1019
napi = { version = "2.14.1", default-features = false, features = ["napi4"] }
1120
napi-derive = "2.14.4"
1221

22+
[target.'cfg(target_arch = "wasm32")'.dependencies]
23+
wasm-bindgen = "0.2.87"
24+
serde-wasm-bindgen = "0.6"
25+
getrandom = { version = "0.2", features = ["js"] }
26+
serde = { version = "1", features = ["derive"], default-features = false }
27+
1328
[dependencies.css-inline]
1429
path = "../../css-inline"
1530
version = "*"
@@ -21,3 +36,5 @@ napi-build = "2.1.0"
2136

2237
[profile.release]
2338
lto = true
39+
opt-level = "z"
40+
codegen-units = 1

bindings/javascript/README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# css-inline
22

33
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/Stranger6667/css-inline/build.yml?style=flat-square&labelColor=555555&logo=github" height="20">](https://github.com/Stranger6667/css-inline/actions/workflows/build.yml)
4-
[<img alt="npm" src="https://img.shields.io/npm/v/css-inline?style=flat-square" height="20">](https://www.npmjs.com/package/css-inline)
4+
[<img alt="npm" src="https://img.shields.io/npm/v/@css-inline/css-inline.svg?style=flat-square" height="20">](https://www.npmjs.com/package/@css-inline/css-inline)
55
[<img alt="codecov.io" src="https://img.shields.io/codecov/c/gh/Stranger6667/css-inline?logo=codecov&style=flat-square&token=tOzvV4kDY0" height="20">](https://app.codecov.io/github/Stranger6667/css-inline)
66
[<img alt="gitter" src="https://img.shields.io/gitter/room/Stranger6667/css-inline?style=flat-square" height="20">](https://gitter.im/Stranger6667/css-inline)
77

@@ -72,13 +72,13 @@ var inlined = inline(
7272

7373
### Configuration
7474

75-
- `inline_style_tags`. Specifies whether to inline CSS from "style" tags. Default: `true`
76-
- `keep_style_tags`. Specifies whether to keep "style" tags after inlining. Default: `false`
77-
- `keep_link_tags`. Specifies whether to keep "link" tags after inlining. Default: `false`
78-
- `base_url`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `null`
79-
- `load_remote_stylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
80-
- `extra_css`. Extra CSS to be inlined. Default: `null`
81-
- `preallocate_node_capacity`. **Advanced**. Preallocates capacity for HTML nodes during parsing. This can improve performance when you have an estimate of the number of nodes in your HTML document. Default: `32`
75+
- `inlineStyleTags`. Specifies whether to inline CSS from "style" tags. Default: `true`
76+
- `keepStyleTags`. Specifies whether to keep "style" tags after inlining. Default: `false`
77+
- `keepLinkTags`. Specifies whether to keep "link" tags after inlining. Default: `false`
78+
- `baseUrl`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `null`
79+
- `loadRemoteStylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
80+
- `extraCss`. Extra CSS to be inlined. Default: `null`
81+
- `preallocateNodeCapacity`. **Advanced**. Preallocates capacity for HTML nodes during parsing. This can improve performance when you have an estimate of the number of nodes in your HTML document. Default: `32`
8282

8383
You can also skip CSS inlining for an HTML tag by adding the `data-css-inline="ignore"` attribute to it:
8484

@@ -105,6 +105,29 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
105105
</body>
106106
```
107107

108+
## WebAssembly
109+
110+
`css-inline` also ships a WebAssembly module built with `wasm-bindgen` to run in browsers.
111+
112+
```html
113+
<script src="https://unpkg.com/@css-inline/css-inline-wasm"></script>
114+
<script>
115+
// Initialize the WASM module first
116+
cssInline.initWasm(fetch('https://unpkg.com/@css-inline/css-inline-wasm/index_bg.wasm'));
117+
118+
const inlinedHtml = cssInline.inline(`<html>
119+
<head>
120+
<style>h1 { color:blue; }</style>
121+
</head>
122+
<body>
123+
<h1>Big Text</h1>
124+
</body>
125+
</html>`);
126+
127+
document.getElementById('output').src = inlinedHtml
128+
</script>
129+
```
130+
108131
## License
109132

110133
This project is licensed under the terms of the [MIT license](https://opensource.org/licenses/MIT).
File renamed without changes.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { promises as fs } from "fs";
2+
import { join } from "path";
3+
4+
import test from "ava";
5+
6+
import { inline, initWasm } from "../wasm";
7+
8+
test.before(async () => {
9+
await initWasm(fs.readFile(join(__dirname, "../wasm/index_bg.wasm")));
10+
});
11+
12+
test("default inlining", (t) => {
13+
t.is(
14+
inline(
15+
"<html><head><style>h1 { color:red; }</style></head><body><h1>Test</h1></body></html>",
16+
),
17+
'<html><head></head><body><h1 style="color: red;">Test</h1></body></html>',
18+
);
19+
});
20+
21+
test("keep style tag", (t) => {
22+
t.is(
23+
inline(
24+
"<html><head><style>h1 { color:red; }</style></head><body><h1>Test</h1></body></html>",
25+
{ keepStyleTags: true },
26+
),
27+
'<html><head><style>h1 { color:red; }</style></head><body><h1 style="color: red;">Test</h1></body></html>',
28+
);
29+
});
30+
31+
test("valid baseURL", (t) => {
32+
t.is(
33+
inline(
34+
"<html><head><style>h1 { color:red; }</style></head><body><h1>Test</h1></body></html>",
35+
{ baseUrl: "http://127.0.0.1" },
36+
),
37+
'<html><head></head><body><h1 style="color: red;">Test</h1></body></html>',
38+
);
39+
});
40+
41+
test("invalid baseURL", (t) => {
42+
const error = t.throws(
43+
() => {
44+
inline(
45+
"<html><head><style>h1 { color:red; }</style></head><body><h1>Test</h1></body></html>",
46+
{ baseUrl: "invalid" },
47+
);
48+
},
49+
{ any: true },
50+
);
51+
t.is(error, "relative URL without a base");
52+
});

bindings/javascript/bundle.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @ts-check
2+
const { buildSync } = require("esbuild");
3+
4+
/** @type {import('esbuild').BuildOptions} */
5+
const commonOptions = {
6+
bundle: true,
7+
logLevel: "error",
8+
entryPoints: ["wasm-binding.ts"],
9+
define: { "import.meta.url": "undefined" },
10+
};
11+
12+
buildSync({
13+
...commonOptions,
14+
format: "cjs",
15+
outfile: "wasm/index.js",
16+
});
17+
buildSync({
18+
...commonOptions,
19+
format: "esm",
20+
outfile: "wasm/index.mjs",
21+
});
22+
buildSync({
23+
...commonOptions,
24+
format: "iife",
25+
minify: true,
26+
globalName: "cssInline",
27+
outfile: "wasm/index.min.js",
28+
});

0 commit comments

Comments
 (0)