Skip to content

Commit

Permalink
fix: avoid recompiling all entry templates after changes of a non-ent…
Browse files Browse the repository at this point in the history
…ry partial file
  • Loading branch information
webdiscus committed Mar 11, 2024
1 parent 4732af5 commit beb28f7
Show file tree
Hide file tree
Showing 25 changed files with 269 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change log

## 3.6.2 (2024-03-11)

- fix: avoid recompiling all entry templates after changes of a non-entry partial file, [pug-plugin issue](https://github.com/webdiscus/pug-plugin/issues/66)

## 3.6.1 (2024-03-08)

- fix: cannot find module 'nunjucks/src/object', introduced in v3.6.0
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "html-bundler-webpack-plugin",
"version": "3.6.1",
"version": "3.6.2",
"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.",
"keywords": [
"html",
Expand Down
33 changes: 22 additions & 11 deletions src/Loader/Dependency.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
const { readDirRecursiveSync } = require('../Common/FileUtils');
const PluginService = require('../Plugin/PluginService');
const AssetEntry = require('../Plugin/AssetEntry');
Expand All @@ -11,18 +12,28 @@ class Dependency {
static fileSystem = null;
static files = new Set();
static directories = new Set();
static loaderContext = null;
static watchFiles = {};
static #entryFiles = new Set();
static entryFiles = new Set();
static excludeDirs = [];
static loaderContext = null;

static init(loaderContext) {
if (!PluginService.isWatchMode()) return;

let watchFile = loaderContext.resourcePath;

PluginService.setDependencyInstance(this);
this.loaderContext = loaderContext;
this.fileSystem = loaderContext.fs.fileSystem;
this.watchFiles = Option.getWatchFiles();
this.#entryFiles = AssetEntry.getEntryFiles();
this.entryFiles = AssetEntry.getEntryFiles();

this.excludeDirs = [];
this.entryFiles.forEach((entryFile) => {
let entryDir = path.dirname(entryFile) + path.sep;
if (!watchFile.startsWith(entryDir)) this.excludeDirs.push(entryDir);
});

this.addFile = this.addFile.bind(this);

const fs = this.fileSystem;
Expand Down Expand Up @@ -69,18 +80,18 @@ class Dependency {
static watch() {
if (!PluginService.isWatchMode()) return;

const { loaderContext } = this;
const { loaderContext, excludeDirs } = this;

for (let dir of this.directories) {
loaderContext.addContextDependency(dir);
}
this.directories.forEach(loaderContext.addContextDependency);

for (let file of this.files) {
if (!this.#entryFiles.has(file)) {
// the dependency already contains the current resource file,
// add for watching only files not defined in the entry to avoid unnecessary rebuilding of all templates
loaderContext.addDependency(file);
let isExcluded = excludeDirs.findIndex((dirname) => file.startsWith(dirname)) > -1;

if (isExcluded || this.entryFiles.has(file)) {
// ignore all files from other entry directory or the current entry file, because it is already in the list
continue;
}
loaderContext.addDependency(file);
}
}

Expand Down
20 changes: 20 additions & 0 deletions test/manual/watch-non-entry-partial-ejs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Problem `FIXED` in v3.6.2

Compiling all entrypoint files after changes of a non-entry file.

**Project files**

```
pages/home/index.html <= entrypoint
pages/home/includes/header.html <= non entry partial
pages/about/index.html <= entrypoint
pages/about/includes/header.html <= non entry partial
```

### Reproduce

- change `pages/home/index.html` => will be rendered only this file. OK
- change `pages/home/includes/header.html` => will be recompiled pages:
- pages/home/index.html (with all dependencies), OK
- pages/about/index.html (with all dependencies), NOT OK, should not be recompiled (`FIXED`)
10 changes: 10 additions & 0 deletions test/manual/watch-non-entry-partial-ejs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"start": "webpack serve --mode development",
"watch": "webpack watch --mode development",
"build": "webpack --mode=production --progress"
},
"devDependencies": {
"html-bundler-webpack-plugin": "file:../../.."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="slider">
<div>Slide 1</div>
<div>Slide 2</div>
<div>Slide 3</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>About product 123456789</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>About product</title>
</head>
<body>
<%- include('./includes/header.html') %>
<p>Test body: 123 45678</p>
<%- include('../../../components/slider/slider.html') %>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>About 123</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>About</title>
</head>
<body>
<%- include('./includes/header.html') %>
<p>Test body: 123 4567</p>
<%- include('../../../components/slider/slider.html') %>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Home 123</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>Home</title>
</head>
<body>
<%- include('./includes/header.html') %>
<p>Test body: 123</p>
<%- include('../../../components/slider/slider.html') %>
</body>
</html>
50 changes: 50 additions & 0 deletions test/manual/watch-non-entry-partial-ejs/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
mode: 'development',
stats: 'minimal',

output: {
path: path.join(__dirname, 'dist/'),
},

plugins: [
new HtmlBundlerPlugin({
entry: {
index: './src/views/pages/home/index.html',
about: './src/views/pages/about/index.html',
},
preprocessor: 'ejs',
//preprocessor: false,
//hotUpdate: true,
//verbose: true,
}),
],

// module: {
// rules: [
// {
// test: /\.(css)$/,
// use: ['css-loader'],
// },
// ],
// },

// devServer: {
// static: {
// directory: path.join(__dirname, 'dist'),
// },
// watchFiles: {
// paths: ['src/**/*.*'],
// options: {
// usePolling: true,
// },
// },
// },

watchOptions: {
// fix twice recompilation the same file
aggregateTimeout: 600,
},
};
20 changes: 20 additions & 0 deletions test/manual/watch-non-entry-partial-pug/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Problem `FIXED` in v3.6.2

Compiling all entrypoint files after changes of a non-entry file.

**Project files**

```
pages/home/index.pug <= entrypoint
pages/home/includes/header.pug <= non entry partial
pages/about/index.pug <= entrypoint
pages/about/includes/header.pug <= non entry partial
```

### Reproduce

- change `pages/home/index.pug` => will be rendered only this file. OK
- change `pages/home/includes/header.pug` => will be recompiled pages:
- pages/home/index.pug (with all dependencies), OK
- pages/about/index.pug (with all dependencies), NOT OK, should not be recompiled (`FIXED`)
10 changes: 10 additions & 0 deletions test/manual/watch-non-entry-partial-pug/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"start": "webpack serve --mode development",
"watch": "webpack watch --mode development",
"build": "webpack --mode=production --progress"
},
"devDependencies": {
"html-bundler-webpack-plugin": "file:../../.."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.slider
div Slide 1: 123
div Slide 2
div Slide 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
html
head
block head
body
.nav Menu: 123
block body
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
h1 About product
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extends ../../layouts/default

block head
title About product

block body
include includes/header
p Test body: 123
include ../../../components/slider/slider
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
h1 About 123
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extends ../../layouts/default

block head
title About

block body
include includes/header
p Test body: 123
include ../../../components/slider/slider
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
h1 Home
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extends ../../layouts/default

block head
title Home

block body
include includes/header
p Test body: 123
include ../../../components/slider/slider
49 changes: 49 additions & 0 deletions test/manual/watch-non-entry-partial-pug/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
mode: 'production',
stats: 'minimal',

output: {
path: path.join(__dirname, 'dist/'),
},

plugins: [
new HtmlBundlerPlugin({
entry: {
index: './src/views/pages/home/index.pug',
about: './src/views/pages/about/index.pug',
},
preprocessor: 'pug',
hotUpdate: true,
//verbose: true,
}),
],

module: {
rules: [
{
test: /\.(css)$/,
use: ['css-loader'],
},
],
},

devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
watchFiles: {
paths: ['src/**/*.*'],
options: {
usePolling: true,
},
},
},

watchOptions: {
// fix twice recompilation the same file
aggregateTimeout: 600,
},
};

0 comments on commit beb28f7

Please sign in to comment.