diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fa75c05..1bf307fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log +## 3.14.0 (2024-05-31) + +- feat(Pug): add `watchFiles.includes` and `watchFiles.excludes` options to allow watch specifically external file, + e.g. *.md file included via Pug filter from any location outer project directory + ## 3.13.0 (2024-05-26) - feat: add resolving the url() value in the style attribute: diff --git a/README.md b/README.md index 0c8d03d5..daad1438 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,14 @@ The **HTML Bundler** generates static HTML or [template function](#template-in-js) from [various templates](#template-engine) containing source files of scripts, styles, images, fonts and other resources, similar to how it works in [Vite](https://vitejs.dev/guide/#index-html-and-project-root). This plugin allows using a template file as an [entry point](#option-entry). -A template imported in JS will be compiled into [template function](#template-in-js). You can use the **template function** in JS to render the template with variables in runtime on the client-side in the browser. +The plugin resolves source files of assets in templates and replaces them with correct output URLs in the generated HTML. +The resolved assets will be processed via Webpack plugins/loaders and placed into the output directory. +You can use a relative path or Webpack alias to a source file. +A template imported in JS will be compiled into [template function](#template-in-js). You can use the **template function** in JS to render the template with variables in runtime on the client-side in the browser. -This plugin is an **advanced successor** to `html-webpack-plugin` and a replacement of the [plugins and loaders](#list-of-plugins). -> 📢 Please help promote this plugin on social networks so that developers know about this useful plugin.\ -> Special Thanks to [Andrew Lisowski](https://twitter.com/HipsterSmoothie) for the tooltips in the video [www.youtube.com/@devtoolsfm](https://youtu.be/w4l89214zN4?si=x-eVXN-iLlOE_Gqy&t=3463). +This plugin is an **advanced replacer** of `html-webpack-plugin` and many other [plugins and loaders](#list-of-plugins). -All source file paths in dependencies will be resolved and auto-replaced with correct URLs in the bundled output. -The resolved assets will be processed via Webpack plugins/loaders and placed into the output directory. -You can use a relative path or Webpack alias to a source file. +All source file paths in dependencies will be resolved and auto-replaced with correct URLs in the bundled output. --- @@ -127,7 +126,7 @@ You can use a relative path or Webpack alias to a source file. - Generates the [integrity](#option-integrity) attribute in the `link` and `script` tags. - Generates the [favicons](#favicons-bundler-plugin) of different sizes for various platforms. - You can create **own plugin** using the [Plugin Hooks](#plugin-hooks-and-callbacks). -- Over 500 [tests](https://github.com/webdiscus/html-bundler-webpack-plugin/tree/master/test). +- Over 550 [tests](https://github.com/webdiscus/html-bundler-webpack-plugin/tree/master/test). See the [full list of features](#features). @@ -139,38 +138,36 @@ Thank you to all our sponsors and patrons! - -
- JetBrains + JetBrains

JetBrains

- Sentry + Sentry

Sentry

- StackAid + StackAid

StackAid

- patron -

Buckley Robinson

+ patron +

Buckley
Robinson

- Pirang + Pirang

Pirang

- Marcel Robitaille -

Marcel Robitaille

+ Marcel Robitaille +

Marcel
Robitaille

- patron -

Marian Kannwischer

+ patron +

Marian
Kannwischer

- patron -

Raymond Ackloo

+ patron +

Raymond
Ackloo

diff --git a/package-lock.json b/package-lock.json index 1ca29439..e063ae5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "html-bundler-webpack-plugin", - "version": "3.11.0", + "version": "3.13.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "html-bundler-webpack-plugin", - "version": "3.11.0", + "version": "3.13.0", "license": "ISC", "dependencies": { "@types/html-minifier-terser": "^7.0.2", @@ -29,6 +29,7 @@ "@test/import-css": "file:./test/fixtures/node_modules/import-css/", "@types/jest": "^29.5.12", "@types/react-dom": "^18.2.25", + "babel-loader": "^9.1.3", "copy-webpack-plugin": "9.1.0", "css-loader": "^7.1.1", "css-minimizer-webpack-plugin": "^6.0.0", @@ -40,7 +41,6 @@ "jest": "^29.7.0", "liquidjs": "^10.10.0", "markdown-it": "^14.0.0", - "mini-css-extract-plugin": "^2.9.0", "mustache": "^4.2.0", "normalize.css": "^8.0.1", "nunjucks": "^3.2.4", @@ -4496,6 +4496,136 @@ "node": ">=8" } }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-loader/node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/babel-loader/node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -5196,6 +5326,12 @@ "node": ">=14" } }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -9908,26 +10044,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dev": true, - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -16675,6 +16791,7 @@ "@types/jest": "^29.5.12", "@types/react-dom": "^18.2.25", "ansis": "2.0.3", + "babel-loader": "^9.1.3", "copy-webpack-plugin": "9.1.0", "css-loader": "^7.1.1", "css-minimizer-webpack-plugin": "^6.0.0", @@ -16689,7 +16806,6 @@ "jest": "^29.7.0", "liquidjs": "^10.10.0", "markdown-it": "^14.0.0", - "mini-css-extract-plugin": "^2.9.0", "mustache": "^4.2.0", "normalize.css": "^8.0.1", "nunjucks": "^3.2.4", @@ -19944,6 +20060,86 @@ } } }, + "babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dev": true, + "requires": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "requires": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + } + }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "requires": { + "find-up": "^6.3.0" + } + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } + }, "babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -20471,6 +20667,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -23943,16 +24145,6 @@ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true }, - "mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dev": true, - "requires": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - } - }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -27987,6 +28179,86 @@ } } }, + "babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dev": true, + "requires": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "requires": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + } + }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "requires": { + "find-up": "^6.3.0" + } + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } + }, "babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -28514,6 +28786,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -31986,16 +32264,6 @@ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true }, - "mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dev": true, - "requires": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - } - }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", diff --git a/package.json b/package.json index 31c21aee..fd4a2be9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "html-bundler-webpack-plugin", - "version": "3.13.0", + "version": "3.14.0", "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", diff --git a/src/Loader/Dependency.js b/src/Loader/Dependency.js index 7f753263..aa5cf73e 100644 --- a/src/Loader/Dependency.js +++ b/src/Loader/Dependency.js @@ -34,18 +34,52 @@ class Dependency { if (!watchFile.startsWith(entryDir)) this.excludeDirs.push(entryDir); }); - this.addFile = this.addFile.bind(this); + this.addFileToWatch = this.addFileToWatch.bind(this); const fs = this.fileSystem; const { files: includes, ignore: excludes, paths = [] } = this.watchFiles; for (const watchDir of paths) { const files = readDirRecursiveSync(watchDir, { fs, includes, excludes }); - files.forEach(this.addFile); + files.forEach(this.addFileToWatch); } const customWatchFiles = Option.getCustomWatchFiles(); - if (customWatchFiles.length > 0) customWatchFiles.forEach(this.addFile); + if (customWatchFiles.length > 0) customWatchFiles.forEach(this.addFileToWatch); + } + + /** + * Check whether the adding file is watchable. + * + * TODO: add to documentation the new options: includes (defaults as watchFiles.files), excludes + * + * @param {string} watchFile + * @return boolean + */ + static isFileWatchable(watchFile) { + let { includes, excludes } = this.watchFiles; + + let isIncluded = includes + ? includes.some((item) => { + if (item.constructor.name === 'RegExp') { + return item.test(watchFile); + } + + return item === watchFile; + }) + : true; + + let isExcluded = excludes + ? excludes.some((item) => { + if (item.constructor.name === 'RegExp') { + return item.test(watchFile); + } + + return item === watchFile; + }) + : false; + + return isIncluded && !isExcluded; } /** @@ -56,9 +90,20 @@ class Dependency { } /** + * Add file using include & exculude filter. + * * @param {string} file */ static addFile(file) { + if (this.isFileWatchable(file)) { + this.addFileToWatch(file); + } + } + + /** + * @param {string} file + */ + static addFileToWatch(file) { this.files.add(file); // delete the file from require.cache to reload cached file after change diff --git a/src/Loader/Option.js b/src/Loader/Option.js index ebc637ce..7bbe596c 100644 --- a/src/Loader/Option.js +++ b/src/Loader/Option.js @@ -175,10 +175,16 @@ class Option { /webpack\.(.+)\.js$/, /\.(je?pg|png|ico|gif|webp|svg|woff2?|ttf|otf|eot)$/, ], + + // include custom files + includes: null, + + // exclude custom files + excludes: null, }; const fs = this.fileSystem; - const { paths, files, ignore } = pluginOption.getWatchFiles(); + let { paths, files, ignore, includes, excludes } = pluginOption.getWatchFiles(); const watchDirs = new Set([rootSourceDir(this.#rootContext, this.#resourcePath)]); const rootContext = this.#rootContext; @@ -224,6 +230,14 @@ class Option { } } + if (!includes) { + watchFiles.includes = watchFiles.files; + } else { + if (!Array.isArray(includes)) includes = [includes]; + watchFiles.includes = [...watchFiles.files, ...includes]; + } + watchFiles.excludes = excludes && !Array.isArray(excludes) ? [excludes] : excludes; + this.#watchFiles = watchFiles; } diff --git a/src/Loader/Preprocessors/Pug/ResolvePlugin.js b/src/Loader/Preprocessors/Pug/ResolvePlugin.js index 58c18fe8..046067bb 100644 --- a/src/Loader/Preprocessors/Pug/ResolvePlugin.js +++ b/src/Loader/Preprocessors/Pug/ResolvePlugin.js @@ -1,4 +1,5 @@ const path = require('path'); +const Dependency = require('../../Dependency'); const Resolver = require('../../Resolver'); const { encodeReservedChars } = require('../../Utils'); const { isWin, pathToPosix } = require('../../../Common/Helpers'); @@ -306,7 +307,12 @@ const ResolvePlugin = { * @return {string} */ resolve(filename, templateFile, options) { - return Resolver.resolve(filename.trim(), templateFile.trim(), Resolver.types.include); + const file = Resolver.resolve(filename.trim(), templateFile.trim(), Resolver.types.include); + + // add included file as dependency to watch + Dependency.addFile(file); + + return file; }, /** diff --git a/src/Loader/index.js b/src/Loader/index.js index 07e495e4..7a95a2b3 100644 --- a/src/Loader/index.js +++ b/src/Loader/index.js @@ -48,6 +48,7 @@ const loader = function (content, map, meta) { errorStage = 'init'; Option.init(loaderContext); Loader.init(loaderContext); + Dependency.init(loaderContext); resolve(); }) .then(() => { @@ -101,7 +102,6 @@ const loader = function (content, map, meta) { }) .then((value) => { errorStage = 'watch'; - Dependency.init(loaderContext); Dependency.watch(); callback(null, value); }) diff --git a/test/cases/postprocess-modify-js/expected/index.html b/test/cases/postprocess-modify-js/expected/index.html index 6206d31c..032ded7d 100644 --- a/test/cases/postprocess-modify-js/expected/index.html +++ b/test/cases/postprocess-modify-js/expected/index.html @@ -2,7 +2,7 @@ Test - +

Hello World!

diff --git a/test/cases/postprocess-modify-js/src/main.js b/test/cases/postprocess-modify-js/src/main.js index f3e78979..9b874f37 100644 --- a/test/cases/postprocess-modify-js/src/main.js +++ b/test/cases/postprocess-modify-js/src/main.js @@ -1,6 +1,34 @@ -let $i = 0; -for ($i = 0; $i < 10; $i++) {} +// use all abc variable names to simulate generation a variable with a name containing the `$` symbol +let a = 0; +let b = a++; +let c = b++; +let d = c++; +let e = d++; +let f = e++; +let g = f++; +let h = g++; +let i = h++; +let j = i++; +let k = j++; +let l = k++; +let m = l++; +let n = m++; +let o = n++; +let p = o++; +let q = p++; +let r = q++; +let s = r++; +let t = s++; +let u = t++; +let v = u++; +let w = v++; +let x = w++; +let y = x++; +let z = y++; +let $z = z++; -let $str = `Count: ${$i} $.`; +// the goal is to generate such JS code, which contains `$` symbol, e.g. in in variable names +// the `$` symbol will be replaced in the testing plugin function used in webpack config +let $str = `Count: ${n} $.`; -console.log($str); +console.log($str, $z); diff --git a/test/cases/postprocess-modify-js/webpack.config.js b/test/cases/postprocess-modify-js/webpack.config.js index fe2a1864..cf65e441 100644 --- a/test/cases/postprocess-modify-js/webpack.config.js +++ b/test/cases/postprocess-modify-js/webpack.config.js @@ -26,10 +26,12 @@ module.exports = { let source = compilation.assets[jsFilename].source(); // modify JS code - source = source.replace(/\$[^\{]/g, 'dollars'); + let newSource = source.replace(/\$[^\{]/g, '__S__'); + + //console.log('\n## OLD SOURCE: ', source, '\n## NEW SOURCE: ', newSource); // update compilation with new JS code before this code will be inlined into HTML - compilation.updateAsset(jsFilename, new RawSource(source)); + compilation.updateAsset(jsFilename, new RawSource(newSource)); }, }), ], diff --git a/types.d.ts b/types.d.ts index de0c4ff4..41a66e46 100644 --- a/types.d.ts +++ b/types.d.ts @@ -347,6 +347,8 @@ type WatchFiles = { paths?: Array; files?: Array; ignore?: Array; + includes?: Array; + excludes?: Array; }; // Private types: used in source code only