@ideasonpurpose/build-tools-wordpress 2.10.6 → 2.10.7
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/README.md +232 -50
- package/bin/format-php-prettier.js +122 -51
- package/bin/vscode-svgo.js +32 -0
- package/biome.json +43 -0
- package/package.json +5 -6
- package/CHANGELOG.md +0 -520
- /package/{boilerplate → config}/svgo.config.mjs +0 -0
package/README.md
CHANGED
|
@@ -1,99 +1,281 @@
|
|
|
1
1
|
# @ideasonpurpose/build-tools-wordpress
|
|
2
2
|
|
|
3
|
-
#### Version 2.10.
|
|
3
|
+
#### Version 2.10.7
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@ideasonpurpose/build-tools-wordpress)
|
|
6
|
-
[](https://github.com/ideasonpurpose/build-tools-wordpress
|
|
6
|
+
[](https://github.com/ideasonpurpose/build-tools-wordpress/actions/workflows/npm-publish.yml)
|
|
7
|
+
[](./LICENSE)
|
|
7
8
|
|
|
8
|
-
Build scripts and dependencies for
|
|
9
|
+
Build scripts and shared dependencies for WordPress development. Used in production at [Ideas On Purpose](https://www.ideasonpurpose.com).
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
This package centralizes Webpack configuration, asset pipelines, and helper CLIs so host projects stay thin: a small `package.json`, a one-line `webpack.config.js`, and an optional config file.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
## Requirements
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
- **Node.js** 22.15+ (required by webpack-dev-server 6; ESM only)
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
## Install
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
```sh
|
|
20
|
+
npm install -D @ideasonpurpose/build-tools-wordpress
|
|
21
|
+
```
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
Typical host scripts (see [`boilerplate/package.json`](./boilerplate/package.json)):
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"type": "module",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"prebuild": "npm run clean",
|
|
30
|
+
"build": "NODE_ENV=production webpack",
|
|
31
|
+
"postbuild": "npm run zip",
|
|
32
|
+
"start": "webpack serve",
|
|
33
|
+
"zip": "iop-build-zip-archive"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@ideasonpurpose/build-tools-wordpress": "^2.10.6"
|
|
37
|
+
},
|
|
38
|
+
"prettier": "@ideasonpurpose/prettier-config",
|
|
39
|
+
"stylelint": {
|
|
40
|
+
"extends": "@ideasonpurpose/stylelint-config"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
23
44
|
|
|
24
|
-
|
|
45
|
+
Prettier and Stylelint configs are re-exported from this package’s dependencies so hosts can extend them without separate installs.
|
|
25
46
|
|
|
26
|
-
|
|
27
|
-
- **`dist`** - The **distribution** directory where processed, production-ready files will be output to. All contents of this directory will be included in builds.
|
|
28
|
-
- **`src`** - An array of file entry points relative to the `src` directory. Each entry point will generate a like-named output file. All files and assets imported by a given entry point will be accessible from that entry's corresponding output file.
|
|
47
|
+
## Quick start
|
|
29
48
|
|
|
30
|
-
|
|
49
|
+
**1. Point Webpack at this package**
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
```js
|
|
52
|
+
// webpack.config.js
|
|
53
|
+
export { webpackConfig as default } from "@ideasonpurpose/build-tools-wordpress";
|
|
54
|
+
```
|
|
33
55
|
|
|
34
|
-
|
|
56
|
+
**2. Lay out sources** under the default theme paths (package `name` → theme folder):
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
```text
|
|
59
|
+
wp-content/themes/<package-name>/
|
|
60
|
+
src/
|
|
61
|
+
js/main.js
|
|
62
|
+
js/admin.js
|
|
63
|
+
js/editor.js
|
|
64
|
+
sass/ # or styles/
|
|
65
|
+
dist/ # build output
|
|
66
|
+
```
|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
- With `?url` query (e.g., `import svg from 'file.svg?url'`): Treated as assets, inlined as data URIs if under 4KB, else files.
|
|
40
|
-
- With `?react` query (e.g., `import Icon from 'file.svg?react'`): Explicitly converted to a React component using `@svgr/webpack`.
|
|
41
|
-
- Without `?url` or `?react`: Converted to React components using `@svgr/webpack` for direct JSX usage (default behavior when imported from `.jsx`/`.tsx`).
|
|
68
|
+
**3. Run**
|
|
42
69
|
|
|
43
|
-
|
|
70
|
+
```sh
|
|
71
|
+
npm start # webpack-dev-server (proxies local WordPress when available)
|
|
72
|
+
NODE_ENV=production npm run build # production build + zip (if postbuild is set)
|
|
73
|
+
```
|
|
44
74
|
|
|
45
|
-
|
|
75
|
+
Full IOP projects also use Docker Compose tooling from this package (`tooling/docker-compose.yml`) and scripts like `bootstrap`, `db:dump`, and `project:refresh`. Those are optional if you only need the asset pipeline.
|
|
46
76
|
|
|
47
|
-
|
|
77
|
+
## Configuration
|
|
48
78
|
|
|
49
|
-
|
|
79
|
+
Optional config is loaded with [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig) under the name `ideasonpurpose` — typically `ideasonpurpose.config.js` next to `package.json`. Values merge over [defaults](./lib/buildConfig.js).
|
|
50
80
|
|
|
51
|
-
|
|
81
|
+
### Defaults
|
|
52
82
|
|
|
53
|
-
|
|
83
|
+
| Option | Default | Notes |
|
|
84
|
+
| -------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
85
|
+
| `src` | `./wp-content/themes/<name>/src` | `<name>` from host `package.json` |
|
|
86
|
+
| `dist` | `./wp-content/themes/<name>/dist` | |
|
|
87
|
+
| `entry` | `["./js/main.js", "./js/admin.js", "./js/editor.js"]` | Relative to `src`. String, array, or object |
|
|
88
|
+
| `publicPath` | `/wp-content/themes/<name>/dist/` | |
|
|
89
|
+
| `esTarget` | `"es2020"` | Passed to esbuild-loader / minimizer |
|
|
90
|
+
| `devtool` | `"source-map"` | |
|
|
91
|
+
| `proxy` | `"wordpress"` | Dev-server proxy target (Docker service name, URL, IP, or `true` to auto-detect) |
|
|
92
|
+
| `manifestFile` | `"./dependency-manifest.json"` | Written into `dist` |
|
|
93
|
+
| `type` | _(unset / theme)_ | Set `"plugin"` to change archive naming |
|
|
54
94
|
|
|
55
|
-
|
|
95
|
+
Paths resolve relative to the config file (or `package.json` if no config file is found).
|
|
56
96
|
|
|
57
|
-
|
|
58
|
-
**Usage:** `npx iop-html-php-prettier path/to/file.php`
|
|
97
|
+
### Entry shapes
|
|
59
98
|
|
|
60
|
-
|
|
99
|
+
```js
|
|
100
|
+
// Array → basenames become entry keys (overlapping basenames merge)
|
|
101
|
+
entry: ["./js/main.js", "./js/admin.js"];
|
|
102
|
+
|
|
103
|
+
// String → single entry
|
|
104
|
+
entry: "./js/main.js";
|
|
105
|
+
|
|
106
|
+
// Object → passed through
|
|
107
|
+
entry: { app: "./js/main.js", admin: "./js/admin.js" };
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Themes vs plugins
|
|
111
|
+
|
|
112
|
+
Releases are versioned so each build is a clear rollback snapshot. For **themes**, zip archives use a versioned folder name (`my-theme-1.2.3`). That fails for **plugins**, where multiple versions can be active if directory names differ.
|
|
113
|
+
|
|
114
|
+
Set `type: "plugin"` to omit the version from the archive directory name:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
// ideasonpurpose.config.js
|
|
118
|
+
export default {
|
|
119
|
+
type: "plugin",
|
|
120
|
+
src: `./wp-content/plugins/my-plugin/src`,
|
|
121
|
+
dist: `./wp-content/plugins/my-plugin/dist`,
|
|
122
|
+
publicPath: `/wp-content/plugins/my-plugin/dist/`,
|
|
123
|
+
entry: ["./js/main.js"],
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## What the build does
|
|
128
|
+
|
|
129
|
+
| Area | Implementation |
|
|
130
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
131
|
+
| Bundler | Webpack 5 |
|
|
132
|
+
| JS/TS/JSX | [esbuild-loader](https://github.com/privatenumber/esbuild-loader) |
|
|
133
|
+
| CSS | Sass ([sass-embedded](https://sass-lang.com/dart-sass/), modern compiler API), PostCSS (autoprefixer; cssnano in production) |
|
|
134
|
+
| Images | `asset` modules + [Sharp](https://sharp.pixelplumbing.com/) via image-minimizer-webpack-plugin |
|
|
135
|
+
| SVG | Asset / data-URI or React components via [@svgr/webpack](https://react-svgr.com/) (see below) |
|
|
136
|
+
| Copy | Static files from `src` (blocks, fonts, etc. handled specially) |
|
|
137
|
+
| WordPress | [`@wordpress/dependency-extraction-webpack-plugin`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dependency-extraction-webpack-plugin/) + custom dependency manifest |
|
|
138
|
+
| Dev server | Hot reload, live reload on PHP/HTML/SVG/JSON, reverse proxy to local WP |
|
|
139
|
+
| Production | Content hashes, minification, optional bundle analyzer report, zip via `iop-build-zip-archive` |
|
|
140
|
+
|
|
141
|
+
Sass `loadPaths` include `src/sass`, `src/styles`, and the project `node_modules`, so packages can be imported by name:
|
|
142
|
+
|
|
143
|
+
```scss
|
|
144
|
+
@use "some-npm-package/styles";
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Dev server
|
|
148
|
+
|
|
149
|
+
- Proxies the site to a local WordPress container (default Docker service name `wordpress`) when `proxy` is enabled
|
|
150
|
+
- Watches theme PHP/HTML/SVG/JSON for full reload
|
|
151
|
+
- `GET /webpack/reload` triggers a client refresh (useful from PHP or external tools)
|
|
152
|
+
|
|
153
|
+
### Zip archives
|
|
154
|
+
|
|
155
|
+
`iop-build-zip-archive` packs the theme/plugin parent of `src` into `_builds/<name>[-version].zip`. Version suffix is skipped when `type` is `"plugin"`.
|
|
156
|
+
|
|
157
|
+
## SVG processing
|
|
158
|
+
|
|
159
|
+
Webpack treats SVGs differently by context:
|
|
160
|
+
|
|
161
|
+
- **In SCSS** (`url('file.svg')`): inlined as a data URI if under 4KB, otherwise emitted as a file.
|
|
162
|
+
- **In JS/TSX**:
|
|
163
|
+
- `import svg from 'file.svg?url'` — asset URL / data URI (4KB threshold)
|
|
164
|
+
- `import Icon from 'file.svg?react'` — React component via SVGR
|
|
165
|
+
- bare `import Icon from 'file.svg'` from `.jsx`/`.tsx` — React component (default)
|
|
166
|
+
|
|
167
|
+
React SVG components use `dimensions: false` (no fixed `width`/`height`; `viewBox` kept) so they scale with CSS.
|
|
61
168
|
|
|
62
|
-
|
|
63
|
-
**Usage:** `npx iop-format-wp-block-pattern path/to/pattern.php`
|
|
169
|
+
Data URIs use URL-encoding (`data:image/svg+xml,<encoded>`), not base64.
|
|
64
170
|
|
|
65
|
-
|
|
171
|
+
### SVGO and VS Code
|
|
66
172
|
|
|
67
|
-
|
|
173
|
+
[SVGO](https://github.com/svg/svgo) and our preferred [`config/svgo.config.mjs`](./config/svgo.config.mjs) ship with the package, plus a stdin formatter for the editor.
|
|
174
|
+
|
|
175
|
+
Install [SVG Language Mode ID](https://marketplace.visualstudio.com/items?itemName=ideasonpurpose.svg-language-mode-id) and [Custom Local Formatters](https://marketplace.visualstudio.com/items?itemName=jkillian.custom-local-formatters), then in `settings.json`:
|
|
68
176
|
|
|
69
177
|
```json
|
|
70
|
-
|
|
71
|
-
|
|
178
|
+
{
|
|
179
|
+
"[svg]": {
|
|
180
|
+
"editor.defaultFormatter": "jkillian.custom-local-formatters",
|
|
181
|
+
"editor.formatOnSave": false
|
|
182
|
+
},
|
|
183
|
+
"customLocalFormatters.formatters": [
|
|
184
|
+
{
|
|
185
|
+
"command": "iop-vscode-svgo",
|
|
186
|
+
"languages": ["svg"]
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The formatter loads a project `svgo.config` if present, otherwise falls back to this package’s config.
|
|
193
|
+
|
|
194
|
+
Notes:
|
|
195
|
+
|
|
196
|
+
- VS Code treats SVG as XML by default; the language-mode extension is required for the `[svg]` scope.
|
|
197
|
+
- Formatting fails if `editor.formatOnSaveMode` is `"modifications"` (range formatting does not send a full document).
|
|
198
|
+
|
|
199
|
+
**IOP SVGO defaults** ([`config/svgo.config.mjs`](./config/svgo.config.mjs)):
|
|
200
|
+
|
|
201
|
+
- Pretty-print with 4-space indent
|
|
202
|
+
- Preserve ID names (`cleanupIds: false`)
|
|
203
|
+
- Custom: copy width/height from `viewBox` onto `<svg>` when missing
|
|
204
|
+
- Custom: remove top-level `fill="none"`
|
|
205
|
+
- `removeUselessStrokeAndFill` with `removeNone: true`
|
|
206
|
+
|
|
207
|
+
## CLI tools
|
|
208
|
+
|
|
209
|
+
| Command | Purpose |
|
|
210
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
211
|
+
| `iop-build-zip-archive` | Zip theme/plugin into `_builds/` |
|
|
212
|
+
| `iop-build-port-reporter` | Print discovered local WordPress URL/port (Docker) |
|
|
213
|
+
| `iop-project-refresh` | Sync host tooling from package boilerplate (`package.json` scripts, `docker-compose.yml`, `.gitignore`, dirs, optional templates). Flags: `--dry-run`, `--force` (allow dirty git tree) |
|
|
214
|
+
| `iop-html-php-prettier` | Experimental mixed HTML/PHP formatter |
|
|
215
|
+
| `iop-format-wp-block-pattern` | Experimental WordPress block-pattern PHP formatter |
|
|
216
|
+
| `iop-vscode-svgo` | SVGO over stdin for editor formatters |
|
|
217
|
+
|
|
218
|
+
### `iop-html-php-prettier`
|
|
219
|
+
|
|
220
|
+
Double-formats mixed HTML and PHP (WordPress templates): PHP is tokenized, the file is formatted as HTML with Prettier, tokens are restored, then PHP is formatted with [@prettier/plugin-php](https://github.com/prettier/plugin-php).
|
|
221
|
+
|
|
222
|
+
A faster rewrite is in progress: **[Format Mixed PHP and HTML](https://github.com/ideasonpurpose/format-mixed-php-html)**.
|
|
223
|
+
|
|
224
|
+
```sh
|
|
225
|
+
npx iop-html-php-prettier path/to/file.php
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Also accepts STDIN → STDOUT for Custom Local Formatters:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
"customLocalFormatters.formatters": [
|
|
232
|
+
{
|
|
233
|
+
"command": "npx iop-html-php-prettier",
|
|
234
|
+
"languages": ["php"]
|
|
72
235
|
}
|
|
236
|
+
]
|
|
73
237
|
```
|
|
74
238
|
|
|
75
|
-
|
|
239
|
+
### `iop-format-wp-block-pattern`
|
|
240
|
+
|
|
241
|
+
Formats WordPress block pattern PHP: readable block markup, expanded JSON in `<!-- wp:... -->` comments, and whitespace tuned for the block editor.
|
|
76
242
|
|
|
77
243
|
```sh
|
|
78
|
-
|
|
79
|
-
npm chokidar-cli "../../build-tools-wordpress/**/*" -c "npm install"
|
|
244
|
+
npx iop-format-wp-block-pattern path/to/pattern.php
|
|
80
245
|
```
|
|
81
246
|
|
|
82
|
-
###
|
|
247
|
+
### `iop-project-refresh`
|
|
83
248
|
|
|
84
|
-
|
|
249
|
+
Updates an existing project’s tooling from this package’s `boilerplate/` and `tooling/` trees. Safe defaults: refuses a dirty git working tree unless `--force`; use `--dry-run` to preview.
|
|
85
250
|
|
|
86
|
-
|
|
251
|
+
```sh
|
|
252
|
+
npx iop-project-refresh
|
|
253
|
+
npx iop-project-refresh --dry-run
|
|
254
|
+
npx iop-project-refresh --force
|
|
255
|
+
```
|
|
87
256
|
|
|
88
|
-
|
|
257
|
+
## Local development (this package)
|
|
89
258
|
|
|
90
|
-
|
|
91
|
-
|
|
259
|
+
Bin scripts break conventional `npm link`. In a consumer project, depend on a local path instead:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
"devDependencies": {
|
|
263
|
+
"@ideasonpurpose/build-tools-wordpress": "file:../../build-tools-wordpress"
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Reinstall on change:
|
|
268
|
+
|
|
269
|
+
```sh
|
|
270
|
+
cd dev-project-working-dir
|
|
271
|
+
npx chokidar-cli "../../build-tools-wordpress/**/*" -c "npm install"
|
|
92
272
|
```
|
|
93
273
|
|
|
94
|
-
|
|
274
|
+
## Publishing
|
|
275
|
+
|
|
276
|
+
Version-tagged releases publish to npm via GitHub Actions (OIDC trusted publishing). See [CHANGELOG.md](./CHANGELOG.md).
|
|
95
277
|
|
|
96
|
-
|
|
278
|
+
If the workflow needs a classic token instead, set repository secret `NPM_TOKEN` from an npm publish-capable account.
|
|
97
279
|
|
|
98
280
|
<!-- START IOP CREDIT BLURB 2026-07-->
|
|
99
281
|
|
|
@@ -102,6 +284,6 @@ A GitHub action will auto-publish version-tagged releases to npm. In order to pu
|
|
|
102
284
|
#### Brought to you by IOP
|
|
103
285
|
|
|
104
286
|
| <a href="https://www.ideasonpurpose.com"><img src="https://raw.githubusercontent.com/ideasonpurpose/ideasonpurpose/master/iop-logo-white-on-black-88px.png" width="44" height="44" align="top" alt="IOP Logo"></a> <br> | This project is actively developed and used in production at <a href="https://www.ideasonpurpose.com">Ideas On Purpose</a>. <br> |
|
|
105
|
-
|
|
|
287
|
+
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
106
288
|
|
|
107
289
|
<!-- END IOP CREDIT BLURB -->
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
//@ts-check
|
|
4
4
|
|
|
5
|
+
import prettierConfig from "@ideasonpurpose/prettier-config" with {
|
|
6
|
+
type: "json",
|
|
7
|
+
};
|
|
5
8
|
/**
|
|
6
9
|
* This is an experimental proof-of-concept for formatting mixed HTML & PHP
|
|
7
10
|
* files from a single function.
|
|
@@ -9,15 +12,17 @@
|
|
|
9
12
|
* TODO: Testing, naming, modularization, VS Code extension
|
|
10
13
|
*/
|
|
11
14
|
import prettier from "prettier";
|
|
12
|
-
import prettierConfig from "@ideasonpurpose/prettier-config" with { type: "json" };
|
|
13
15
|
|
|
14
16
|
const phpPlugin = await import("@prettier/plugin-php");
|
|
15
17
|
|
|
16
18
|
// Explicitly reset the plugin because global installs can't resolve it
|
|
19
|
+
// @ts-expect-error — prettierConfig types expect string paths, but runtime accepts plugin modules
|
|
17
20
|
prettierConfig.plugins = [phpPlugin];
|
|
18
21
|
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
22
|
+
import { realpathSync } from "node:fs";
|
|
23
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
24
|
+
import { basename, resolve } from "node:path";
|
|
25
|
+
import { fileURLToPath } from "node:url";
|
|
21
26
|
|
|
22
27
|
/**
|
|
23
28
|
* Prettier API doesn't recognize overrides, so we extract them
|
|
@@ -30,6 +35,7 @@ const phpOptions = prettierConfig.overrides.find(
|
|
|
30
35
|
(o) => o.files === "*.php",
|
|
31
36
|
)?.options;
|
|
32
37
|
|
|
38
|
+
/** @param {string} html @param {number} offset */
|
|
33
39
|
const isInTag = (html, offset) => {
|
|
34
40
|
if (offset === 0) return false;
|
|
35
41
|
|
|
@@ -56,6 +62,7 @@ const isInTag = (html, offset) => {
|
|
|
56
62
|
* being mutilated by the HTML formatting step. Cleaner than adding a string.replace
|
|
57
63
|
* to unTokenizeHTML().
|
|
58
64
|
*/
|
|
65
|
+
/** @param {string} htmlContent */
|
|
59
66
|
export function tokenizeHTML(htmlContent) {
|
|
60
67
|
let tokenizedHTML = "";
|
|
61
68
|
const phpCodeBlocks = new Map(); // Changed to Map for better performance and type safety
|
|
@@ -67,6 +74,7 @@ export function tokenizeHTML(htmlContent) {
|
|
|
67
74
|
*
|
|
68
75
|
* NOTE: This uses tokenCount from the enclosing scope
|
|
69
76
|
*/
|
|
77
|
+
/** @param {string} phpCodeBlock @param {string} prevContent */
|
|
70
78
|
const tokenizeCodeBlock = (phpCodeBlock, prevContent) => {
|
|
71
79
|
let start = "<";
|
|
72
80
|
let end = " />";
|
|
@@ -79,27 +87,14 @@ export function tokenizeHTML(htmlContent) {
|
|
|
79
87
|
return `${start}php_${tokenCount++}__`.padEnd(codeLength, "_") + end;
|
|
80
88
|
};
|
|
81
89
|
|
|
82
|
-
// const pattern = /<\?(?:php|=)[\s\S]*?\?>/gs;
|
|
83
|
-
// const pattern =
|
|
84
|
-
// /(?<before>(?:[^\s]|\s|^)\s*)(?<php><\?(?:php|=).*?(?:\?>|$))(?<after>(?:\s*)[^\s]|$)/gs;
|
|
85
|
-
// const pattern =
|
|
86
|
-
// /((?:[^\s]|\s|^)\s*)(<\?(?:php|=).*?(?:\?>|$))((?:\s*)[^\s]|$)/gms;
|
|
87
|
-
// // const pattern = /([^\s]+)\s*(<\?(?:php|=).*?(?:\?>|$))\s*([^\s]*)/gms;
|
|
88
|
-
// const pattern =
|
|
89
|
-
// /([^\s]?\s*)?(<\?(?:php|=).*?(?:\?>|$))((?:\s*)[^\s]|$)/gms;
|
|
90
|
-
// const pattern =
|
|
91
|
-
// /(?<=((?:[^\s]|\s|^)\s*))(<\?(?:php|=).*?\?>)(?=((?:\s*)[^\s]|$))/gms;
|
|
92
|
-
// try removing look ahead/behind
|
|
93
|
-
const pattern = /(<\?(?:php|=).*?\?>)/gms;
|
|
94
|
-
|
|
95
90
|
// const regex = new RegExp(/<\?(?:php|=).*?\?>/, "gs");
|
|
96
91
|
// Trying to capture open-ended PHP codeBlocks in a single regexp
|
|
97
92
|
const regex = new RegExp(/<\?(?:php|=).*?(?:\?>|$)/, "gs");
|
|
98
93
|
|
|
99
|
-
let match;
|
|
94
|
+
let match = regex.exec(htmlContent);
|
|
100
95
|
let token;
|
|
101
96
|
let lastIndex = 0;
|
|
102
|
-
while (
|
|
97
|
+
while (match !== null) {
|
|
103
98
|
tokenizedHTML += htmlContent.slice(lastIndex, match.index);
|
|
104
99
|
|
|
105
100
|
token = tokenizeCodeBlock(match[0], tokenizedHTML);
|
|
@@ -107,12 +102,14 @@ export function tokenizeHTML(htmlContent) {
|
|
|
107
102
|
tokenizedHTML += token;
|
|
108
103
|
|
|
109
104
|
lastIndex = match.index + match[0].length;
|
|
105
|
+
match = regex.exec(htmlContent);
|
|
110
106
|
}
|
|
111
107
|
tokenizedHTML += htmlContent.slice(lastIndex);
|
|
112
108
|
|
|
113
109
|
return { tokenizedHTML, phpCodeBlocks };
|
|
114
110
|
}
|
|
115
111
|
|
|
112
|
+
/** @param {string} tokenizedHTML @param {Map<string, string>} phpCodeBlocks */
|
|
116
113
|
export function unTokenizeHTML(tokenizedHTML, phpCodeBlocks) {
|
|
117
114
|
let phpContent = tokenizedHTML;
|
|
118
115
|
for (const [token, phpBlock] of phpCodeBlocks) {
|
|
@@ -132,55 +129,129 @@ export function unTokenizeHTML(tokenizedHTML, phpCodeBlocks) {
|
|
|
132
129
|
}
|
|
133
130
|
|
|
134
131
|
/**
|
|
135
|
-
*
|
|
132
|
+
* @param {bigint} start
|
|
133
|
+
* @param {bigint} end
|
|
134
|
+
*/
|
|
135
|
+
const ms = (start, end) => Number(end - start) / 1e6;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Formats mixed HTML & PHP content:
|
|
136
139
|
* 1. Tokenize PHP Blocks as HTML-safe and attribute-safe strings
|
|
137
140
|
* 2. Format the result as HTML
|
|
138
141
|
* 3. Un-tokenize HTML back to PHP
|
|
139
142
|
* 4. Format again as PHP
|
|
140
|
-
* 5. Overwrite the file
|
|
141
143
|
*
|
|
142
|
-
* @param {string}
|
|
144
|
+
* @param {string} content
|
|
145
|
+
* @param {string} [label]
|
|
146
|
+
* @returns {Promise<string>}
|
|
143
147
|
*/
|
|
144
|
-
export async function
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const rawFile = await readFile(filepath, "utf8");
|
|
148
|
+
export async function formatHTMLThenPHPContent(content, label = "stdin") {
|
|
149
|
+
const t0 = process.hrtime.bigint();
|
|
150
|
+
const startupMs = process.uptime() * 1e3;
|
|
148
151
|
|
|
149
|
-
|
|
152
|
+
const tTokenize0 = process.hrtime.bigint();
|
|
153
|
+
const { tokenizedHTML, phpCodeBlocks } = tokenizeHTML(content);
|
|
154
|
+
const tTokenize1 = process.hrtime.bigint();
|
|
150
155
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
const htmlFormatted = await prettier.format(tokenizedHTML, {
|
|
157
|
+
...prettierConfig,
|
|
158
|
+
...htmlOptions,
|
|
159
|
+
parser: "html",
|
|
160
|
+
embeddedLanguageFormatting: "auto",
|
|
161
|
+
});
|
|
162
|
+
const tHtml = process.hrtime.bigint();
|
|
157
163
|
|
|
158
|
-
|
|
164
|
+
const phpUnTokenized = unTokenizeHTML(htmlFormatted, phpCodeBlocks);
|
|
165
|
+
const tUnTokenize = process.hrtime.bigint();
|
|
159
166
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
const phpFormatted = await prettier.format(phpUnTokenized, {
|
|
168
|
+
...prettierConfig,
|
|
169
|
+
...phpOptions,
|
|
170
|
+
parser: "php",
|
|
171
|
+
embeddedLanguageFormatting: "auto",
|
|
172
|
+
});
|
|
173
|
+
const tEnd = process.hrtime.bigint();
|
|
167
174
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
175
|
+
console.error(
|
|
176
|
+
[
|
|
177
|
+
label,
|
|
178
|
+
`startup ${startupMs.toFixed(2)}ms`,
|
|
179
|
+
`tokenize ${ms(tTokenize0, tTokenize1).toFixed(2)}ms`,
|
|
180
|
+
`formatHTML ${ms(tTokenize1, tHtml).toFixed(2)}ms`,
|
|
181
|
+
`unTokenize ${ms(tHtml, tUnTokenize).toFixed(2)}ms`,
|
|
182
|
+
`formatPHP ${ms(tUnTokenize, tEnd).toFixed(2)}ms`,
|
|
183
|
+
`total ${(startupMs + ms(t0, tEnd)).toFixed(2)}ms`,
|
|
184
|
+
].join(" "),
|
|
185
|
+
);
|
|
171
186
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
return phpFormatted;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Formats a mixed HTML & PHP file in place.
|
|
192
|
+
*
|
|
193
|
+
* @param {string} filepath
|
|
194
|
+
*/
|
|
195
|
+
export async function formatHTMLThenPHP(filepath) {
|
|
196
|
+
const rawFile = await readFile(filepath, "utf8");
|
|
197
|
+
const phpFormatted = await formatHTMLThenPHPContent(
|
|
198
|
+
rawFile,
|
|
199
|
+
basename(filepath),
|
|
200
|
+
);
|
|
201
|
+
await writeFile(filepath, phpFormatted, "utf8");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @returns {Promise<string>}
|
|
206
|
+
*/
|
|
207
|
+
async function readStdin() {
|
|
208
|
+
const chunks = [];
|
|
209
|
+
for await (const chunk of process.stdin) {
|
|
210
|
+
chunks.push(chunk);
|
|
175
211
|
}
|
|
212
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
176
213
|
}
|
|
177
214
|
|
|
215
|
+
/**
|
|
216
|
+
* CLI: filepath arg overwrites the file; no arg reads STDIN and writes STDOUT.
|
|
217
|
+
*
|
|
218
|
+
* @param {string} [filepath]
|
|
219
|
+
*/
|
|
178
220
|
export async function main(filepath = process.argv[2]) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
221
|
+
try {
|
|
222
|
+
if (filepath) {
|
|
223
|
+
await formatHTMLThenPHP(resolve(filepath));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (process.stdin.isTTY) {
|
|
228
|
+
console.error(
|
|
229
|
+
"Usage: iop-html-php-prettier <filepath>\n iop-html-php-prettier < input.php",
|
|
230
|
+
);
|
|
231
|
+
process.exitCode = 1;
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const formatted = await formatHTMLThenPHPContent(
|
|
236
|
+
await readStdin(),
|
|
237
|
+
"stdin",
|
|
238
|
+
);
|
|
239
|
+
process.stdout.write(formatted);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.error("Error:", error);
|
|
242
|
+
process.exitCode = 1;
|
|
182
243
|
}
|
|
183
|
-
await formatHTMLThenPHP(resolve(filepath));
|
|
184
244
|
}
|
|
185
245
|
|
|
186
|
-
|
|
246
|
+
const isMain = (() => {
|
|
247
|
+
if (process.argv[1] == null) return false;
|
|
248
|
+
try {
|
|
249
|
+
return (
|
|
250
|
+
fileURLToPath(import.meta.url) === realpathSync(resolve(process.argv[1]))
|
|
251
|
+
);
|
|
252
|
+
} catch {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
})();
|
|
256
|
+
|
|
257
|
+
if (isMain) main();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// @ts-check
|
|
4
|
+
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { loadConfig, optimize } from "svgo";
|
|
7
|
+
import fallbackConfig from "../config/svgo.config.mjs";
|
|
8
|
+
|
|
9
|
+
console.error("starting iop-vscode-svgo");
|
|
10
|
+
|
|
11
|
+
if (process.stdin.isTTY) {
|
|
12
|
+
process.stderr.write("Error: No SVG data received on stdin\n");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const svg = readFileSync(0, "utf8").trim();
|
|
17
|
+
if (!svg) {
|
|
18
|
+
process.stderr.write("Error: No SVG data received on stdin\n");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const svgoConfig = /** @type {import("svgo").Config} */ (
|
|
24
|
+
(await loadConfig()) ?? fallbackConfig
|
|
25
|
+
);
|
|
26
|
+
const result = optimize(svg, svgoConfig);
|
|
27
|
+
process.stdout.write(result.data);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : err}\n`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
console.error("Done!");
|
package/biome.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.5.6/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": true
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false
|
|
10
|
+
},
|
|
11
|
+
"formatter": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"indentStyle": "space"
|
|
14
|
+
},
|
|
15
|
+
"linter": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"rules": {
|
|
18
|
+
"preset": "recommended",
|
|
19
|
+
"a11y": {
|
|
20
|
+
"noSvgWithoutTitle": "off"
|
|
21
|
+
},
|
|
22
|
+
"style": {
|
|
23
|
+
"useNodejsImportProtocol": {
|
|
24
|
+
"level": "error",
|
|
25
|
+
"fix": "safe"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"javascript": {
|
|
31
|
+
"formatter": {
|
|
32
|
+
"quoteStyle": "double"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"assist": {
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"actions": {
|
|
38
|
+
"source": {
|
|
39
|
+
"organizeImports": "on"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ideasonpurpose/build-tools-wordpress",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.7",
|
|
4
4
|
"description": "Build scripts and dependencies for IOP's WordPress development environments.",
|
|
5
5
|
"homepage": "https://github.com/ideasonpurpose/build-tools-wordpress#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -23,14 +23,15 @@
|
|
|
23
23
|
"iop-build-zip-archive": "./bin/zip.js",
|
|
24
24
|
"iop-html-php-prettier": "./bin/format-php-prettier.js",
|
|
25
25
|
"iop-format-wp-block-pattern": "./bin/format-wp-block-pattern.js",
|
|
26
|
-
"iop-project-refresh": "./bin/refresh.js"
|
|
26
|
+
"iop-project-refresh": "./bin/refresh.js",
|
|
27
|
+
"iop-vscode-svgo": "./bin/vscode-svgo.js"
|
|
27
28
|
},
|
|
28
29
|
"directories": {
|
|
29
30
|
"lib": "lib"
|
|
30
31
|
},
|
|
31
32
|
"scripts": {
|
|
32
33
|
"test": "vitest",
|
|
33
|
-
"version": "version-everything &&
|
|
34
|
+
"version": "version-everything && git add -u"
|
|
34
35
|
},
|
|
35
36
|
"prettier": "@ideasonpurpose/prettier-config",
|
|
36
37
|
"dependencies": {
|
|
@@ -89,12 +90,10 @@
|
|
|
89
90
|
"version-everything": "^0.12.2",
|
|
90
91
|
"webpack": "^5.108.4",
|
|
91
92
|
"webpack-bundle-analyzer": "^5.3.1",
|
|
93
|
+
"webpack-cli": "^6.0.1",
|
|
92
94
|
"webpack-dev-server": "^6.0.0",
|
|
93
95
|
"webpack-manifest-plugin": "^6.0.1"
|
|
94
96
|
},
|
|
95
|
-
"peerDependencies": {
|
|
96
|
-
"webpack-cli": "^6.0.1"
|
|
97
|
-
},
|
|
98
97
|
"engines": {
|
|
99
98
|
"node": ">=22.15.0"
|
|
100
99
|
},
|
package/CHANGELOG.md
DELETED
|
@@ -1,520 +0,0 @@
|
|
|
1
|
-
### Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
|
4
|
-
|
|
5
|
-
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
|
-
|
|
7
|
-
#### v2.10.5
|
|
8
|
-
|
|
9
|
-
> 22 July 2026
|
|
10
|
-
|
|
11
|
-
- logo, vscode settings
|
|
12
|
-
- output tweaks
|
|
13
|
-
|
|
14
|
-
#### v2.10.4
|
|
15
|
-
|
|
16
|
-
> 18 July 2026
|
|
17
|
-
|
|
18
|
-
- fix zip reporting and resolve typescript types
|
|
19
|
-
|
|
20
|
-
#### v2.10.3
|
|
21
|
-
|
|
22
|
-
> 17 July 2026
|
|
23
|
-
|
|
24
|
-
- More reporter tweaks
|
|
25
|
-
|
|
26
|
-
#### v2.10.2
|
|
27
|
-
|
|
28
|
-
> 16 July 2026
|
|
29
|
-
|
|
30
|
-
- tweak reporting
|
|
31
|
-
|
|
32
|
-
#### v2.10.1
|
|
33
|
-
|
|
34
|
-
> 15 July 2026
|
|
35
|
-
|
|
36
|
-
- remove infrastructureLogging
|
|
37
|
-
|
|
38
|
-
#### v2.10.0
|
|
39
|
-
|
|
40
|
-
> 15 July 2026
|
|
41
|
-
|
|
42
|
-
- bump deps, AGENTS
|
|
43
|
-
- update proxy, messing with output
|
|
44
|
-
- add discard-changes config to example composer.json
|
|
45
|
-
|
|
46
|
-
#### v2.9.1
|
|
47
|
-
|
|
48
|
-
> 26 June 2026
|
|
49
|
-
|
|
50
|
-
- bump deps, format action
|
|
51
|
-
|
|
52
|
-
#### v2.9.0
|
|
53
|
-
|
|
54
|
-
> 26 June 2026
|
|
55
|
-
|
|
56
|
-
- update AGENTS
|
|
57
|
-
- strip dimensions from React-imported SVGRs.
|
|
58
|
-
|
|
59
|
-
#### v2.8.5
|
|
60
|
-
|
|
61
|
-
> 23 June 2026
|
|
62
|
-
|
|
63
|
-
- simplify release workflow
|
|
64
|
-
- suppress GTID warnings from mysqldump
|
|
65
|
-
|
|
66
|
-
#### v2.8.4
|
|
67
|
-
|
|
68
|
-
> 23 June 2026
|
|
69
|
-
|
|
70
|
-
- bump deps
|
|
71
|
-
- update SVGO config plus custom plugins
|
|
72
|
-
- extend whitespace handling to paragraphs with attributes
|
|
73
|
-
|
|
74
|
-
#### v2.8.3
|
|
75
|
-
|
|
76
|
-
> 5 June 2026
|
|
77
|
-
|
|
78
|
-
- make formatting conditionals work with npx again
|
|
79
|
-
- add WP_ENVIRONMENT_TYPE to docker-compose environment
|
|
80
|
-
|
|
81
|
-
#### v2.8.2
|
|
82
|
-
|
|
83
|
-
> 3 June 2026
|
|
84
|
-
|
|
85
|
-
- update zip script to use ESM archiver
|
|
86
|
-
|
|
87
|
-
#### v2.8.1
|
|
88
|
-
|
|
89
|
-
> 3 June 2026
|
|
90
|
-
|
|
91
|
-
- fix db connection checks in docker-compose
|
|
92
|
-
|
|
93
|
-
#### v2.8.0
|
|
94
|
-
|
|
95
|
-
> 3 June 2026
|
|
96
|
-
|
|
97
|
-
- bump deps
|
|
98
|
-
- refactor format functions and improve tests
|
|
99
|
-
- boilerplate and README SVGo info
|
|
100
|
-
|
|
101
|
-
#### v2.7.0
|
|
102
|
-
|
|
103
|
-
> 6 May 2026
|
|
104
|
-
|
|
105
|
-
- bump deps, migrate some tooling
|
|
106
|
-
- feat: add AI Coding Assistant guidelines documentation
|
|
107
|
-
|
|
108
|
-
#### v2.6.6
|
|
109
|
-
|
|
110
|
-
> 27 April 2026
|
|
111
|
-
|
|
112
|
-
- bump deps
|
|
113
|
-
- feat: add nested list structure and formatting for WordPress block patterns
|
|
114
|
-
- feat: add experimental formatting helpers for HTML/PHP and WordPress block patterns
|
|
115
|
-
|
|
116
|
-
#### v2.6.5
|
|
117
|
-
|
|
118
|
-
> 5 April 2026
|
|
119
|
-
|
|
120
|
-
- fix: update setup-node action version to v6 for consistency
|
|
121
|
-
|
|
122
|
-
#### v2.6.4
|
|
123
|
-
|
|
124
|
-
> 5 April 2026
|
|
125
|
-
|
|
126
|
-
- chore: update actions versions in npm-publish workflow and bump version-everything dependency
|
|
127
|
-
- feat: add new formatting functions for handling list elements and normalize newlines
|
|
128
|
-
|
|
129
|
-
#### v2.6.3
|
|
130
|
-
|
|
131
|
-
> 4 April 2026
|
|
132
|
-
|
|
133
|
-
- bump deps
|
|
134
|
-
- feat: add formatter for WordPress block pattern PHP files and corresponding tests
|
|
135
|
-
|
|
136
|
-
#### v2.6.2
|
|
137
|
-
|
|
138
|
-
> 23 March 2026
|
|
139
|
-
|
|
140
|
-
- feat: add error handling for WebSocket proxy requests
|
|
141
|
-
|
|
142
|
-
#### v2.6.1
|
|
143
|
-
|
|
144
|
-
> 23 March 2026
|
|
145
|
-
|
|
146
|
-
- chore: update dependencies in package.json
|
|
147
|
-
|
|
148
|
-
#### v2.6.0
|
|
149
|
-
|
|
150
|
-
> 13 March 2026
|
|
151
|
-
|
|
152
|
-
- bump deps, remove debug logs, resulve from sass & styles
|
|
153
|
-
|
|
154
|
-
#### v2.5.1
|
|
155
|
-
|
|
156
|
-
> 8 March 2026
|
|
157
|
-
|
|
158
|
-
- add rimraf
|
|
159
|
-
- add SVG processing details to README
|
|
160
|
-
- add comment for runner images in release workflow
|
|
161
|
-
|
|
162
|
-
#### v2.5.0
|
|
163
|
-
|
|
164
|
-
> 7 March 2026
|
|
165
|
-
|
|
166
|
-
- bump deps
|
|
167
|
-
- beginning of typing, some cleanup
|
|
168
|
-
- inline SVGs in SCSS files by default
|
|
169
|
-
|
|
170
|
-
#### v2.4.2
|
|
171
|
-
|
|
172
|
-
> 22 December 2025
|
|
173
|
-
|
|
174
|
-
- Update npm publish command with options
|
|
175
|
-
|
|
176
|
-
#### v2.4.1
|
|
177
|
-
|
|
178
|
-
> 22 December 2025
|
|
179
|
-
|
|
180
|
-
- update workflow for trusted publishing
|
|
181
|
-
|
|
182
|
-
#### v2.4.0
|
|
183
|
-
|
|
184
|
-
> 21 December 2025
|
|
185
|
-
|
|
186
|
-
- bump deps
|
|
187
|
-
- Enable loading Sass files from node_modules
|
|
188
|
-
|
|
189
|
-
#### v2.3.2
|
|
190
|
-
|
|
191
|
-
> 3 November 2025
|
|
192
|
-
|
|
193
|
-
- bump deps
|
|
194
|
-
- watch tweaks, debugging, formatting and cleanup
|
|
195
|
-
|
|
196
|
-
#### v2.3.1
|
|
197
|
-
|
|
198
|
-
> 21 October 2025
|
|
199
|
-
|
|
200
|
-
- liveReload workaround for mini-css-extract-plugin HMR issues
|
|
201
|
-
- WIP updates
|
|
202
|
-
|
|
203
|
-
#### v2.3.0
|
|
204
|
-
|
|
205
|
-
> 19 October 2025
|
|
206
|
-
|
|
207
|
-
- Fixes and optimizations for multiple entry points
|
|
208
|
-
|
|
209
|
-
#### v2.2.6
|
|
210
|
-
|
|
211
|
-
> 18 October 2025
|
|
212
|
-
|
|
213
|
-
- bump deps
|
|
214
|
-
|
|
215
|
-
#### v2.2.5
|
|
216
|
-
|
|
217
|
-
> 6 October 2025
|
|
218
|
-
|
|
219
|
-
- bump deps
|
|
220
|
-
- update example docker-compose file with experimental WP Multisite envvars
|
|
221
|
-
|
|
222
|
-
#### v2.2.4
|
|
223
|
-
|
|
224
|
-
> 10 September 2025
|
|
225
|
-
|
|
226
|
-
- Make iop-format-prettier work globally
|
|
227
|
-
|
|
228
|
-
#### v2.2.3
|
|
229
|
-
|
|
230
|
-
> 9 September 2025
|
|
231
|
-
|
|
232
|
-
- trying explicit PHP plugin loading
|
|
233
|
-
|
|
234
|
-
#### v2.2.2
|
|
235
|
-
|
|
236
|
-
> 9 September 2025
|
|
237
|
-
|
|
238
|
-
- tweaking deps
|
|
239
|
-
|
|
240
|
-
#### v2.2.1
|
|
241
|
-
|
|
242
|
-
> 9 September 2025
|
|
243
|
-
|
|
244
|
-
- tweak format-php-prettier, bump deps
|
|
245
|
-
|
|
246
|
-
#### v2.2.0
|
|
247
|
-
|
|
248
|
-
> 7 September 2025
|
|
249
|
-
|
|
250
|
-
- bump deps
|
|
251
|
-
- Update websocket reload for v5, cleanup
|
|
252
|
-
- Testing some watch fixes
|
|
253
|
-
|
|
254
|
-
#### v2.1.11
|
|
255
|
-
|
|
256
|
-
> 3 September 2025
|
|
257
|
-
|
|
258
|
-
- bump deps
|
|
259
|
-
|
|
260
|
-
#### v2.1.10
|
|
261
|
-
|
|
262
|
-
> 3 September 2025
|
|
263
|
-
|
|
264
|
-
- tweak devserver hot setting
|
|
265
|
-
|
|
266
|
-
#### v2.1.9
|
|
267
|
-
|
|
268
|
-
> 24 August 2025
|
|
269
|
-
|
|
270
|
-
- bump deps
|
|
271
|
-
|
|
272
|
-
#### v2.1.8
|
|
273
|
-
|
|
274
|
-
> 29 May 2025
|
|
275
|
-
|
|
276
|
-
- Fix inline-whitespace wrapped php token bug
|
|
277
|
-
- typo
|
|
278
|
-
|
|
279
|
-
#### v2.1.7
|
|
280
|
-
|
|
281
|
-
> 28 May 2025
|
|
282
|
-
|
|
283
|
-
- bump deps
|
|
284
|
-
- enable sourcemaps on all CSS loaders
|
|
285
|
-
|
|
286
|
-
#### v2.1.6
|
|
287
|
-
|
|
288
|
-
> 1 May 2025
|
|
289
|
-
|
|
290
|
-
- refactor tokenizeHTML, bug fixes, tests
|
|
291
|
-
- typo
|
|
292
|
-
|
|
293
|
-
#### v2.1.5
|
|
294
|
-
|
|
295
|
-
> 17 April 2025
|
|
296
|
-
|
|
297
|
-
- escape capture group replacement strings when unTokenizing, plus tests
|
|
298
|
-
- change dev site reporter emoji
|
|
299
|
-
|
|
300
|
-
#### v2.1.4
|
|
301
|
-
|
|
302
|
-
> 16 April 2025
|
|
303
|
-
|
|
304
|
-
- use look-behind and look-forward to allow overlaps, simplify replacements
|
|
305
|
-
- fix README
|
|
306
|
-
|
|
307
|
-
#### v2.1.3
|
|
308
|
-
|
|
309
|
-
> 16 April 2025
|
|
310
|
-
|
|
311
|
-
- Use self-closing html tags as tokens. Closes #11
|
|
312
|
-
|
|
313
|
-
#### v2.1.2
|
|
314
|
-
|
|
315
|
-
> 14 April 2025
|
|
316
|
-
|
|
317
|
-
- bump deps
|
|
318
|
-
- experimental html & php formatter
|
|
319
|
-
|
|
320
|
-
#### v2.1.1
|
|
321
|
-
|
|
322
|
-
> 9 April 2025
|
|
323
|
-
|
|
324
|
-
- Clean up outputs a little
|
|
325
|
-
|
|
326
|
-
#### v2.1.0
|
|
327
|
-
|
|
328
|
-
> 1 April 2025
|
|
329
|
-
|
|
330
|
-
- bump deps
|
|
331
|
-
- Standardize on sass-embedded, clean up, bump deps
|
|
332
|
-
|
|
333
|
-
#### v2.0.6
|
|
334
|
-
|
|
335
|
-
> 20 March 2025
|
|
336
|
-
|
|
337
|
-
- try moving webpack-cli to peerDependencies
|
|
338
|
-
|
|
339
|
-
#### v2.0.5
|
|
340
|
-
|
|
341
|
-
> 20 March 2025
|
|
342
|
-
|
|
343
|
-
- add note about local development to readme
|
|
344
|
-
- resolve webpack loaders when running linked
|
|
345
|
-
- Fix for missing content-type header
|
|
346
|
-
|
|
347
|
-
#### v2.0.4
|
|
348
|
-
|
|
349
|
-
> 19 March 2025
|
|
350
|
-
|
|
351
|
-
- update GitHub Actions
|
|
352
|
-
|
|
353
|
-
#### v2.0.3
|
|
354
|
-
|
|
355
|
-
> 19 March 2025
|
|
356
|
-
|
|
357
|
-
- bump deps
|
|
358
|
-
- update example files
|
|
359
|
-
- update devserver-proxy tests
|
|
360
|
-
|
|
361
|
-
#### v2.0.2
|
|
362
|
-
|
|
363
|
-
> 13 January 2025
|
|
364
|
-
|
|
365
|
-
- bump deps
|
|
366
|
-
|
|
367
|
-
#### v2.0.1
|
|
368
|
-
|
|
369
|
-
> 19 October 2024
|
|
370
|
-
|
|
371
|
-
- another Sass bump
|
|
372
|
-
|
|
373
|
-
#### v2.0.0
|
|
374
|
-
|
|
375
|
-
> 19 October 2024
|
|
376
|
-
|
|
377
|
-
- bump deps
|
|
378
|
-
- update example webpack.config file
|
|
379
|
-
- bump deps
|
|
380
|
-
|
|
381
|
-
#### v1.2.1
|
|
382
|
-
|
|
383
|
-
> 19 September 2024
|
|
384
|
-
|
|
385
|
-
- plugins updates, config fixes
|
|
386
|
-
|
|
387
|
-
#### v1.2.0
|
|
388
|
-
|
|
389
|
-
> 19 September 2024
|
|
390
|
-
|
|
391
|
-
- deprecation free build! closes #5
|
|
392
|
-
- bump deps, remove some for deprecations. Ref #5
|
|
393
|
-
- bump deps, update examples and testing
|
|
394
|
-
- export webpackConfig
|
|
395
|
-
|
|
396
|
-
#### v1.1.14
|
|
397
|
-
|
|
398
|
-
> 6 May 2024
|
|
399
|
-
|
|
400
|
-
- minor bumps
|
|
401
|
-
|
|
402
|
-
#### v1.1.13
|
|
403
|
-
|
|
404
|
-
> 10 April 2024
|
|
405
|
-
|
|
406
|
-
- bump most all the deps
|
|
407
|
-
- add read-package-up, esTarget: es2020
|
|
408
|
-
- readme tweak
|
|
409
|
-
|
|
410
|
-
#### v1.1.12
|
|
411
|
-
|
|
412
|
-
> 4 March 2024
|
|
413
|
-
|
|
414
|
-
- readme badge links
|
|
415
|
-
- were all these problems just a missing shebang?
|
|
416
|
-
|
|
417
|
-
#### v1.1.11
|
|
418
|
-
|
|
419
|
-
> 4 March 2024
|
|
420
|
-
|
|
421
|
-
- Remove version from plugin builds WIP
|
|
422
|
-
|
|
423
|
-
#### v1.1.10
|
|
424
|
-
|
|
425
|
-
> 4 March 2024
|
|
426
|
-
|
|
427
|
-
- use process.stdout references (of course)
|
|
428
|
-
|
|
429
|
-
#### v1.1.9
|
|
430
|
-
|
|
431
|
-
> 4 March 2024
|
|
432
|
-
|
|
433
|
-
- update actions
|
|
434
|
-
- missed a couple readline calls
|
|
435
|
-
|
|
436
|
-
#### v1.1.8
|
|
437
|
-
|
|
438
|
-
> 4 March 2024
|
|
439
|
-
|
|
440
|
-
- quick remove readline function
|
|
441
|
-
|
|
442
|
-
#### v1.1.7
|
|
443
|
-
|
|
444
|
-
> 4 March 2024
|
|
445
|
-
|
|
446
|
-
- extracting the zip script, updated deps
|
|
447
|
-
- WIP example webpack.config.js file
|
|
448
|
-
- update readme
|
|
449
|
-
|
|
450
|
-
#### v1.1.6
|
|
451
|
-
|
|
452
|
-
> 30 January 2024
|
|
453
|
-
|
|
454
|
-
- test stuff and fixes
|
|
455
|
-
- misc fixes and first zip testing
|
|
456
|
-
|
|
457
|
-
#### v1.1.5
|
|
458
|
-
|
|
459
|
-
> 25 January 2024
|
|
460
|
-
|
|
461
|
-
- move the localPort stuff into devserver-proxy
|
|
462
|
-
|
|
463
|
-
#### v1.1.4
|
|
464
|
-
|
|
465
|
-
> 25 January 2024
|
|
466
|
-
|
|
467
|
-
- deps, formatting, debugging
|
|
468
|
-
|
|
469
|
-
#### v1.1.3
|
|
470
|
-
|
|
471
|
-
> 24 January 2024
|
|
472
|
-
|
|
473
|
-
- reconfigure imports, port-reporter to module, lots of deps
|
|
474
|
-
- add changelog, update readme (badges)
|
|
475
|
-
- fix path to port-reporter script
|
|
476
|
-
|
|
477
|
-
#### v1.1.2
|
|
478
|
-
|
|
479
|
-
> 23 January 2024
|
|
480
|
-
|
|
481
|
-
#### v1.1.1
|
|
482
|
-
|
|
483
|
-
> 23 January 2024
|
|
484
|
-
|
|
485
|
-
- versioning, github actions, bump deps, README
|
|
486
|
-
- update version in readme
|
|
487
|
-
|
|
488
|
-
#### v1.1.0
|
|
489
|
-
|
|
490
|
-
> 23 January 2024
|
|
491
|
-
|
|
492
|
-
- add packages
|
|
493
|
-
- name change, prepare for npm publish
|
|
494
|
-
- add port-reporter script, giving up on linking local pacakges
|
|
495
|
-
|
|
496
|
-
#### v1.0.4
|
|
497
|
-
|
|
498
|
-
> 16 January 2024
|
|
499
|
-
|
|
500
|
-
- embed default.config
|
|
501
|
-
|
|
502
|
-
#### v1.0.3
|
|
503
|
-
|
|
504
|
-
> 16 January 2024
|
|
505
|
-
|
|
506
|
-
- buildConfig
|
|
507
|
-
|
|
508
|
-
#### v1.0.2
|
|
509
|
-
|
|
510
|
-
> 16 January 2024
|
|
511
|
-
|
|
512
|
-
- add sass-embedded
|
|
513
|
-
|
|
514
|
-
#### v1.0.1
|
|
515
|
-
|
|
516
|
-
> 16 January 2024
|
|
517
|
-
|
|
518
|
-
- add modules
|
|
519
|
-
- add lib, temp exports
|
|
520
|
-
- Initial commit
|
|
File without changes
|