onlybuild 1.0.0 → 1.1.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 +14 -0
- package/README.md +140 -6
- package/bin/index.js +51 -6
- package/package.json +3 -2
- package/src/build.js +35 -16
- package/src/copy.js +15 -5
- package/src/html.js +2 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [v1.1.0](https://github.com/neogeek/onlybuild/tree/v1.1.0) - (2024-04-26)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/neogeek/onlybuild/compare/v1.0.0...v1.1.0)
|
|
6
|
+
|
|
7
|
+
- [feat] Added input arg and version, help and out flags. [#2](https://github.com/neogeek/onlybuild/pull/2)
|
|
8
|
+
- [feat] Broke out build and copy methods into smaller ones. [#1](https://github.com/neogeek/onlybuild/pull/1)
|
|
9
|
+
|
|
10
|
+
## [v1.0.0](https://github.com/neogeek/onlybuild/tree/v1.0.0) - (2024-04-23)
|
|
11
|
+
|
|
12
|
+
- Initial release! 🎉
|
|
13
|
+
|
|
14
|
+
_This changelog was generated with **[generate-local-changelog](https://github.com/neogeek/generate-local-changelog)**_
|
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/neogeek/onlybuild/actions/workflows/test.workflow.yml)
|
|
6
6
|
[](https://github.com/neogeek/onlybuild/actions/workflows/publish.workflow.yml)
|
|
7
|
+
[](https://doxdox.org/neogeek/onlybuild)
|
|
7
8
|
[](https://www.npmjs.org/package/onlybuild)
|
|
8
9
|
[](https://discord.gg/nNtFsfd)
|
|
9
10
|
|
|
@@ -26,11 +27,14 @@
|
|
|
26
27
|
## Table of Contents
|
|
27
28
|
|
|
28
29
|
- [Install](#install)
|
|
30
|
+
- [Usage](#usage)
|
|
29
31
|
- [Quick Start Guide](#quick-start-guide)
|
|
30
32
|
- [Getting Started](#getting-started)
|
|
31
33
|
- [File Structure](#file-structure)
|
|
32
34
|
- [Ignore Files](#ignore-files)
|
|
33
35
|
- [Formatting Files](#formatting-files)
|
|
36
|
+
- [Watching For Changes](#watching-for-changes)
|
|
37
|
+
- [Local Server](#local-server)
|
|
34
38
|
- [Examples](#examples)
|
|
35
39
|
- [Benchmark](#benchmark)
|
|
36
40
|
- [Testing](#testing)
|
|
@@ -76,6 +80,19 @@ $ npm install onlybuild --save-dev
|
|
|
76
80
|
$ npm run build
|
|
77
81
|
```
|
|
78
82
|
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
Usage: onlybuild <path> [options]
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
|
|
90
|
+
-h, --help Display this help message.
|
|
91
|
+
-v, --version Display the current installed version.
|
|
92
|
+
-o, --out Sets build directory. Default path is build/
|
|
93
|
+
-i, --ignore Sets ignore file path. Default path is .onlyignore
|
|
94
|
+
```
|
|
95
|
+
|
|
79
96
|
## Quick Start Guide
|
|
80
97
|
|
|
81
98
|
Create a new file `index.mjs` with the following contents:
|
|
@@ -142,6 +159,31 @@ import { marked } from 'marked';
|
|
|
142
159
|
export default marked.parse(await readFile('index.md', 'utf8'));
|
|
143
160
|
```
|
|
144
161
|
|
|
162
|
+
### Parse Markdown w/ Syntax Highlighting
|
|
163
|
+
|
|
164
|
+
This Markdown example parses code blocks and adds CSS classes before rendering the page to HTML.
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
import { readFile } from 'node:fs/promises';
|
|
168
|
+
|
|
169
|
+
import { Marked } from 'marked';
|
|
170
|
+
|
|
171
|
+
import { markedHighlight } from 'marked-highlight';
|
|
172
|
+
import hljs from 'highlight.js';
|
|
173
|
+
|
|
174
|
+
const marked = new Marked(
|
|
175
|
+
markedHighlight({
|
|
176
|
+
langPrefix: 'hljs language-',
|
|
177
|
+
highlight(code, lang, info) {
|
|
178
|
+
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
|
|
179
|
+
return hljs.highlight(code, { language }).value;
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
export default marked.parse(await readFile('index.md', 'utf8'));
|
|
185
|
+
```
|
|
186
|
+
|
|
145
187
|
### <code>`html`</code> String Template Utility
|
|
146
188
|
|
|
147
189
|
The `onlybuild` library includes an optional <code>`html`</code> string template utility that can be used to add syntax highlighting and formatting to HTML, making it easier to author HTML in JavaScript.
|
|
@@ -156,14 +198,62 @@ Install the [lit-html](https://marketplace.visualstudio.com/items?itemName=biern
|
|
|
156
198
|
|
|
157
199
|
## File Structure
|
|
158
200
|
|
|
159
|
-
When you run `npx onlybuild`
|
|
201
|
+
When you run `npx onlybuild`, all `.mjs` files with a `export default` that returns a string will be captured and written to the `build/` directory. All other files will be copied with the same file structure to the `build` directory unless included in the `.onlyignore` file or in a default ignored directory, indicated by a leading `_` character.
|
|
160
202
|
|
|
161
203
|
If the name of your `.mjs` file is `index.mjs` the output will be saved to `index.html`, but if it's name is `something-else.mjs` the output will be saved to `something-else/index.mjs`.
|
|
162
204
|
|
|
205
|
+
See the example file structure below for a more comprehensive example that includes building files and copying static files.
|
|
206
|
+
|
|
207
|
+
<table>
|
|
208
|
+
<tr>
|
|
209
|
+
<th>
|
|
210
|
+
Files
|
|
211
|
+
</v>
|
|
212
|
+
<th>
|
|
213
|
+
Build Output
|
|
214
|
+
</th>
|
|
215
|
+
<tr>
|
|
216
|
+
<td>
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
├── _includes
|
|
220
|
+
│ └── head.mjs
|
|
221
|
+
├── about
|
|
222
|
+
│ └── index.mjs
|
|
223
|
+
├── blog
|
|
224
|
+
│ └── hello-world.mjs
|
|
225
|
+
├── css
|
|
226
|
+
│ └── styles.css
|
|
227
|
+
├── images
|
|
228
|
+
│ └── icon.png
|
|
229
|
+
└── index.mjs
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
</td>
|
|
233
|
+
<td>
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
├── index.html
|
|
237
|
+
├── css
|
|
238
|
+
│ └── styles.css
|
|
239
|
+
├── images
|
|
240
|
+
│ └── icon.png
|
|
241
|
+
├── about
|
|
242
|
+
│ └── index.html
|
|
243
|
+
└── blog
|
|
244
|
+
└── hello-world
|
|
245
|
+
└── index.html
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
</td></tr></table>
|
|
250
|
+
|
|
163
251
|
## Ignore Files
|
|
164
252
|
|
|
165
253
|
If you want to ignore files from being generated into static files or copied into the `build.` directory you can add them to an ignore file called `.onlyignore`, which has a syntax similar to [`.gitignore`](https://git-scm.com/docs/gitignore) files.
|
|
166
254
|
|
|
255
|
+
As stated in the previous section, any files in a directory with a leading `_` character will be automatically ignored. Example: `_includes` or `_data`.
|
|
256
|
+
|
|
167
257
|
```
|
|
168
258
|
*.md
|
|
169
259
|
|
|
@@ -174,16 +264,60 @@ LICENSE
|
|
|
174
264
|
|
|
175
265
|
## Formatting Files
|
|
176
266
|
|
|
177
|
-
|
|
267
|
+
If you want to reformat the HTML files in the build directory, you can use [Prettier](https://prettier.io/) after the build completes.
|
|
178
268
|
|
|
179
|
-
```
|
|
180
|
-
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
...
|
|
272
|
+
"scripts": {
|
|
273
|
+
"build": "onlybuild",
|
|
274
|
+
"format": "npx prettier --write \"build/**/*.html\""
|
|
275
|
+
},
|
|
276
|
+
...
|
|
277
|
+
}
|
|
181
278
|
```
|
|
182
279
|
|
|
183
280
|
If your `build/` directory is in `.gitignore` (which it probably should be) you will need to ignore the `.gitignore` file by setting the `--ignore-path` flag to something else. The file you set it to doesn't need to exist.
|
|
184
281
|
|
|
185
|
-
```
|
|
186
|
-
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
...
|
|
285
|
+
"scripts": {
|
|
286
|
+
"build": "onlybuild",
|
|
287
|
+
"format": "npx prettier --write --ignore-path .prettierignore \"build/**/*.html\""
|
|
288
|
+
},
|
|
289
|
+
...
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Watching For Changes
|
|
294
|
+
|
|
295
|
+
If you want to automatically rebuild the project when files are updated you can use [nodemon](https://nodemon.io/).
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
...
|
|
300
|
+
"scripts": {
|
|
301
|
+
"build": "onlybuild",
|
|
302
|
+
"watch": "npx nodemon --ext mjs,md,css --ignore ./build -x \"npm run build\""
|
|
303
|
+
},
|
|
304
|
+
...
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Local Server
|
|
309
|
+
|
|
310
|
+
Serving the files once the build is complete is easy using the NPM package [http-server](https://github.com/http-party/http-server).
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
...
|
|
315
|
+
"scripts": {
|
|
316
|
+
"build": "onlybuild",
|
|
317
|
+
"serve": "npx http-server build"
|
|
318
|
+
},
|
|
319
|
+
...
|
|
320
|
+
}
|
|
187
321
|
```
|
|
188
322
|
|
|
189
323
|
## Examples
|
package/bin/index.js
CHANGED
|
@@ -1,16 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
3
7
|
import { globby } from 'globby';
|
|
4
8
|
|
|
9
|
+
import parseCmdArgs from 'parse-cmd-args';
|
|
10
|
+
|
|
5
11
|
import { buildFiles } from '../src/build.js';
|
|
6
12
|
import { copyFiles } from '../src/copy.js';
|
|
7
13
|
|
|
14
|
+
const args = parseCmdArgs(null, {
|
|
15
|
+
requireUserInput: false
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (args.flags['--version'] || args.flags['-v']) {
|
|
19
|
+
process.stdout.write(
|
|
20
|
+
`${
|
|
21
|
+
JSON.parse(
|
|
22
|
+
await readFile(
|
|
23
|
+
join(dirname(fileURLToPath(import.meta.url)), '../package.json'),
|
|
24
|
+
'utf8'
|
|
25
|
+
)
|
|
26
|
+
).version
|
|
27
|
+
}\n`
|
|
28
|
+
);
|
|
29
|
+
process.exit();
|
|
30
|
+
} else if (args.flags['--help'] || args.flags['-h']) {
|
|
31
|
+
process.stdout.write(`Usage: onlybuild <path> [options]
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
|
|
35
|
+
-h, --help Display this help message.
|
|
36
|
+
-v, --version Display the current installed version.
|
|
37
|
+
-o, --out Sets build directory. Default path is build/
|
|
38
|
+
-i, --ignore Sets ignore file path. Default path is .onlyignore
|
|
39
|
+
`);
|
|
40
|
+
process.exit();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const [buildDir = 'build/'] = [args.flags['--out'], args.flags['-o']]
|
|
44
|
+
.filter(flag => typeof flag === 'string')
|
|
45
|
+
.map(String);
|
|
46
|
+
|
|
47
|
+
const [ignoreFile = '.onlyignore'] = [args.flags['--ignore'], args.flags['-i']]
|
|
48
|
+
.filter(flag => typeof flag === 'string')
|
|
49
|
+
.map(String);
|
|
50
|
+
|
|
8
51
|
await buildFiles(
|
|
9
|
-
await globby(['**/*.mjs', '!_*/**/*', '!node_modules/',
|
|
52
|
+
await globby(['**/*.mjs', '!_*/**/*', '!node_modules/', `!${buildDir}`], {
|
|
10
53
|
gitignore: true,
|
|
11
|
-
ignoreFiles: [
|
|
54
|
+
ignoreFiles: [ignoreFile],
|
|
55
|
+
cwd: args.inputs[0]
|
|
12
56
|
}),
|
|
13
|
-
|
|
57
|
+
buildDir
|
|
14
58
|
);
|
|
15
59
|
|
|
16
60
|
await copyFiles(
|
|
@@ -22,14 +66,15 @@ await copyFiles(
|
|
|
22
66
|
'!package.json',
|
|
23
67
|
'!package-lock.json',
|
|
24
68
|
'!node_modules/',
|
|
25
|
-
|
|
69
|
+
`!${buildDir}`
|
|
26
70
|
],
|
|
27
71
|
{
|
|
28
72
|
gitignore: true,
|
|
29
|
-
ignoreFiles: [
|
|
73
|
+
ignoreFiles: [ignoreFile],
|
|
74
|
+
cwd: args.inputs[0]
|
|
30
75
|
}
|
|
31
76
|
),
|
|
32
|
-
|
|
77
|
+
buildDir
|
|
33
78
|
);
|
|
34
79
|
|
|
35
80
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onlybuild",
|
|
3
3
|
"description": "A zero-config cli for building static websites.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.x"
|
|
7
7
|
},
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"main": "./src/index.js",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"globby": "14.0.1"
|
|
15
|
+
"globby": "14.0.1",
|
|
16
|
+
"parse-cmd-args": "5.0.1"
|
|
16
17
|
},
|
|
17
18
|
"scripts": {
|
|
18
19
|
"test": "node --test"
|
package/src/build.js
CHANGED
|
@@ -2,26 +2,45 @@ import { writeFile, mkdir } from 'node:fs/promises';
|
|
|
2
2
|
import { basename, dirname, join, resolve } from 'node:path';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Write the file to the build directory while creating the directory, recursively, if it doesn't exist.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} path
|
|
6
8
|
* @param {string} buildDir
|
|
9
|
+
* @param {string} contents
|
|
7
10
|
*/
|
|
8
|
-
export const
|
|
9
|
-
|
|
10
|
-
paths.map(async path => {
|
|
11
|
-
const filename = basename(path, '.mjs');
|
|
11
|
+
export const writeFileAndMakeDir = async (path, buildDir, contents) => {
|
|
12
|
+
const filename = basename(path, '.mjs');
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const directory =
|
|
15
|
+
filename === 'index'
|
|
16
|
+
? join(buildDir, dirname(path))
|
|
17
|
+
: join(buildDir, dirname(path), filename);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
await mkdir(directory, { recursive: true });
|
|
20
|
+
|
|
21
|
+
await writeFile(join(directory, 'index.html'), contents);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Import the default export of a JavaScript file and check that the default export is a string before writing the contents to a build file.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} path
|
|
28
|
+
* @param {string} buildDir
|
|
29
|
+
*/
|
|
30
|
+
export const buildFile = async (path, buildDir) => {
|
|
31
|
+
const contents = (await import(resolve(path))).default;
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
if (typeof contents === 'string') {
|
|
34
|
+
await writeFileAndMakeDir(path, buildDir, contents);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
22
37
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Iterate over all the file paths and write them to the build directory.
|
|
40
|
+
*
|
|
41
|
+
* @param {string[]} paths
|
|
42
|
+
* @param {string} buildDir
|
|
43
|
+
*/
|
|
44
|
+
export const buildFiles = async (paths, buildDir) => {
|
|
45
|
+
await Promise.all(paths.map(async path => await buildFile(path, buildDir)));
|
|
27
46
|
};
|
package/src/copy.js
CHANGED
|
@@ -2,15 +2,25 @@ import { copyFile, mkdir } from 'node:fs/promises';
|
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
+
* Copy the file to the build directory while creating the directory, recursively, if it doesn't exist.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} path
|
|
8
|
+
* @param {string} buildDir
|
|
9
|
+
*/
|
|
10
|
+
export const copyFileAndMakeDir = async (path, buildDir) => {
|
|
11
|
+
await mkdir(join(buildDir, dirname(path)), { recursive: true });
|
|
12
|
+
|
|
13
|
+
await copyFile(path, join(buildDir, path));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Iterate over all the file paths and copy them to the build directory.
|
|
18
|
+
*
|
|
5
19
|
* @param {string[]} paths
|
|
6
20
|
* @param {string} buildDir
|
|
7
21
|
*/
|
|
8
22
|
export const copyFiles = async (paths, buildDir) => {
|
|
9
23
|
await Promise.all(
|
|
10
|
-
paths.map(async path =>
|
|
11
|
-
await mkdir(join(buildDir, dirname(path)), { recursive: true });
|
|
12
|
-
|
|
13
|
-
await copyFile(path, join(buildDir, path));
|
|
14
|
-
})
|
|
24
|
+
paths.map(async path => await copyFileAndMakeDir(path, buildDir))
|
|
15
25
|
);
|
|
16
26
|
};
|