@normed/bundle 4.6.3 → 4.7.1

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 CHANGED
@@ -6,6 +6,10 @@ Given a version number MAJOR.MINOR.PATCH, increment the:
6
6
  2. MINOR version when you add functionality in a backwards compatible manner, and
7
7
  3. PATCH version when you make backwards compatible bug fixes.
8
8
 
9
+ # 4.7.1
10
+
11
+ * PATCH: Fix `node.attrs is not iterable` error in pug templates when non-Tag AST nodes (e.g. code blocks, mixins, comments) are encountered during asset path rebasing.
12
+
9
13
  # 4.6.3
10
14
 
11
15
  * PATCH: Fix JavaScript and TypeScript files referenced from `.static.pug` templates being copied verbatim instead of being bundled. Script files (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) are now properly processed through esbuild, bundling imports and transpiling TypeScript, producing `.js` output with correct paths in the generated HTML.
package/README.md CHANGED
@@ -192,6 +192,53 @@ Common asset types are automatically configured to use esbuild's `file` loader:
192
192
 
193
193
  This means these files referenced from your CSS/JS will be copied to the output directory and their paths will be rewritten appropriately.
194
194
 
195
+ ### asset paths
196
+
197
+ By default, asset paths in the output are relative to the HTML/CSS file that references them. To serve static assets (images, fonts, media files) from a CDN or a specific URL prefix, use the `publicPath` esbuild option:
198
+
199
+ ```json
200
+ {
201
+ "bundle": {
202
+ "baseConfig": {
203
+ "javascript": {
204
+ "esbuild": {
205
+ "publicPath": "https://cdn.example.com/assets"
206
+ }
207
+ }
208
+ }
209
+ }
210
+ }
211
+ ```
212
+
213
+ With this configuration, static asset references like `<img src="logo.png">` in pug/HTML and `url(images/bg.png)` in CSS will be rewritten to use the public path prefix (e.g., `https://cdn.example.com/assets/logo-A1B2C3D4.png`).
214
+
215
+ **Note:** `publicPath` only affects static assets (images, fonts, media). Links between HTML pages, CSS stylesheets, and JavaScript files discovered in pug templates always use relative paths.
216
+
217
+ You can also customize how asset filenames are generated using the `assetNames` option:
218
+
219
+ ```json
220
+ {
221
+ "bundle": {
222
+ "baseConfig": {
223
+ "javascript": {
224
+ "esbuild": {
225
+ "publicPath": "/static",
226
+ "assetNames": "assets/[name]-[hash]"
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ The `assetNames` template supports the following placeholders:
235
+ - `[name]` - The original filename without extension
236
+ - `[hash]` - A content-based hash for cache busting
237
+ - `[ext]` - The file extension
238
+ - `[dir]` - The directory path relative to the source directory
239
+
240
+ The default is `[name]-[hash]` for static assets in pug templates. For CSS/JS files discovered in pug templates, the default is `[dir]/[name]-[hash]` to preserve directory structure.
241
+
195
242
  ### external CSS URLs
196
243
 
197
244
  For CSS files that reference runtime paths (like `/fonts/*` or `/images/*`) that should not be resolved at build time, use the `css.externalUrls` configuration:
@@ -240,6 +287,60 @@ Features:
240
287
 
241
288
  This works for all HTML attributes that can contain paths (href, src, data, poster, etc.).
242
289
 
290
+ ### Node-resolved references (`build:` / `copy:`)
291
+
292
+ Pug templates support two prefixes for referencing files via Node's module resolution (`require.resolve`):
293
+
294
+ | Prefix | Action |
295
+ |--------|--------|
296
+ | `build:` | Resolve via Node, then compile through the appropriate pipeline (Less→CSS, Pug→HTML, TS→JS) |
297
+ | `copy:` | Resolve via Node, then copy to output with content-hashing |
298
+
299
+ ```pug
300
+ //- Compile a Less file from a shared location
301
+ link(rel="stylesheet" href="build:#shared/styles.less")
302
+
303
+ //- Copy a vendor CSS file (url() references are rewritten)
304
+ link(rel="stylesheet" href="copy:normalize.css/normalize.css")
305
+
306
+ //- Copy a vendor JS file as-is
307
+ script(src="copy:bootstrap/dist/js/bootstrap.min.js")
308
+ ```
309
+
310
+ Both prefixes support:
311
+ - **Bare specifiers**: `bootstrap/dist/css/bootstrap.css` — resolves from `node_modules`
312
+ - **`#` subpath imports**: `#shared/styles.less` — resolves via the `imports` field in `package.json`
313
+
314
+ #### Configuring `#` subpath imports
315
+
316
+ Add an `imports` field to your `package.json`:
317
+
318
+ ```json
319
+ {
320
+ "imports": {
321
+ "#shared/*": "./src/shared/*",
322
+ "#assets/*": "./src/assets/*"
323
+ }
324
+ }
325
+ ```
326
+
327
+ This is a standard Node.js feature (v12.19+) that also works natively in esbuild and TypeScript (4.5+). One config, consistent everywhere.
328
+
329
+ #### `build:` supported file types
330
+
331
+ | Extension | Pipeline |
332
+ |-----------|----------|
333
+ | `.less` | Less → CSS (via esbuild CSS pipeline) |
334
+ | `.pug` | Pug → HTML |
335
+ | `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs` | TypeScript/JavaScript bundling |
336
+ | `.css` | CSS (via esbuild CSS pipeline, handles `url()` rewriting) |
337
+
338
+ Using `build:` on an unsupported extension emits a warning suggesting `copy:` instead.
339
+
340
+ #### Deprecation of `pkg:`
341
+
342
+ The `pkg:` prefix is deprecated in favour of `copy:`. Both work identically — `pkg:` emits a deprecation warning during build. Replace `pkg:normalize.css/normalize.css` with `copy:normalize.css/normalize.css`.
343
+
243
344
  ### analyse
244
345
 
245
346
  To get a report on bundle content and size enable analysis:
@@ -364,6 +465,16 @@ Now `*.worker.ts` files will be discovered and built with server platform settin
364
465
 
365
466
  Use `LOG_LEVEL=verbose yarn bundle` to see which patterns are being searched.
366
467
 
468
+ # Known issues
469
+
470
+ ### Declaration generation may resolve wrong dependency versions
471
+
472
+ When `declarations: true` is set, the bundler uses TypeScript's compiler API (`ts.createProgram`) to generate `.d.ts` files. In Yarn PnP environments, this can resolve `@types` packages to the wrong version — e.g. picking up a transitive `@types/node@20` instead of your workspace's direct `@types/node@25`.
473
+
474
+ This happens because `ts.createCompilerHost` uses filesystem-walking resolution, which goes through PnP's `fs` patch (layer 2) rather than PnP's scope-aware `require` resolution (layer 1). The `fs` patch makes all zip cache contents readable but doesn't enforce dependency scoping, so transitive dependencies can leak into type resolution. The Yarn TypeScript SDK solves this for `tsc` and `tsserver` by wrapping them to call `.pnp.cjs.setup()`, but the programmatic `ts.createProgram` API doesn't benefit from this.
475
+
476
+ If you encounter spurious type errors during declaration generation that don't appear in `tsc` or your IDE, this is likely the cause. A workaround is to fix the offending type at the call site.
477
+
367
478
  # Potential errors
368
479
 
369
480
  es-build, which is essentially the basis for this whole thing, breaks reproducible builds as it includes the full path to a file as both a comment and a map key. To get around this we manually replace certain paths on build. There is a good chance this will not work for globally installed modules and will break certain hard coded strings.
@@ -1,4 +1,4 @@
1
- import type { ResolvedEntryConfig, EntryConfig, CompleteEntryConfig } from "./types";
1
+ import type { ResolvedEntryConfig, EntryConfig, CompleteEntryConfig } from "./types.ts";
2
2
  export declare class EntryConfigInstance {
3
3
  readonly config: ResolvedEntryConfig;
4
4
  readonly name: string;