Skip to content

Commit

Permalink
release v2.15.0
Browse files Browse the repository at this point in the history
- feat: add `parsedValue` argument as an array of parsed filenames w/o URL query, in the `filter()` function of the `sources`
- fix(BREAKING CHANGE): for `srcset` attribute the type of the `value` argument is now `string` (was as `Array<string>`), in the `filter()` function of the `sources`, #36\
  Note: for `srcset` attribute you can use the `parsedValue` as an array instead of the `value`, the `value` contains now an original string
- docs: fix attributes type
  • Loading branch information
webdiscus committed Oct 18, 2023
1 parent f2e39c3 commit 6f8e15b
Show file tree
Hide file tree
Showing 36 changed files with 160 additions and 66 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Change log

## 2.14.5 (2023-10-17)
## 2.15.0 (2023-10-18)

- fix: correct the type of the `value` argument in the `filter()` function of the `sources` loader option
- feat: add `parsedValue` argument as an array of parsed filenames w/o URL query, in the `filter()` function of the `sources`
- fix(BREAKING CHANGE): for `srcset` attribute the type of the `value` argument is now `string` (was as `Array<string>`), in the `filter()` function of the `sources`\
Note: for `srcset` attribute you can use the `parsedValue` as an array instead of the `value`, the `value` contains now an original string
- docs: fix attributes type

## 2.14.4 (2023-10-12)

Expand All @@ -20,7 +23,7 @@
- fix: pass correct entry data in the template when the same template used for many pages with different data, in `serve` mode

## 2.14.1 (2023-09-24)
-

- fix: remove unused `isEntry` property from the `info` argument of the `postprocess` callback
the `isEntry` property was always true, because template is defined as an entrypoint
- chore: code cleanup
Expand Down
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ The plugin automatically extracts JS and CSS whose source files are specified in

```ts
type EntryObject = {
[key: string]: EntryDescription | string;
[name: string]: EntryDescription | string;
};
```

Expand Down Expand Up @@ -681,7 +681,7 @@ type EntryDescription = {
/**
* The template data.
*/
data?: { [k: string]: any } | string;
data?: { [key: string]: any } | string;
};

type FilenameTemplate =
Expand Down Expand Up @@ -1330,7 +1330,7 @@ type Preload = Array<{
as?: string;
rel?: string;
type?: string;
attributes?: { [k: string]: string | boolean };
attributes?: { [attributeName: string]: string | boolean };
}>;
```
Expand Down Expand Up @@ -2008,8 +2008,9 @@ type Sources =
filter?: (props: {
tag: string;
attribute: string;
value: string | Array<string>;
attributes: { [k: string]: string };
value: string;
parsedValue: Array<string>;
attributes: { [attributeName: string]: string };
resourcePath: string;
}) => boolean | undefined;
}>;
Expand Down Expand Up @@ -2071,10 +2072,15 @@ The argument is an object containing the properties:
- `tag: string` - a name of the HTML tag
- `attribute: string` - a name of the HTML attribute
- `value: string | Array<string>` - a value of the HTML attribute;\
for `srcset` the `value` argument is an array of parsed filenames,\
an original srcset value as string is available via `attributes.srcset`
- `attributes: string` - all attributes of the tag
- `value: string` - an original value of the HTML attribute
- `parsedValue: Array<string>` - an array of filenames w/o URL query, parsed in the value\
it's useful for the `srcset` attribute containing many image files, e.g.:
```html
<img src="image.png?size=800" srcset="image1.png?size=200 200w, image2.png 400w">
```
the `parsedValue` for the `src` is `['image.png']`, the array with one parsed filename\
the `parsedValue` for the `srcset` is `['image1.png', 'image2.png']`
- `attributes: { [attributeName: string]: string }` - all attributes of the tag
- `resourcePath: string` - a path of the HTML template
The processing of an attribute can be ignored by returning `false`.
Expand Down Expand Up @@ -2259,7 +2265,7 @@ type BeforePreprocessor =
| false
| ((
template: string,
loaderContext: LoaderContext<Object> & { data: { [k: string]: any } | string }
loaderContext: LoaderContext<Object> & { data: { [key: string]: any } | string }
) => string | undefined);
```
Expand Down Expand Up @@ -2311,7 +2317,7 @@ type Preprocessor =
| 'nunjucks'
| ((
template: string,
loaderContext: LoaderContext<Object> & { data: { [k: string]: any } | string }
loaderContext: LoaderContext<Object> & { data: { [key: string]: any } | string }
) => string | Promise<any> | undefined);
```
Expand Down Expand Up @@ -2391,7 +2397,7 @@ To use any templating engine, you can define the `preprocessor` as a function.
```ts
type Preprocessor = (
template: string,
loaderContext: LoaderContext<Object> & { data: { [k: string]: any } | string }
loaderContext: LoaderContext<Object> & { data: { [key: string]: any } | string }
) => string | Promise<any> | undefined;
```
Expand Down
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": "2.14.5",
"version": "2.15.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",
Expand Down
14 changes: 8 additions & 6 deletions src/Common/HtmlParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,14 @@ class HtmlParser {
let res = true;

if (filter) {
let value = parsedAttr.value;
const { value, parsedValue } = parsedAttr;

// when is the filter defined, parse all attributes once
if (!attrs) {
attrs = this.parseAttrAll(source);
}

res = filter({ tag, attribute, value, attributes: attrs, resourcePath }) !== false;
res = filter({ tag, attribute, value, parsedValue, attributes: attrs, resourcePath }) !== false;
}

if (res === true) {
Expand Down Expand Up @@ -223,7 +223,7 @@ class HtmlParser {
* @param {string} attr The attribute to parse value.
* @param {string} type The type of attribute value.
* @param {Number} offset The absolute tag offset in the content.
* @return {{attr: string, attrs?: Array, value: string|Array<string>, startPos: number, endPos: number}|boolean}
* @return {{attr: string, attrs?: Array, value: string, parsedValue: Array<string>, startPos: number, endPos: number}|boolean}
*/
static parseAttr(content, attr, type = 'asset', offset = 0) {
const open = `${attr}="`;
Expand All @@ -248,14 +248,15 @@ class HtmlParser {
return {
attr,
attrs,
value: values,
value,
parsedValue: values,
startPos,
endPos,
offset,
};
}

return { type, attr, value, startPos, endPos, offset };
return { type, attr, value, parsedValue: [value.split('?', 1)[0]], startPos, endPos, offset };
}

/**
Expand All @@ -282,6 +283,7 @@ class HtmlParser {
// support for 'responsive-loader' value, e.g.: image.png?{sizes: [100,200,300], format: 'jpg'}
if (srcsetValue.indexOf('?{') > 0) {
return {
// TODO: parse this complex non-standard use case
values: [srcsetValue],
attrs: [
{ type, attr: 'srcset', value: srcsetValue, startPos: valueOffset, endPos: valueOffset + lastPos, offset },
Expand Down Expand Up @@ -309,7 +311,7 @@ class HtmlParser {
endPos = currentPos;
}

values.push(value);
values.push(value.split('?', 1)[0]);

attrs.push({
type,
Expand Down
10 changes: 0 additions & 10 deletions test/cases/loader-option-sources-attrs/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ module.exports = {
tag: 'img-ng',
attributes: ['data-src-one', 'data-src-two'],
},
// TODO: in next major version
// - change the value as original string
// - add the values argument containing array of parsed in srcset filenames
// {
// tag: 'img',
// attributes: ['srcset'],
// filter: ({ attribute, value, values }) => {
// console.log('\n### ATTR: ', { attribute, value, values });
// },
// },
{
tag: 'link',
attributes: ['data-source'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<!-- this data-srcset should be resolved -->
<img src="assets/img/apple.02a7c382.png" data-srcset="assets/img/fig.c6809878.png, assets/img/fig2.c6809878.png 100w, assets/img/fig3.c6809878.png 1.5x">
<!-- this data-srcset should not be resolved -->
<img src="@images/pear.png?size=300" data-srcset="@images/lemon.png?size=200, @images/lemon2.png 100w, @images/lemon3.png 1.5x">
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<!-- this data-srcset should be resolved -->
<img src="@images/apple.png" data-srcset="@images/fig.png, @images/fig2.png 100w, @images/fig3.png 1.5x">
<!-- this data-srcset should not be resolved -->
<img src="@images/pear.png?size=300" data-srcset="@images/lemon.png?size=200, @images/lemon2.png 100w, @images/lemon3.png 1.5x">
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const path = require('path');
const HtmlBundlerPlugin = require('../../../');

module.exports = {
mode: 'production',

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

resolve: {
alias: {
'@images': path.join(__dirname, '../../fixtures/images'),
},
},

plugins: [
new HtmlBundlerPlugin({
entry: {
index: './src/index.html',
},
loaderOptions: {
sources: [
{
tag: 'img',
attributes: ['data-srcset'],
// test parsedValue
filter: ({ attribute, value, parsedValue }) => {
//console.log('\n### filter attributes: ', { attribute, value, parsedValue });
if (attribute === 'src' && parsedValue.includes('@images/pear.png')) return false;
if (attribute === 'data-srcset' && parsedValue.includes('@images/lemon.png')) return false;
},
},
],
},
}),
],

module: {
rules: [
{
test: /\.(png|jpe?g|ico|svg)$/,
type: 'asset/resource',
generator: {
filename: 'assets/img/[name].[hash:8][ext][query]',
},
},
],
},
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ module.exports = {
// add filter to default tag
{
tag: 'img',
filter: ({ tag, attribute, value, attributes, resourcePath }) => {
filter: ({ tag, attribute, value, parsedValue, attributes, resourcePath }) => {
if (attribute === 'src' && !value.endsWith('lemon.png')) return false;
if (attribute === 'srcset' && !value.find((item) => item.endsWith('fig3.png'))) return false;
if (attribute === 'srcset' && !parsedValue.find((item) => item.endsWith('fig3.png'))) return false;
},
},

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h1>Home</h1>
<img src="../assets/img/apple-160w.png">

<!-- resized image -->
<img src="../assets/img/apple-50w.png">
<img src="../assets/img/apple-50w.png" srcset="../assets/img/apple-60w.png w600, ../assets/img/apple-70w.png w700">

<!-- placeholder via CSS -->
<div class="header-container placeholder-css"></div>
Expand Down
2 changes: 1 addition & 1 deletion test/cases/responsive-images-html-css/src/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h1>Home</h1>
<img src="@images/apple.png">

<!-- resized image -->
<img src="@images/apple.png?size=50">
<img src="@images/apple.png?size=50" srcset="@images/apple.png?size=60 w600, @images/apple.png?size=70 w700">

<!-- placeholder via CSS -->
<div class="header-container placeholder-css"></div>
Expand Down
1 change: 1 addition & 0 deletions test/cases/responsive-images-html-css/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
plugins: [
new HtmlBundlerPlugin({
entry: {
// test a relative image path
'pages/home': './src/views/index.html',
},
js: {
Expand Down
7 changes: 5 additions & 2 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,12 @@ describe('plugin minify option', () => {
describe('loader options common', () => {
test('defaults, when in module.rules is not defined', () => compareFiles('loader-option-defaults'));
test('disable parsing for all tags and attributes', () => compareFiles('loader-option-sources-false'));

test('add custom tags and attributes', () => compareFiles('loader-option-sources-attrs'));
test('filter tags and attributes', () => compareFiles('loader-option-sources-attrs-filter'));
test('filter property attribute', () => compareFiles('loader-option-sources-attrs-filter-property'));
test('filter tags and attributes', () => compareFiles('loader-option-sources-filter'));
test('filter property attribute', () => compareFiles('loader-option-sources-filter-property'));
test('filter, parsedValues', () => compareFiles('loader-option-sources-filter-parsedValues'));

test('preprocessor by defaults', () => compareFiles('loader-option-preprocessor-default'));
test('preprocessor disabled', () => compareFiles('loader-option-preprocessor-disabled'));
test('preprocessor null', () => compareFiles('loader-option-preprocessor-return-null'));
Expand Down
Loading

0 comments on commit 6f8e15b

Please sign in to comment.