poops 1.0.19 → 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/README.md +246 -104
- package/lib/copy.js +119 -0
- package/lib/markups.js +258 -162
- package/lib/scripts.js +9 -11
- package/lib/ssg.js +158 -0
- package/lib/styles.js +10 -76
- package/lib/utils/helpers.js +157 -47
- package/lib/utils/print-style.js +1 -1
- package/package.json +23 -10
- package/poops.js +102 -76
- package/.eslintrc.yml +0 -10
- package/.github/dependabot.yml +0 -9
- package/.nojekyll +0 -1
- package/changelog/blog-functionality.html +0 -58
- package/changelog/feed.rss +0 -31
- package/changelog/front-matter.html +0 -61
- package/changelog/index.html +0 -74
- package/changelog/markdown-support.html +0 -56
- package/example/dist/css/styles.css +0 -9475
- package/example/dist/css/styles.css.map +0 -1
- package/example/dist/css/styles.min.css +0 -2
- package/example/dist/js/scripts.js +0 -35
- package/example/dist/js/scripts.js.map +0 -7
- package/example/dist/js/scripts.min.js +0 -2
- package/example/src/js/main.ts +0 -28
- package/example/src/js/scripts/utils.ts +0 -16
- package/example/src/markup/_data/features.yaml +0 -9
- package/example/src/markup/_data/links.json +0 -10
- package/example/src/markup/_data/poops.yaml +0 -7
- package/example/src/markup/_layouts/blog.html +0 -35
- package/example/src/markup/_layouts/default.html +0 -93
- package/example/src/markup/_partials/heading.html +0 -10
- package/example/src/markup/_partials/site-header.html +0 -17
- package/example/src/markup/changelog/blog-functionality.md +0 -10
- package/example/src/markup/changelog/feed.rss +0 -23
- package/example/src/markup/changelog/front-matter.md +0 -12
- package/example/src/markup/changelog/index.html +0 -30
- package/example/src/markup/changelog/markdown-support.md +0 -7
- package/example/src/markup/index.html +0 -33
- package/example/src/scss/_config.scss +0 -22
- package/example/src/scss/index.scss +0 -4
- package/example/src/scss/style/index.scss +0 -13
- package/example/src/scss/style/test.css +0 -3
- package/index.html +0 -166
- package/poop.png +0 -0
- package/poops.json +0 -55
- package/script/build +0 -3
- package/script/publish +0 -138
- package/script/server +0 -3
- package/test.html +0 -96
- package/tsconfig.json +0 -16
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# 💩 Poops [](https://www.npmjs.com/package/poops)
|
|
2
|
+
|
|
2
3
|
Straightforward, no-bullshit bundler for the web.
|
|
3
4
|
|
|
4
5
|
> When your day is long
|
|
@@ -17,7 +18,7 @@ Straightforward, no-bullshit bundler for the web.
|
|
|
17
18
|
|
|
18
19
|
[R.E.M. - Everybody Poops :poop:](https://www.youtube.com/watch?v=5rOiW_xY-kc)
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
---
|
|
21
22
|
|
|
22
23
|
Intuitive with a minimal learning curve and minimal docs, utilizing the most efficient transpilers and compilers available (like [dart-sass](https://sass-lang.com/dart-sass) and [esbuild](https://esbuild.github.io/)) Poops aims to be the simplest bundler option there is. If it's not, please do contribute so we can make it so! 🙏 All ideas and contributions are welcome.
|
|
23
24
|
|
|
@@ -25,20 +26,20 @@ It uses a simple config file where you define your input and output paths and it
|
|
|
25
26
|
|
|
26
27
|
## Features
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
- Bundles SCSS/SASS to CSS
|
|
30
|
+
- Uses [dart-sass](https://sass-lang.com/dart-sass) for SCSS/SASS bundling
|
|
31
|
+
- Bundles JS/TS/JSX/TSX to IIFE/ESM/CJS
|
|
32
|
+
- Uses [esbuild](https://esbuild.github.io/) for bundling and transpiling JS/TS/JSX/TSX to IIFE/ESM/CJS
|
|
33
|
+
- Optional JS and CSS minification using [esbuild](https://esbuild.github.io/)
|
|
34
|
+
- Can produce minified code simultaneously with non-minified code! (cause I always forget to minify my code for production)
|
|
35
|
+
- Supports source maps only for non minified - non production code (optional)
|
|
36
|
+
- Supports multiple input and output paths
|
|
37
|
+
- Resolves node modules
|
|
38
|
+
- Can add a templatable banner to output files (optional)
|
|
39
|
+
- Static site generation with [nunjucks](https://mozilla.github.io/nunjucks/) templating, with blogging option (optional)
|
|
40
|
+
- Has a configurable local server (optional)
|
|
41
|
+
- Rebuilds on file changes (optional)
|
|
42
|
+
- Live reloads on file changes (optional)
|
|
42
43
|
|
|
43
44
|
## Quick Start
|
|
44
45
|
|
|
@@ -82,26 +83,30 @@ Just create a `poops.json` file in the root of your project and add the followin
|
|
|
82
83
|
|
|
83
84
|
```json
|
|
84
85
|
{
|
|
85
|
-
"scripts": [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
"scripts": [
|
|
87
|
+
{
|
|
88
|
+
"in": "example/src/js/main.ts",
|
|
89
|
+
"out": "example/dist/js/scripts.js",
|
|
90
|
+
"options": {
|
|
91
|
+
"sourcemap": true,
|
|
92
|
+
"minify": true,
|
|
93
|
+
"justMinified": false,
|
|
94
|
+
"format": "iife",
|
|
95
|
+
"target": "es2019"
|
|
96
|
+
}
|
|
94
97
|
}
|
|
95
|
-
|
|
96
|
-
"styles": [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
],
|
|
99
|
+
"styles": [
|
|
100
|
+
{
|
|
101
|
+
"in": "example/src/scss/index.scss",
|
|
102
|
+
"out": "example/dist/css/styles.css",
|
|
103
|
+
"options": {
|
|
104
|
+
"sourcemap": true,
|
|
105
|
+
"minify": true,
|
|
106
|
+
"justMinified": false
|
|
107
|
+
}
|
|
103
108
|
}
|
|
104
|
-
|
|
109
|
+
],
|
|
105
110
|
"markup": {
|
|
106
111
|
"in": "example/src/markup",
|
|
107
112
|
"out": "/",
|
|
@@ -120,18 +125,20 @@ Just create a `poops.json` file in the root of your project and add the followin
|
|
|
120
125
|
]
|
|
121
126
|
}
|
|
122
127
|
},
|
|
128
|
+
"copy": [
|
|
129
|
+
{
|
|
130
|
+
"in": "example/src/static",
|
|
131
|
+
"out": "example/dist"
|
|
132
|
+
}
|
|
133
|
+
],
|
|
123
134
|
"banner": "/* {{ name }} v{{ version }} | {{ homepage }} | {{ license }} License */",
|
|
124
|
-
"serve"
|
|
135
|
+
"serve": {
|
|
125
136
|
"port": 4040,
|
|
126
137
|
"base": "/"
|
|
127
138
|
},
|
|
128
139
|
"livereload": true,
|
|
129
|
-
"watch": [
|
|
130
|
-
|
|
131
|
-
],
|
|
132
|
-
"includePaths": [
|
|
133
|
-
"node_modules"
|
|
134
|
-
]
|
|
140
|
+
"watch": ["src"],
|
|
141
|
+
"includePaths": ["node_modules"]
|
|
135
142
|
}
|
|
136
143
|
```
|
|
137
144
|
|
|
@@ -141,19 +148,20 @@ You can freely remove the properties that you don't need. For example, if you do
|
|
|
141
148
|
|
|
142
149
|
### Scripts
|
|
143
150
|
|
|
144
|
-
Scripts are bundled with [esbuild](https://esbuild.github.io/). You can specify multiple scripts to bundle. Each script has the following properties:
|
|
151
|
+
Scripts are bundled with [esbuild](https://esbuild.github.io/). Supports `.js`, `.ts`, `.jsx`, and `.tsx` files out of the box — including React and other JSX frameworks. You can specify multiple scripts to bundle. Each script has the following properties:
|
|
145
152
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
153
|
+
- `in` - the input path, can be an array of file paths, but please just use one file path per script
|
|
154
|
+
- `out` - the output path, can be a directory or a file path, but please just use it as a filename
|
|
155
|
+
- `options` - the options for the bundler. You can apply most of the esbuild options that are not in conflict with Poops. See [esbuild's options](https://esbuild.github.io/api/#build-api) for more info.
|
|
149
156
|
|
|
150
157
|
**Options:**
|
|
151
|
-
* `sourcemap` - whether to generate sourcemaps or not, sourcemaps are generated only for non-minified files since they are useful for debugging. Default is `false`. This is a direct esbuild option
|
|
152
|
-
* `minify` - whether to minify the output or not, minification is performed by `esbuild` and is only applied to non-minified files. Default is `false`
|
|
153
|
-
* `justMinified` - whether you want to have a minified file as output only. Removes the non-minified file from the output. Useful for production builds. Default is `false`
|
|
154
|
-
* `format` - the output format, can be `iife` or `esm` or `cjs` - this is a direct esbuild option
|
|
155
|
-
* `target` - the target for the output, can be `es2018` or `es2019` or `es2020` or `esnext` for instance - this is a direct esbuild option
|
|
156
158
|
|
|
159
|
+
- `sourcemap` - whether to generate sourcemaps or not, sourcemaps are generated only for non-minified files since they are useful for debugging. Default is `false`. This is a direct esbuild option
|
|
160
|
+
- `minify` - whether to minify the output or not, minification is performed by `esbuild` and is only applied to non-minified files. Default is `false`
|
|
161
|
+
- `justMinified` - whether you want to have a minified file as output only. Removes the non-minified file from the output. Useful for production builds. Default is `false`
|
|
162
|
+
- `format` - the output format, can be `iife` or `esm` or `cjs` - this is a direct esbuild option
|
|
163
|
+
- `target` - the target for the output, can be `es2018` or `es2019` or `es2020` or `esnext` for instance - this is a direct esbuild option
|
|
164
|
+
- `jsx` - the JSX transform mode, can be `transform` (default) or `automatic`. Use `automatic` for React 17+ JSX runtime which doesn't require importing React in every file - this is a direct esbuild option
|
|
157
165
|
|
|
158
166
|
`scripts` property can accept an array of script configurations or just a single script configuration. If you want to bundle multiple scripts, just add them to the `scripts` array:
|
|
159
167
|
|
|
@@ -186,20 +194,90 @@ Scripts are bundled with [esbuild](https://esbuild.github.io/). You can specify
|
|
|
186
194
|
}
|
|
187
195
|
```
|
|
188
196
|
|
|
197
|
+
#### JSX/TSX (React) Example
|
|
198
|
+
|
|
199
|
+
To bundle a React app, just point `in` to your `.jsx` or `.tsx` entry file:
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"scripts": [
|
|
204
|
+
{
|
|
205
|
+
"in": "src/js/app.jsx",
|
|
206
|
+
"out": "dist/js/app.js",
|
|
207
|
+
"options": {
|
|
208
|
+
"minify": true,
|
|
209
|
+
"format": "iife",
|
|
210
|
+
"jsx": "automatic"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Setting `jsx` to `automatic` uses React's JSX runtime (React 17+), so you don't need `import React from 'react'` in every file. If you omit `jsx` or set it to `transform`, the classic `React.createElement` transform is used.
|
|
218
|
+
|
|
189
219
|
As noted earlier, if you don't want to bundle scripts, just remove the `scripts` property from the config.
|
|
190
220
|
|
|
221
|
+
### React SSG (Static Site Generation)
|
|
222
|
+
|
|
223
|
+
SSG renders React components to HTML at build time, then hydrates them on the client. This means pages load with pre-rendered content instead of an empty `<div>`.
|
|
224
|
+
|
|
225
|
+
Each SSG entry has the following properties:
|
|
226
|
+
|
|
227
|
+
- `component` — the file that default-exports a React component (rendered server-side)
|
|
228
|
+
- `in` — the client entry file for hydration (bundled for browser)
|
|
229
|
+
- `out` — output path for the client bundle
|
|
230
|
+
- `inject` — Nunjucks variable name for the rendered HTML
|
|
231
|
+
- `options` — esbuild options (applied to the client bundle, same as `scripts` options)
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"ssg": [
|
|
236
|
+
{
|
|
237
|
+
"component": "src/js/App.jsx",
|
|
238
|
+
"in": "src/js/app-hydrate.jsx",
|
|
239
|
+
"out": "dist/js/app-hydrate.js",
|
|
240
|
+
"inject": "app_html",
|
|
241
|
+
"options": {
|
|
242
|
+
"minify": true,
|
|
243
|
+
"target": "es2019"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
In your Nunjucks templates, use the `inject` name to insert the rendered HTML:
|
|
251
|
+
|
|
252
|
+
```html
|
|
253
|
+
<div id="root">{{ app_html | safe }}</div>
|
|
254
|
+
<script src="js/app-hydrate.min.js"></script>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**How it works:**
|
|
258
|
+
|
|
259
|
+
1. Poops bundles the component with `react-dom/server` for Node.js and calls `renderToString`
|
|
260
|
+
2. The rendered HTML is stored and made available as a Nunjucks global variable
|
|
261
|
+
3. The client entry is bundled for the browser (same as a regular `scripts` entry)
|
|
262
|
+
4. At runtime, React hydrates the pre-rendered HTML, making it interactive
|
|
263
|
+
|
|
264
|
+
SSG runs after Styles but before Scripts and Markups in the build pipeline. Poops does not need `react` or `react-dom` as its own dependency — they are resolved from your project's `node_modules`.
|
|
265
|
+
|
|
266
|
+
In watch mode, changes to JSX/TSX files trigger SSG re-rendering followed by a markup recompile.
|
|
267
|
+
|
|
191
268
|
### Styles
|
|
192
269
|
|
|
193
270
|
Styles are bundled with [Dart Sass](https://sass-lang.com/dart-sass). You can specify multiple styles to bundle. Each style has the following properties:
|
|
194
271
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
272
|
+
- `in` - the input path, accepts only a path to a file
|
|
273
|
+
- `out` - the output path, can be a directory or a file path, but please just use it as a filename
|
|
274
|
+
- `options` - the options for the bundler.
|
|
198
275
|
|
|
199
276
|
**Options:**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
277
|
+
|
|
278
|
+
- `sourcemap` - whether to generate sourcemaps or not, sourcemaps are generated only for non-minified files since they are useful for debugging. Default is `false`
|
|
279
|
+
- `minify` - whether to minify the output or not, minification is performed by `esbuild`. Default is `false`
|
|
280
|
+
- `justMinified` - whether you want to have a minified file as output only. Removes the non-minified file from the output. Useful for production builds. Defaults to `false`.
|
|
203
281
|
|
|
204
282
|
`styles` property can accept an array of style configurations or just a single style configuration. If you want to bundle multiple styles, just add them to the `styles` array:
|
|
205
283
|
|
|
@@ -232,16 +310,15 @@ As noted earlier, if you don't want to bundle styles, just remove the `styles` p
|
|
|
232
310
|
|
|
233
311
|
### Markups 🚧
|
|
234
312
|
|
|
235
|
-
Poops can generate static pages for you. This feature is still under development, but available for testing from the
|
|
313
|
+
Poops can generate static pages for you. This feature is still under development, but available for testing from the v1.0.2. Your markup is templated with [nunjucks](https://mozilla.github.io/nunjucks/). You can specify multiple markup directories to template. **It's currently recommended to specify only one markup directory since this feature is still WIP 🚧.** Each markup directory has the following properties:
|
|
236
314
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
**💡 NOTE:** If, for instance, you are building a simple static onepager for your library, and want to pass a version variable from your `package.json`, Poops automatically reads your `package.json` if it exists in your working directory and sets the golobal variable `package` to the parsed JSON. So you can use it in your markup files, for example like this: `{{ package.version }}`.
|
|
315
|
+
- `in` - the input path, can be a directory or a file path, but please just use it as a directory path for now. All files in this directory will be processed and the structure of the directory will be preserved in the output directory with exception to directories that begin with an underscore `_` will be ignored.
|
|
316
|
+
- `out` - the output path, can be only a directory path (for now)
|
|
317
|
+
- `site` (optional) - global data that will be available to all templates in the markup directory. Like site title, description, social media links, etc. You can then use this data in your templates `{{ site.title }}` for instance.
|
|
318
|
+
- `data` (optional) - is an array of JSON or YAML data files, that once loaded will be available to all templates in the markup directory. If you provide a path to a file for instance `links.json` with a `facebook` property, you can then use this data in your templates `{{ links.facebook }}`. The base name of the file will be used as the variable name, with spaces, dashes and dots replaced with underscores. So `the awesome-links.json` will be available as `{{ the_awesome_links.facebook }}` in your templates. The root directory of the data files is `in` directory. So if you have a `data` directory in your `in` directory, you can specify the data files like this `data: ["data/links.json"]`. The same goes for the YAML files.
|
|
319
|
+
- `includePaths` - an array of paths to directories that will be added to the nunjucks include paths. Useful if you want to separate template partials and layouts. For instance, if you have a `_includes` directory with a `header.njk` partial that you want to include in your markup, you can add it to the include paths and then include the templates like this `{% include "header.njk" %}`, without specifying the full path to the partial. This will change in the future, to provide better ignore and include patterns for the markup directories.
|
|
244
320
|
|
|
321
|
+
**💡 NOTE:** If, for instance, you are building a simple static onepager for your library, and want to pass a version variable from your `package.json`, Poops automatically reads your `package.json` if it exists in your working directory and sets the global variable `package` to the parsed JSON. So you can use it in your markup files, for example like this: `{{ package.version }}`.
|
|
245
322
|
|
|
246
323
|
Here is a sample markup configuration:
|
|
247
324
|
|
|
@@ -271,20 +348,84 @@ If your project doesn't have markups, you can remove the `markups` property from
|
|
|
271
348
|
|
|
272
349
|
#### Custom Filters
|
|
273
350
|
|
|
274
|
-
|
|
351
|
+
- `slugify` - slugifies a string. Usage: `{{ "My Awesome Title" | slugify }}` will output `my-awesome-title`
|
|
352
|
+
|
|
353
|
+
### Copy
|
|
354
|
+
|
|
355
|
+
Configuration entry to copy files or directories - copy your static files like images and fonts, for instance, from `src` to `dist` directory. This feature was added to enable moving static files if you deploy GitHub pages via a GitHub action. If you don't want to use this feature, simply exclude the `copy` property from your config file.
|
|
356
|
+
|
|
357
|
+
Here is a sample copy configuration which will copy the `static` directory and it's contents to the `dist` directory:
|
|
358
|
+
|
|
359
|
+
```JSON
|
|
360
|
+
{
|
|
361
|
+
"copy": {
|
|
362
|
+
"in": "src/static",
|
|
363
|
+
"out": "dist"
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
You can specify a list of input paths and pass them to an output directory, for instance:
|
|
369
|
+
|
|
370
|
+
```JSON
|
|
371
|
+
{
|
|
372
|
+
"copy": {
|
|
373
|
+
"in": ["src/static/ogimage.jpg", "src/static/favicon.ico", "src/fonts"],
|
|
374
|
+
"out": "dist"
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**💡 NOTE:** Copy property can also accept the list of objects containing `in` and `out` properties. For instance:
|
|
380
|
+
|
|
381
|
+
```JSON
|
|
382
|
+
{
|
|
383
|
+
"copy": [
|
|
384
|
+
{
|
|
385
|
+
"in": ["src/static/ogimage.jpg", "src/static/favicon.ico", "src/fonts"],
|
|
386
|
+
"out": "dist"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"in": "images",
|
|
390
|
+
"out": "dist/static"
|
|
391
|
+
}
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**💡 NOTE:** Copy can also accept **GLOB** and **EXTGLOB** patterns as input paths, except POSIX character classes (e.g. `[[:alpha:]]`):
|
|
397
|
+
|
|
398
|
+
```JSON
|
|
399
|
+
{
|
|
400
|
+
"copy": {
|
|
401
|
+
"in": [
|
|
402
|
+
"images/**/awesome.{jpeg,jpg,png}",
|
|
403
|
+
"notes/info[0-9].txt",
|
|
404
|
+
"notes/doc?.txt",
|
|
405
|
+
"notes/memo*.txt",
|
|
406
|
+
"notes/log[!123a].txt",
|
|
407
|
+
"assets/!(vendor)/*.js",
|
|
408
|
+
"fonts/@(woff|woff2)/*.+(woff|woff2)",
|
|
409
|
+
"docs/?(intro|overview).md"
|
|
410
|
+
],
|
|
411
|
+
"out": "dist"
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
275
415
|
|
|
276
416
|
### Banner (optional)
|
|
277
417
|
|
|
278
418
|
Here you can specify a banner that will be added to the top of the output files. It is templatable via mustache. The following variables are available from your project's `package.json`:
|
|
279
419
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
420
|
+
- `name`
|
|
421
|
+
- `version`
|
|
422
|
+
- `homepage`
|
|
423
|
+
- `license`
|
|
424
|
+
- `author`
|
|
425
|
+
- `description`
|
|
286
426
|
|
|
287
427
|
Here is a sample banner template.
|
|
428
|
+
|
|
288
429
|
```
|
|
289
430
|
/* {{ name }} v{{ version }} | {{ homepage }} | {{ license }} License */
|
|
290
431
|
```
|
|
@@ -294,20 +435,24 @@ You can always pass just a string, you don't have to template it.
|
|
|
294
435
|
If you don't want to add a banner, just remove the `banner` property from the config.
|
|
295
436
|
|
|
296
437
|
### Local Server (optional)
|
|
438
|
+
|
|
297
439
|
Sets up a local server for your project.
|
|
298
440
|
|
|
299
441
|
Server options:
|
|
300
|
-
|
|
301
|
-
|
|
442
|
+
|
|
443
|
+
- `port` - the port on which the server will run
|
|
444
|
+
- `base` - the base path of the server, where your HTML files are located
|
|
302
445
|
|
|
303
446
|
If you don't want to run a local server, just remove the `serve` property from the config.
|
|
304
447
|
|
|
305
448
|
### Live Reload (optional)
|
|
449
|
+
|
|
306
450
|
Sets up a livereload server for your project.
|
|
307
451
|
|
|
308
452
|
Live reload options:
|
|
309
|
-
|
|
310
|
-
|
|
453
|
+
|
|
454
|
+
- `port` - the port on which the livereload server will run
|
|
455
|
+
- `exclude` - an array of files and directories to exclude from livereload
|
|
311
456
|
|
|
312
457
|
`livereload` can only be `true`, which means that it will run on the default port (`35729`) or you can specify a port:
|
|
313
458
|
|
|
@@ -324,10 +469,7 @@ You can also exclude files and directories from livereload:
|
|
|
324
469
|
```json
|
|
325
470
|
{
|
|
326
471
|
"livereload": {
|
|
327
|
-
"exclude": [
|
|
328
|
-
"some_directory/**/*",
|
|
329
|
-
"some_other_directory/**/*"
|
|
330
|
-
]
|
|
472
|
+
"exclude": ["some_directory/**/*", "some_other_directory/**/*"]
|
|
331
473
|
}
|
|
332
474
|
}
|
|
333
475
|
```
|
|
@@ -335,10 +477,14 @@ You can also exclude files and directories from livereload:
|
|
|
335
477
|
In order for Livereload to work, you need to add the following script snippet to your HTML files in your development environment:
|
|
336
478
|
|
|
337
479
|
```html
|
|
338
|
-
<script>
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
480
|
+
<script>
|
|
481
|
+
document.write(
|
|
482
|
+
'<script src="http://' +
|
|
483
|
+
(location.host || "localhost").split(":")[0] +
|
|
484
|
+
':35729/livereload.js?snipver=1"></' +
|
|
485
|
+
"script>",
|
|
486
|
+
);
|
|
487
|
+
</script>
|
|
342
488
|
```
|
|
343
489
|
|
|
344
490
|
Be mindful of the port, if you have specified a custom port, you need to change the port in the snippet as well.
|
|
@@ -348,56 +494,52 @@ You can also use a browser extension for livereload, for instance here is one fo
|
|
|
348
494
|
If you don't want to run livereload, just remove the `livereload` property from the config, or set it to false.
|
|
349
495
|
|
|
350
496
|
### Watch (optional)
|
|
497
|
+
|
|
351
498
|
Sets up a watcher for your project which will rebuild your files on change.
|
|
352
499
|
|
|
353
500
|
`watch` property accepts an array of paths to watch for changes. If you want to watch for changes in the `src` directory, just add it to the `watch` array:
|
|
354
501
|
|
|
355
502
|
```json
|
|
356
503
|
{
|
|
357
|
-
"watch": [
|
|
358
|
-
"src"
|
|
359
|
-
]
|
|
504
|
+
"watch": ["src"]
|
|
360
505
|
}
|
|
361
506
|
```
|
|
362
507
|
|
|
363
508
|
If you don't want to watch for file changes, just remove the `watch` property from the config.
|
|
364
509
|
|
|
365
510
|
### Include Paths (optional)
|
|
511
|
+
|
|
366
512
|
This property is used to specify paths that you want to resolve your imports from. Like `node_modules`. You don't need to specify the `includePaths`, `node_modules` are included by default. But if you do specify `includePaths`, you need to include `node_modules` as well, since this change will override the default behavior.
|
|
367
513
|
|
|
368
514
|
Same as `watch` property, `includePaths` accepts an array of paths to include. If you want to include `lib` directory for instance, just add it to the `includePaths` array:
|
|
369
515
|
|
|
370
516
|
```json
|
|
371
517
|
{
|
|
372
|
-
"includePaths": [
|
|
373
|
-
"node_modules", "lib"
|
|
374
|
-
]
|
|
518
|
+
"includePaths": ["node_modules", "lib"]
|
|
375
519
|
}
|
|
376
520
|
```
|
|
377
521
|
|
|
378
522
|
## Todo
|
|
379
523
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
* [x] RSS and ATOM generation for collections
|
|
394
|
-
* [ ] Refactor!!!!
|
|
524
|
+
- [ ] Run esbuild for each input path individually if there are multiple input paths
|
|
525
|
+
- [ ] Styles `in` should be able to support array of inputs like we have it on scripts
|
|
526
|
+
- [ ] Build a cli config creation helper tool. If the user doesn't have a config file, we can ask them a few questions and create a config file for them. Create Yeoman generator for poops projects.
|
|
527
|
+
- [x] Add nunjucks static templating
|
|
528
|
+
- [ ] Refactor nunjucks implementation
|
|
529
|
+
- [ ] Complete documentation for nunjucks
|
|
530
|
+
- [x] Add markdown support
|
|
531
|
+
- [x] Front Matter support
|
|
532
|
+
- [x] Future implementation: posts and custom collections, so we can have a real static site generator
|
|
533
|
+
- [x] Collection pagination system
|
|
534
|
+
- [x] Post published toggle
|
|
535
|
+
- [x] RSS and ATOM generation for collections
|
|
536
|
+
- [ ] Support for images and creating srcsets
|
|
395
537
|
|
|
396
538
|
## Why?
|
|
397
539
|
|
|
398
540
|
Why doesn't anyone maintain GULP anymore? Why does Parcel hate config files? Why are Rollup and Webpack so complex to setup for simple tasks? Vite???? What's going on?
|
|
399
541
|
|
|
400
|
-
I'm tired... Tired of bullshit... I just want to bundle my scss/sass and/or my js/ts to css and iife/esm js, by providing input and output paths for both/one. And to be able to have minimal easily maintainable dependencies. I don't need plugins, I'll add the features manually for the practice I use. That's it. The f
|
|
542
|
+
I'm tired... Tired of bullshit... I just want to bundle my scss/sass and/or my js/ts to css and iife/esm js, by providing input and output paths for both/one. And to be able to have minimal easily maintainable dependencies. I don't need plugins, I'll add the features manually for the practice I use. That's it. The f\*\*king end.
|
|
401
543
|
|
|
402
544
|
To better illustrate it, here is a sample diff of Poops replacing Rollup:
|
|
403
545
|
|
package/lib/copy.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { globSync, hasMagic } from 'glob'
|
|
2
|
+
import {
|
|
3
|
+
pathExists,
|
|
4
|
+
pathIsDirectory,
|
|
5
|
+
mkDir,
|
|
6
|
+
copyDirectory,
|
|
7
|
+
buildTime
|
|
8
|
+
} from './utils/helpers.js'
|
|
9
|
+
import fs from 'node:fs'
|
|
10
|
+
import path from 'node:path'
|
|
11
|
+
import PrintStyle from './utils/print-style.js'
|
|
12
|
+
|
|
13
|
+
const pstyle = new PrintStyle()
|
|
14
|
+
|
|
15
|
+
export default class Copy {
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async execute() {
|
|
21
|
+
if (!this.config.copy) return
|
|
22
|
+
const copyStartTime = performance.now()
|
|
23
|
+
this.config.copy = Array.isArray(this.config.copy) ? this.config.copy : [this.config.copy]
|
|
24
|
+
let copyLastPath = ''
|
|
25
|
+
let copyPathCount = 0
|
|
26
|
+
|
|
27
|
+
for (const copyEntry of this.config.copy) {
|
|
28
|
+
if (!copyEntry.in || !copyEntry.out) {
|
|
29
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}[copy] ${pstyle.dim}Cannot copy. Missing 'in' or 'out' property in copy entry:${pstyle.reset} ${JSON.stringify(copyEntry)}`)
|
|
30
|
+
continue
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const outPath = path.resolve(process.cwd(), copyEntry.out)
|
|
34
|
+
const inEntries = Array.isArray(copyEntry.in) ? copyEntry.in : [copyEntry.in]
|
|
35
|
+
|
|
36
|
+
for (const inEntry of inEntries) {
|
|
37
|
+
const hasGlobMagic = typeof hasMagic === 'function'
|
|
38
|
+
? hasMagic(inEntry)
|
|
39
|
+
: ['*', '?', '[', ']', '{', '}', '(', ')', '!'].some((ch) => inEntry.includes(ch))
|
|
40
|
+
let matches = []
|
|
41
|
+
try {
|
|
42
|
+
if (typeof globSync === 'function') {
|
|
43
|
+
matches = globSync(inEntry, { dot: true, nodir: false })
|
|
44
|
+
}
|
|
45
|
+
} catch (err) {
|
|
46
|
+
matches = []
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (matches.length > 0) {
|
|
50
|
+
for (const matchedPath of matches) {
|
|
51
|
+
if (pathExists(matchedPath)) {
|
|
52
|
+
await this.copyEntry(matchedPath, outPath)
|
|
53
|
+
copyLastPath = inEntry
|
|
54
|
+
copyPathCount++
|
|
55
|
+
} else {
|
|
56
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}[copy] ${pstyle.dim}Cannot copy. Source path does not exist:${pstyle.reset} ${matchedPath}`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
continue
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (pathExists(inEntry)) {
|
|
63
|
+
await this.copyEntry(inEntry, outPath)
|
|
64
|
+
copyLastPath = inEntry
|
|
65
|
+
copyPathCount++
|
|
66
|
+
} else {
|
|
67
|
+
if (hasGlobMagic) {
|
|
68
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}[copy] ${pstyle.dim}No files matched glob pattern:${pstyle.reset} ${inEntry}`)
|
|
69
|
+
} else {
|
|
70
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}[copy] ${pstyle.dim}Cannot copy. Source path does not exist:${pstyle.reset} ${inEntry}`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const copyEndTime = performance.now()
|
|
77
|
+
if (copyPathCount === 0) return
|
|
78
|
+
if (copyPathCount === 1) {
|
|
79
|
+
console.log(`${pstyle.green + pstyle.bold}[copy]${pstyle.reset} ${pstyle.dim}Copied${pstyle.reset} ${pstyle.italic + pstyle.underline}${copyLastPath}${pstyle.reset} ${pstyle.green}(${buildTime(copyStartTime, copyEndTime)})${pstyle.reset}`)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.log(`${pstyle.green + pstyle.bold}[copy]${pstyle.reset} ${pstyle.dim}Copied${pstyle.reset} ${copyPathCount} paths ${pstyle.green}(${buildTime(copyStartTime, copyEndTime)})${pstyle.reset}`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async unlink(file, copyPaths) {
|
|
87
|
+
if (!file || !copyPaths) return
|
|
88
|
+
if (!copyPaths.out || !copyPaths.in) return
|
|
89
|
+
if (!pathExists(copyPaths.out) || !pathExists(copyPaths.in)) return
|
|
90
|
+
|
|
91
|
+
if (pathIsDirectory(copyPaths.in)) {
|
|
92
|
+
const inBaseName = path.basename(copyPaths.in)
|
|
93
|
+
copyPaths.out = path.join(copyPaths.out, inBaseName)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
file = file.replace(copyPaths.in, copyPaths.out)
|
|
97
|
+
|
|
98
|
+
const outputFilePath = path.join(process.cwd(), file)
|
|
99
|
+
|
|
100
|
+
if (pathExists(outputFilePath)) {
|
|
101
|
+
if (pathIsDirectory(outputFilePath)) {
|
|
102
|
+
fs.rmSync(outputFilePath, { recursive: true })
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
fs.unlinkSync(outputFilePath)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async copyEntry(inFilePath, outFilePath) {
|
|
110
|
+
const baseName = path.basename(inFilePath)
|
|
111
|
+
let outPath = outFilePath
|
|
112
|
+
mkDir(outFilePath)
|
|
113
|
+
|
|
114
|
+
if (pathIsDirectory(outFilePath)) {
|
|
115
|
+
outPath = path.join(outFilePath, baseName)
|
|
116
|
+
}
|
|
117
|
+
copyDirectory(inFilePath, outPath)
|
|
118
|
+
}
|
|
119
|
+
}
|