Skip to content

Commit 970f732

Browse files
committed
feat: add pipeline for many postrocesses
1 parent 090acad commit 970f732

12 files changed

Lines changed: 203 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Change log
22

3+
## 3.7.0 (2024-03-21)
4+
5+
- feat: add the possibility to add many post processes. Next postprocess receives the result from previous.
6+
So you can extend this plugin with additional default functionality.
7+
```js
8+
class MyPlugin extends HtmlBundlerPlugin {
9+
init(compiler) {
10+
MyPlugin.option.addProcess('postprocess', (content) => {
11+
// TODO: modify the generated HTML content
12+
return content;
13+
});
14+
}
15+
}
16+
17+
module.exports = {
18+
plugins: [
19+
new MyPlugin({
20+
entry: {
21+
index: './src/index.html',
22+
},
23+
}),
24+
],
25+
};
26+
```
27+
This feature is used in the [pug-plugin](https://github.com/webdiscus/pug-plugin) for pretty formatting generated HTML.\
28+
See an example in the [test case](https://github.com/webdiscus/html-bundler-webpack-plugin/tree/master/test/cases/option-postprocess-pipe).
29+
330
## 3.6.5 (2024-03-19)
431

532
- fix: define the unique instance name for the plugin as `HtmlBundlerPlugin` instead of `Plugin`

README.md

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,26 @@ If you have discovered a bug or have a feature suggestion, feel free to create a
230230

231231
For full release notes see the [changelog](https://github.com/webdiscus/html-bundler-webpack-plugin/blob/master/CHANGELOG.md).
232232

233-
> **Warning**\
234-
> **Limitation**
235-
>
236-
> The current version works stable with `cache.type` as `'memory'` (Webpack's default setting).\
237-
> Support for the `'filesystem'` cache type is experimental and under development.
233+
## ⚠️ Limitations
234+
235+
### Cache type
236+
237+
The current version works stable with `cache.type` as `'memory'` (Webpack's default setting).\
238+
Support for the `'filesystem'` cache type is experimental.
239+
240+
### Multiple config files
241+
242+
The multiple config files are not supported, because in some special use cases the Webpack API works not properly (all previous configurations are overridden by the latest configuration).
243+
244+
Instead of this:
245+
```
246+
npx webpack -c app1.config.js app2.config.js
247+
```
248+
you can use following:
249+
```
250+
npx webpack -c app1.config.js
251+
npx webpack -c app2.config.js
252+
```
238253

239254
---
240255

@@ -524,6 +539,7 @@ See [boilerplate](https://github.com/webdiscus/webpack-html-scss-boilerplate)
524539
2. [Problems & Solutions](#solutions)
525540
- [Automatic resolving of file extensions](#solutions-resolve-extensions)
526541
- [How to use `@import url()` in CSS](#solutions-import-url-in-css)
542+
- [How to disable resolving in commented out tag](#solutions-disable-resolving-in-commented-out-tag)
527543
3. <a id="demo-sites" name="demo-sites"></a>
528544
Demo sites
529545
- Multiple page e-shop template (`Handlebars`) [demo](https://alpine-html-bootstrap.vercel.app/) | [source](https://github.com/webdiscus/demo-shop-template-bundler-plugin)
@@ -6021,6 +6037,25 @@ The plugin does not support handling of `@import url()` in CSS. Imported url wil
60216037
>
60226038
> The `*.css` files imported in CSS are not handled, therefore these files must be manually copied to the `dist/` folder using the `copy-webpack-plugin`.
60236039
6040+
#### [↑ back to contents](#contents)
6041+
6042+
<a id="solutions-disable-resolving-in-commented-out-tag" name="solutions-disable-resolving-in-commented-out-tag"></a>
6043+
6044+
## How to disable resolving in commented out tag
6045+
6046+
In [default attributes](#default-attributes), files will be resolved automatically, regardless of whether the tag is commented out or not.
6047+
This is not a bug, it is a feature for very fast attribute parsing.
6048+
6049+
If you commented out a tag and don't want to resolve files in the tag's [attributes](#default-attributes), rename the attribute.
6050+
For example: `href` -> `x-href` or `src` -> `x-src`.
6051+
6052+
```html
6053+
<!-- <link x-href="./styles.css" rel="stylesheet /> -->
6054+
<!-- <script x-src="./main.js" defer="defer"></script> -->
6055+
<!-- <img x-src="./image.png"> -->
6056+
```
6057+
6058+
60246059
#### [↑ back to contents](#contents)
60256060
60266061
---

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "html-bundler-webpack-plugin",
3-
"version": "3.6.5",
3+
"version": "3.7.0",
44
"description": "HTML bundler plugin for webpack handles a template as an entry point, extracts CSS and JS from their sources referenced in HTML, supports template engines like Eta, EJS, Handlebars, Nunjucks.",
55
"keywords": [
66
"html",

src/Plugin/Collection.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,6 @@ class Collection {
10131013
// 9. beforeEmit hook allows plugins to change the html after chunks and inlined assets are injected
10141014
promise = promise.then((content) => hooks.beforeEmit.promise(content, compileEntry) || content);
10151015

1016-
// TODO: add in readme: use callbacks for debugging or small features
10171016
// 10. beforeEmit callback
10181017
if (Option.hasBeforeEmit()) {
10191018
promise = promise.then((content) => Option.beforeEmit(content, compileEntry, compilation) || content);

src/Plugin/Option.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Option {
1515
static cacheable = false;
1616
static context = '';
1717
static testEntry = null;
18+
1819
static js = {
1920
test: /\.(js|ts|jsx|tsx|mjs|cjs|mts|cts)$/,
2021
enabled: true,
@@ -23,6 +24,7 @@ class Option {
2324
outputPath: undefined,
2425
inline: false,
2526
};
27+
2628
static css = {
2729
test: /\.(css|scss|sass|less|styl)$/,
2830
enabled: true,
@@ -32,6 +34,14 @@ class Option {
3234
inline: false,
3335
};
3436

37+
/**
38+
* The pipeline of processes.
39+
* The result of one will be passed into next.
40+
*
41+
* @type {Map<string, Array<Function>>}
42+
*/
43+
static #process = new Map();
44+
3545
/**
3646
* Initialize plugin options.
3747
*
@@ -50,6 +60,9 @@ class Option {
5060

5161
const loaderOptions = this.options.loaderOptions;
5262

63+
// remove cached data from previous webpack running
64+
this.#process.clear();
65+
5366
// add reference for the preprocessor option into the plugin options
5467
if (loaderOptions && loaderOptions.preprocessor != null) {
5568
options.preprocessor = loaderOptions.preprocessor;
@@ -63,6 +76,10 @@ class Option {
6376
if (!isFunction(options.beforeEmit)) this.options.beforeEmit = null;
6477
if (!isFunction(options.afterEmit)) this.options.afterEmit = null;
6578

79+
if (this.options.postprocess != null) {
80+
this.addProcess('postprocess', this.options.postprocess);
81+
}
82+
6683
if (!options.watchFiles) this.options.watchFiles = {};
6784
this.options.hotUpdate = this.options.hotUpdate === true;
6885
}
@@ -437,7 +454,7 @@ class Option {
437454
}
438455

439456
static hasPostprocess() {
440-
return this.options.postprocess != null;
457+
return this.#process.has('postprocess');
441458
}
442459

443460
static hasBeforeEmit() {
@@ -677,6 +694,46 @@ class Option {
677694
}
678695
}
679696

697+
/**
698+
* Add the process to pipeline.
699+
*
700+
* @param {string} name The name of process. Currently supported only `postprocess` pipeline.
701+
* @param {Function} fn The process function.
702+
*/
703+
static addProcess(name, fn) {
704+
let processes = this.#process.get(name);
705+
706+
if (!processes) {
707+
processes = [];
708+
this.#process.set(name, processes);
709+
}
710+
711+
processes.push(fn);
712+
}
713+
714+
/**
715+
* @param {string} name The name of a process.
716+
* @param {Array<*>} args The arguments of a process.
717+
* @return {*|null} The result of passed through all processes.
718+
*/
719+
static #runProcesses(name, args) {
720+
let processPipe = this.#process.get(name);
721+
let i = 0;
722+
let result;
723+
724+
for (; i < processPipe.length; i++) {
725+
const postprocess = processPipe[i];
726+
result = postprocess.apply(null, args);
727+
728+
// the result will be pipelined in the next function as the first argument
729+
if (result != null) {
730+
args[0] = result;
731+
}
732+
}
733+
734+
return result;
735+
}
736+
680737
/**
681738
* Called after js template is compiled into html string.
682739
*
@@ -688,7 +745,7 @@ class Option {
688745
*/
689746
static postprocess(content, info, compilation) {
690747
try {
691-
return this.options.postprocess(content, info, compilation);
748+
return this.#runProcesses('postprocess', [content, info, compilation]);
692749
} catch (error) {
693750
postprocessException(error, info);
694751
}
@@ -697,8 +754,6 @@ class Option {
697754
/**
698755
* Called after processing all plugins, before emit.
699756
*
700-
* TODO: test not yet documented experimental feature
701-
*
702757
* @param {string} content
703758
* @param {CompileEntry} entry
704759
* @param {Compilation} compilation

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class HtmlBundlerPlugin extends AssetCompiler {
4242
* @param {Compiler} compiler The instance of the webpack compilation.
4343
*/
4444
init(compiler) {
45-
// TODO: do some thing in an extended plugin
45+
// do some thing in an extended plugin
4646
}
4747
}
4848

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Test</title>
5+
</head>
6+
<body>
7+
<h1>Hello World!</h1>
8+
<p>The new replaced content.</p>
9+
</body>
10+
</html>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Test</title>
5+
</head>
6+
<body>
7+
<h1>Hello World!</h1>
8+
<p>REPLACE ME FIRST</p>
9+
</body>
10+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('>> main');
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
color: red;
3+
}

0 commit comments

Comments
 (0)