Skip to content

Commit

Permalink
feat: add support for Webpack v5.96
Browse files Browse the repository at this point in the history
  • Loading branch information
webdiscus committed Nov 3, 2024
1 parent d32655c commit 16936f3
Show file tree
Hide file tree
Showing 154 changed files with 1,729 additions and 2,882 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Change log

## 4.2.0 (2024-11-03)

- feat: add support for Webpack `>= 5.96` to correct inline images into CSS and HTML
WARNING: Webpack version `5.96.0` introduces the BREAKING CHANGE in the `CodeGenerationResults` class!
- feat: add support for Webpack `>= 5.96` to correct CSS lazy loading
WARNING: Webpack version `5.96.0` introduces the BREAKING CHANGE in the `AssetGenerator` class!
- chore: update package and devel dependencies
- test: update tests

## 4.1.4 (2024-11-01)

- chore: update dependencies
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,9 @@ If you have discovered a bug or have a feature suggestion, feel free to create a
## 🔆 What's New in v4

- **NEW** added supports the [multiple configurations](https://webpack.js.org/configuration/configuration-types/#exporting-multiple-configurations).
- **SUPPORTS** Node.js version `18+`
- **SUPPORTS** Webpack version `5.81+`
- **SUPPORTS** Webpack version `5.96+` (since `v4.2.0`).
- **SUPPORTS** Webpack version `5.81+` (since `v4.0.0`).
- **SUPPORTS** Node.js version `18+`.
- **BREAKING CHANGES** see in the [changelog](https://github.com/webdiscus/html-bundler-webpack-plugin/blob/master/CHANGELOG.md#v4-0-0).

## 🔆 What's New in v3
Expand All @@ -235,8 +236,11 @@ For full release notes see the [changelog](https://github.com/webdiscus/html-bun

### Cache type

The current version works stable with `cache.type` as `'memory'` (Webpack's default setting).\
Support for the `'filesystem'` cache type is experimental.
The current version works stably with `cache.type` as `'memory'` (Webpack's default setting).

Support for the `'filesystem'` cache type is in beta.
It works stably in standard use cases, but it cannot be guaranteed to work in all use cases.
If you have any problems, feel free to create an [issue](https://github.com/webdiscus/html-bundler-webpack-plugin/issues).

---

Expand Down
3,937 changes: 1,205 additions & 2,732 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "html-bundler-webpack-plugin",
"version": "4.1.4",
"version": "4.2.0",
"description": "HTML Bundler Plugin for Webpack renders HTML templates containing source files of scripts, styles, images. Supports template engines: Eta, EJS, Handlebars, Nunjucks, Pug, TwigJS. Alternative to html-webpack-plugin.",
"keywords": [
"html",
Expand Down Expand Up @@ -145,12 +145,12 @@
"@types/html-minifier-terser": "^7.0.2",
"ansis": "3.3.2",
"enhanced-resolve": ">=5.7.0",
"eta": "^3.4.1",
"eta": "^3.5.0",
"html-minifier-terser": "^7.2.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.4",
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@emotion/react": "11.13.0",
"@emotion/styled": "11.13.0",
"@mui/material": "5.16.7",
Expand All @@ -160,23 +160,23 @@
"@test-fixtures/scss": "0.0.7",
"@test/html-bundler-webpack-plugin": "file:./",
"@test/import-css": "file:./test/fixtures/node_modules/import-css/",
"@types/jest": "^29.5.12",
"@types/react-dom": "^18.3.0",
"@types/jest": "^29.5.14",
"@types/react-dom": "^18.3.1",
"copy-webpack-plugin": "9.1.0",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"cssnano": "^7.0.5",
"cssnano": "^7.0.6",
"ejs": "^3.1.10",
"favicons": "7.2.0",
"handlebars": "^4.7.8",
"handlebars-layouts": "^3.1.4",
"jest": "^29.7.0",
"liquidjs": "^10.17.0",
"liquidjs": "^10.18.0",
"markdown-it": "^14.1.0",
"mustache": "^4.2.0",
"normalize.css": "^8.0.1",
"nunjucks": "^3.2.4",
"parse5": "^7.1.2",
"parse5": "^7.2.1",
"postcss-loader": "^8.1.1",
"prettier": "^3.3.3",
"prismjs": "^1.29.0",
Expand All @@ -185,17 +185,17 @@
"react-dom": "18.3.1",
"responsive-loader": "^3.1.2",
"rtlcss": "^4.3.0",
"sass": "1.77.8",
"sass-loader": "15.0.0",
"sass": "1.80.6",
"sass-loader": "16.0.3",
"sharp": "^0.33.5",
"svgo-loader": "^4.0.0",
"ts-loader": "9.5.1",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"twig": "^1.17.1",
"typescript": "5.5.4",
"vue": "3.5.3",
"typescript": "5.6.3",
"vue": "3.5.12",
"vue-loader": "^17.4.2",
"webpack": "^5.95.0",
"webpack": "5.96.1",
"webpack-cli": "5.1.4",
"webpack-dev-server": "^5.1.0"
}
Expand Down
63 changes: 63 additions & 0 deletions src/Common/Helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,67 @@ const replaceAll = (str, search, replace) => {
return str.replace(new RegExp(search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

/**
* Parse version string including leading compare chars.
* For example: '=5.96.1', '>5.96.1', '< 5.96.1', '<= 5.96.1', >= 5.96.1'
*
* @param version
* @return {[compare: string, version: string]}
*/
const parseVersion = (version) => {
let i;
for (i = 0; i < version.length; i++) {
let char = version.codePointAt(i);
if (char >= 48 && char <= 57) {
break;
}
}
let compare = version.slice(0, i);
compare = compare.trim();

return [compare, version.slice(i)];
};

/**
* Compare two semantic versions.
*
* @param {string} version1
* @param {string} compare One of: `=`, `<`, `>`, `<=`, `>=`
* @param {string} version2
* @return {boolean}
*/
const compareVersions = (version1, compare, version2) => {
const sortVersions = (x, v = (s) => s.match(/[a-z]|\d+/g).map((c) => (c == ~~c ? String.fromCharCode(97 + c) : c))) =>
x.sort((a, b) => ((a + b).match(/[a-z]/) ? (v(b) < v(a) ? 1 : -1) : a.localeCompare(b, 0, { numeric: true })));

const versions = [version1, version2];
const sorted = sortVersions(versions);
let result;

if (version1 === version2) {
result = 0;
} else if (sorted[0] === version1) {
result = -1;
} else {
result = 1;
}

switch (compare) {
case '=':
return result === 0;
case '<':
return result === -1;
case '>':
return result === 1;
case '<=':
return result === 0 || result === -1;
case '>=':
return result === 0 || result === 1;
}

return false;
};

module.exports = {
isWin,
isFunction,
Expand All @@ -143,4 +204,6 @@ module.exports = {
detectIndent,
replaceAll,
outToConsole,
parseVersion,
compareVersions,
};
22 changes: 19 additions & 3 deletions src/Plugin/AssetCompiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Config = require('../Common/Config');
const { baseUri, urlPathPrefix, cssLoaderName } = require('../Loader/Utils');
const { findRootIssuer } = require('../Common/CompilationHelpers');
const { isDir } = require('../Common/FileUtils');
const { outToConsole } = require('../Common/Helpers');
const { parseVersion, compareVersions } = require('../Common/Helpers');
const createPersistentCache = require('./createPersistentCache');

const CssExtractModule = require('./Modules/CssExtractModule');
Expand Down Expand Up @@ -99,6 +99,9 @@ let RawSource;
class AssetCompiler {
static processAssetsPromises = [];

/** Whether the installed Webpack version < 5.96.0 */
IS_WEBPACK_VERSION_LOWER_5_96_0 = true;

/** @type {Array<Promise>} */
promises = [];

Expand Down Expand Up @@ -398,6 +401,8 @@ class AssetCompiler {
const { NormalModule, Compilation } = compilation.compiler.webpack;
const normalModuleHooks = NormalModule.getCompilationHooks(compilation);

this.IS_WEBPACK_VERSION_LOWER_5_96_0 = compareVersions(compilation.compiler.webpack.version, '<', '5.96.0');

this.compilation = compilation;
this.pluginContext.compilation = compilation;
this.assetEntry.setCompilation(compilation);
Expand Down Expand Up @@ -778,11 +783,22 @@ class AssetCompiler {

// lazy load CSS in JS using `?url` query, see js-import-css-lazy-url
if (meta.isImportedStyle && isUrl && !query.includes(cssLoaderName)) {
const dataUrlOptions = undefined;
const filename = this.pluginOption.getCss().filename;

if (this.IS_WEBPACK_VERSION_LOWER_5_96_0) {
// Webpack <= 5.95
createData.generator = new AssetGenerator(undefined, filename);
} else {
// Webpack >= 5.96
const moduleGraph = this.compilation.moduleGraph;
const dataUrl = undefined;
const publicPath = undefined;
const outputPath = undefined;
const emit = true;
createData.generator = new AssetGenerator(moduleGraph, dataUrl, filename, publicPath, outputPath, emit);
}

createData.parser = new AssetParser(false);
createData.generator = new AssetGenerator(dataUrlOptions, filename);
createData.type = ASSET_MODULE_TYPE_RESOURCE;
}
}
Expand Down
23 changes: 22 additions & 1 deletion src/Plugin/AssetInline.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,28 @@ class AssetInline {
}
} else if (item.source == null) {
// data URL for binary resource
const dataUrl = codeGenerationResults.getData(module, chunk.runtime, 'url').toString();
const data = codeGenerationResults.getData(module, chunk.runtime, 'url');
let dataUrl;

// note: webpack has introduced a braking change by 5.95.0 -> 5.96.0
if (!data?.javascript) {
// webpack <= 5.95.x: data is Buffer
dataUrl = data.toString();
} else if (data?.javascript) {
// webpack => 5.96.0: data contains `javascript` key
dataUrl = data?.javascript;

// remove quotes in value like "data:image/..."
if (dataUrl.at(0) === '"') {
dataUrl = dataUrl.slice(1, -1);
}
} else {
// warning as svg
const warning1 = 'Downgrade your webpack.';
const warning2 = 'This version is not compatible.';
dataUrl = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='40' viewBox='0 0 200 40'><text y='15'>${warning1}</text><text dy='30'>${warning2}</text></svg>`;
}

item.source = { dataUrl };
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<!DOCTYPE html><html><head><style>h1{color:#228b22}</style>
<!DOCTYPE html><html><head><style>h1{color:forestgreen}</style>
</head><body><h1>Home</h1><div class="my-component"><style scope="some">.my-component{color:violet}</style><div>my component</div></div></body></html>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="css/main.4f0fb2f1.css"><link rel="stylesheet" href="css/style.f07588a7.css"><script src="js/main.bundle.js"></script></head><body><h4>Default layout</h4><h1>About</h1><script src="js/script.1.bundle.js"></script></body></html>
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="css/main.4f0fb2f1.css"><link rel="stylesheet" href="css/style.f07588a7.css"><script src="js/main.5317c1f6.js"></script></head><body><h4>Default layout</h4><h1>About</h1><script src="js/about.e55bdc4a.js"></script></body></html>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="css/main.4f0fb2f1.css"><script src="js/main.bundle.js"></script></head><body><h4>Default layout</h4><h1>Start page</h1></body></html>
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="css/main.4f0fb2f1.css"><script src="js/main.5317c1f6.js"></script></head><body><h4>Default layout</h4><h1>Start page</h1></body></html>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="css/main.4f0fb2f1.css"><link rel="stylesheet" href="css/style.dd1336a7.css"><script src="js/main.bundle.js"></script></head><body><h4>Default layout</h4><h1>News</h1><script src="js/script.bundle.js"></script></body></html>
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="css/main.4f0fb2f1.css"><link rel="stylesheet" href="css/style.dd1336a7.css"><script src="js/main.5317c1f6.js"></script></head><body><h4>Default layout</h4><h1>News</h1><script src="js/news.26d1b659.js"></script></body></html>
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
extends @views/layouts/default

append script
script(src='./script.js')
script(src='./about.js')

append style
link(rel='stylesheet' href=require('./style.css'))
//-link(rel='stylesheet' href='./style.css')
link(rel='stylesheet' href='./style.css')

block content
h1 About
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
extends @views/layouts/default

append script
script(src='./script.js')
script(src='./news.js')

append style
link(rel='stylesheet' href=require('./style.css'))
//-link(rel='stylesheet' href='./style.css')
link(rel='stylesheet' href='./style.css')

block content
h1 News
4 changes: 1 addition & 3 deletions test/cases/_pug/resolve-js-css-multipage/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ module.exports = {
index: './src/views/pages/index.pug',
},
js: {
// the problem: randomize contenthash after every test
//filename: 'js/[name].[contenthash:8].js',
filename: 'js/[name].bundle.js',
filename: 'js/[name].[contenthash:8].js',
},
css: {
filename: 'css/[name].[contenthash:8].css',
Expand Down
14 changes: 13 additions & 1 deletion test/cases/css-devtool-inline-source-map/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,19 @@ module.exports = {
rules: [
{
test: /\.(css|scss)$/,
use: ['css-loader', 'sass-loader'],
//use: ['css-loader', 'sass-loader'], // sass-loader <= 15.0.0
use: [
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
// include the sources in the generated source map (required since sass-loader >= 16.0.0)
sourceMapIncludeSources: true,
},
},
},
],
},
],
},
Expand Down
14 changes: 13 additions & 1 deletion test/cases/css-devtool-source-map/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,19 @@ module.exports = {
rules: [
{
test: /\.(css|scss)$/,
use: ['css-loader', 'sass-loader'],
//use: ['css-loader', 'sass-loader'], // sass-loader <= 15.0.0
use: [
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
// include the sources in the generated source map (required since sass-loader >= 16.0.0)
sourceMapIncludeSources: true,
},
},
},
],
},
],
},
Expand Down
14 changes: 13 additions & 1 deletion test/cases/entry-scss-font-url/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,19 @@ module.exports = {
rules: [
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader'],
//use: ['css-loader', 'sass-loader'], // sass-loader <= 15.0.0
use: [
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
// include the sources in the generated source map (required since sass-loader >= 16.0.0)
sourceMapIncludeSources: true,
},
},
},
],
},
{
test: /\.(woff|woff2|eot|ttf|otf|svg)$/i,
Expand Down

This file was deleted.

Loading

0 comments on commit 16936f3

Please sign in to comment.