@beforesemicolon/builder 1.6.2 → 1.6.4
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 +214 -1
- package/dist/cjs/build-browser.js +1 -1
- package/dist/esm/build-browser.js +1 -1
- package/dist/types/build-browser.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,216 @@
|
|
|
1
1
|
# @beforesemicolon/builder
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Utilities to build npm packages and a documentation website for Before Semicolon projects.
|
|
4
|
+
|
|
5
|
+
This package provides small, focused helpers to:
|
|
6
|
+
|
|
7
|
+
- Build server-friendly CommonJS and ESM module bundles (dist/cjs and dist/esm).
|
|
8
|
+
- Produce a browser bundle (dist/client.js) for documentation or demos.
|
|
9
|
+
- Render a static documentation website from Markdown files (output defaults to `website/`).
|
|
10
|
+
|
|
11
|
+
Table of contents
|
|
12
|
+
|
|
13
|
+
- Features
|
|
14
|
+
- Requirements
|
|
15
|
+
- Installation
|
|
16
|
+
- Quick examples
|
|
17
|
+
- Library usage (Node)
|
|
18
|
+
- Building the browser bundle
|
|
19
|
+
- Generating the documentation website
|
|
20
|
+
- API
|
|
21
|
+
- buildModules(options?)
|
|
22
|
+
- buildBrowser(options?)
|
|
23
|
+
- buildDocs(options?)
|
|
24
|
+
- Documentation site layout and front-matter
|
|
25
|
+
- Scripts (in package.json)
|
|
26
|
+
- Development
|
|
27
|
+
- Contributing
|
|
28
|
+
- License
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
Features
|
|
32
|
+
|
|
33
|
+
- Builds all TypeScript sources into both ESM and CJS formats using esbuild.
|
|
34
|
+
- Produces a single browser bundle for client-side documentation UI.
|
|
35
|
+
- Static site generator for Markdown: supports layouts, assets, stylesheets, and scripts.
|
|
36
|
+
- Uses marked + highlight.js for Markdown rendering, DOMPurify for sanitization and minifies output CSS/JS/HTML.
|
|
37
|
+
- Simple, zero-config defaults plus options for common customization.
|
|
38
|
+
|
|
39
|
+
Requirements
|
|
40
|
+
|
|
41
|
+
- Node.js >= 18.16.0 (see `engines` in package.json)
|
|
42
|
+
|
|
43
|
+
Installation
|
|
44
|
+
|
|
45
|
+
Install from npm (package name: `@beforesemicolon/builder`) or use the repo directly.
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
# npm
|
|
49
|
+
npm install @beforesemicolon/builder
|
|
50
|
+
|
|
51
|
+
# or using the repository
|
|
52
|
+
git clone https://github.com/beforesemicolon/builder.git
|
|
53
|
+
cd builder
|
|
54
|
+
npm install
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Quick examples
|
|
58
|
+
|
|
59
|
+
Library usage (Node / programmatic)
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
// ESM
|
|
63
|
+
import { buildModules, buildBrowser, buildDocs } from '@beforesemicolon/builder'
|
|
64
|
+
|
|
65
|
+
// Build server-side modules (dist/esm and dist/cjs)
|
|
66
|
+
await buildModules({ directoryPath: 'src' })
|
|
67
|
+
|
|
68
|
+
// Build single browser bundle (defaults to src/client -> dist/client.js)
|
|
69
|
+
await buildBrowser({ entry: 'src/client', out: 'dist/client.js' })
|
|
70
|
+
|
|
71
|
+
// Generate static docs (defaults: docs -> website)
|
|
72
|
+
await buildDocs({ srcDir: 'docs', publicDir: 'website' })
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
CommonJS
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const { buildModules, buildBrowser, buildDocs } = require('@beforesemicolon/builder')
|
|
79
|
+
|
|
80
|
+
;(async () => {
|
|
81
|
+
await buildModules()
|
|
82
|
+
await buildBrowser()
|
|
83
|
+
await buildDocs()
|
|
84
|
+
})()
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
CLI / npm scripts
|
|
88
|
+
|
|
89
|
+
The repo ships with a `build` script that will emit types and run the TypeScript build entry (`build.ts`).
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
npm run build
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This runs TypeScript declaration emission and then executes `build.ts` which calls `buildModules()` to produce the `dist/` outputs.
|
|
96
|
+
|
|
97
|
+
API
|
|
98
|
+
|
|
99
|
+
- buildModules(options?: { directoryPath?: string }) => Promise
|
|
100
|
+
- Scans the given directory (default: `process.cwd()/src`) recursively for files and builds them into:
|
|
101
|
+
- `dist/esm` (ESM format)
|
|
102
|
+
- `dist/cjs` (CommonJS format)
|
|
103
|
+
- Files ending with `.spec.ts` or `/client.ts` are ignored from the module build set.
|
|
104
|
+
- Uses `esbuild` with minification and keeps symbol names for better stack traces.
|
|
105
|
+
|
|
106
|
+
- buildBrowser(options?: { entry?: string; out?: string }) => Promise
|
|
107
|
+
- Bundles a single browser file using `esbuild`.
|
|
108
|
+
- Defaults: `entry` -> `src/client`, `out` -> `dist/client.js`.
|
|
109
|
+
- Includes a small plugin to remove the `Doc` export from `@beforesemicolon/html-parser` during bundling (keeps bundle size smaller when that export isn't used).
|
|
110
|
+
- Generates sourcemaps and minifies the output.
|
|
111
|
+
|
|
112
|
+
- buildDocs(options?: { srcDir?: string; publicDir?: string }) => Promise
|
|
113
|
+
- Generates a static documentation website from a Markdown `docs` directory.
|
|
114
|
+
- Defaults: `srcDir` -> `docs`, `publicDir` -> `website`.
|
|
115
|
+
- Supported docs structure (defaults used by the generator):
|
|
116
|
+
- `_layouts/` — custom templates (each module should default-export a function matching `PageProps`)
|
|
117
|
+
- `assets/` — copied to the site output
|
|
118
|
+
- `stylesheets/` — CSS files are minified and copied
|
|
119
|
+
- `scripts/` — JS files are minified and copied
|
|
120
|
+
- `*.md` — Markdown pages with front-matter to control metadata
|
|
121
|
+
- Pages use `marked` with a custom renderer (heading IDs, code blocks, links) and `highlight.js` for syntax highlighting.
|
|
122
|
+
- HTML is sanitized with DOMPurify and minified with `html-minifier`.
|
|
123
|
+
|
|
124
|
+
Documentation site layout and front-matter
|
|
125
|
+
|
|
126
|
+
Markdown pages should contain front-matter (YAML) with properties compatible with the site's `PageProps`:
|
|
127
|
+
|
|
128
|
+
- title: string — page title (used in the HTML title)
|
|
129
|
+
- description: string — meta description
|
|
130
|
+
- order: number — numeric order used when building the site map and sorting pages
|
|
131
|
+
- layout: string — layout name; corresponds to a template in `_layouts` (default: `default`)
|
|
132
|
+
|
|
133
|
+
PageProps (shape used by layouts)
|
|
134
|
+
|
|
135
|
+
- name: string
|
|
136
|
+
- path: string (page path, e.g. `/guide/getting-started.html`)
|
|
137
|
+
- order: number
|
|
138
|
+
- title: string
|
|
139
|
+
- description: string
|
|
140
|
+
- content: string (HTML produced from Markdown)
|
|
141
|
+
- siteMap: Map representing the site structure
|
|
142
|
+
- tableOfContent: array of { path, label } entries generated from headings
|
|
143
|
+
|
|
144
|
+
A minimal docs layout example (the package ships a simple `default` template):
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
export default ({ title, description, content }) => `
|
|
148
|
+
<!doctype html>
|
|
149
|
+
<html>
|
|
150
|
+
<head>
|
|
151
|
+
<meta charset="utf-8" />
|
|
152
|
+
<meta name="description" content="${description}" />
|
|
153
|
+
<title>${title}</title>
|
|
154
|
+
</head>
|
|
155
|
+
<body>
|
|
156
|
+
${content}
|
|
157
|
+
</body>
|
|
158
|
+
</html>`
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Scripts (from package.json)
|
|
162
|
+
|
|
163
|
+
- `build` — removes `dist`, emits TypeScript declarations, then runs `build.ts` (which calls `buildModules`).
|
|
164
|
+
- `lint` — runs ESLint and Prettier check
|
|
165
|
+
- `format` — runs ESLint autofix and Prettier write
|
|
166
|
+
|
|
167
|
+
Development
|
|
168
|
+
|
|
169
|
+
- Ensure you use Node >= 18.16.0
|
|
170
|
+
- Install dependencies:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
npm install
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
- Run the build pipeline locally:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
npm run build
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- Lint and format:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
npm run lint
|
|
186
|
+
npm run format
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- The source entry points are in `src/`. `src/build-modules.ts`, `src/build-browser.ts` and `src/docs/run.ts` provide the public functionality.
|
|
190
|
+
|
|
191
|
+
Testing and validation
|
|
192
|
+
|
|
193
|
+
This repository does not include automated tests by default. If you add tests, consider using the existing devDependencies (TypeScript + ts-jest + tinybench if you want benchmarks).
|
|
194
|
+
|
|
195
|
+
Contributing
|
|
196
|
+
|
|
197
|
+
Contributions are welcome. A good workflow is:
|
|
198
|
+
|
|
199
|
+
1. Fork the repository and create a feature branch.
|
|
200
|
+
2. Add or modify code in `src/`.
|
|
201
|
+
3. Run `npm run build` to check the build output.
|
|
202
|
+
4. Run `npm run lint` or `npm run format` to keep code style consistent.
|
|
203
|
+
5. Open a pull request describing the change.
|
|
204
|
+
|
|
205
|
+
License
|
|
206
|
+
|
|
207
|
+
BSD-3-Clause — see `package.json` for author and license metadata.
|
|
208
|
+
|
|
209
|
+
Acknowledgements and internals
|
|
210
|
+
|
|
211
|
+
- Uses `esbuild` for fast bundling and minification.
|
|
212
|
+
- Markdown rendering powered by `marked` with a custom renderer and `marked-highlight` plugin using `highlight.js`.
|
|
213
|
+
- Front-matter parsing via `front-matter`.
|
|
214
|
+
- DOM sanitization by `isomorphic-dompurify` and HTML/CSS/JS minification using `html-minifier`, `clean-css`, and `@putout/minify` respectively.
|
|
215
|
+
|
|
216
|
+
If you'd like any sections expanded (examples, advanced options, or a CONTRIBUTING.md), tell me which parts to elaborate and I'll add them.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.create;var n=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var i=(e,r)=>n(e,"name",{value:r,configurable:!0});var g=(e,r)=>{for(var t in r)n(e,t,{get:r[t],enumerable:!0})},c=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of d(r))!y.call(e,o)&&o!==t&&n(e,o,{get:()=>r[o],enumerable:!(s=m(r,o))||s.enumerable});return e};var p=(e,r,t)=>(t=e!=null?a(f(e)):{},c(r||!e||!e.__esModule?n(t,"default",{value:e,enumerable:!0}):t,e)),h=e=>c(n({},"__esModule",{value:!0}),e);var D={};g(D,{buildBrowser:()=>B});module.exports=h(D);var l=p(require("path"),1),u=p(require("esbuild"),1);const B=i(async({entry:e,out:r})=>{const t={name:"empty-parser-Doc-plugin",setup(s){s.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),s.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};u.default.build({entryPoints:[e??l.default.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[t]}).catch(console.error)},"buildBrowser");0&&(module.exports={buildBrowser});
|
|
1
|
+
"use strict";var a=Object.create;var n=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var i=(e,r)=>n(e,"name",{value:r,configurable:!0});var g=(e,r)=>{for(var t in r)n(e,t,{get:r[t],enumerable:!0})},c=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of d(r))!y.call(e,o)&&o!==t&&n(e,o,{get:()=>r[o],enumerable:!(s=m(r,o))||s.enumerable});return e};var p=(e,r,t)=>(t=e!=null?a(f(e)):{},c(r||!e||!e.__esModule?n(t,"default",{value:e,enumerable:!0}):t,e)),h=e=>c(n({},"__esModule",{value:!0}),e);var D={};g(D,{buildBrowser:()=>B});module.exports=h(D);var l=p(require("path"),1),u=p(require("esbuild"),1);const B=i(async({entry:e,out:r}={})=>{const t={name:"empty-parser-Doc-plugin",setup(s){s.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),s.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};u.default.build({entryPoints:[e??l.default.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[t]}).catch(console.error)},"buildBrowser");0&&(module.exports={buildBrowser});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var i=Object.defineProperty;var s=(e,r)=>i(e,"name",{value:r,configurable:!0});import c from"path";import p from"esbuild";const d=s(async({entry:e,out:r})=>{const n={name:"empty-parser-Doc-plugin",setup(t){t.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),t.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};p.build({entryPoints:[e??c.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[n]}).catch(console.error)},"buildBrowser");export{d as buildBrowser};
|
|
1
|
+
var i=Object.defineProperty;var s=(e,r)=>i(e,"name",{value:r,configurable:!0});import c from"path";import p from"esbuild";const d=s(async({entry:e,out:r}={})=>{const n={name:"empty-parser-Doc-plugin",setup(t){t.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),t.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};p.build({entryPoints:[e??c.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[n]}).catch(console.error)},"buildBrowser");export{d as buildBrowser};
|