New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

html-bundler-webpack-plugin

Package Overview
Dependencies
Maintainers
1
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

html-bundler-webpack-plugin - npm Package Compare versions

Comparing version 0.8.0 to 0.9.0

42

CHANGELOG.md
# Change log
## 0.9.0 (2023-02-04)
- feat(BREAKING CHANGE): the 3rd argument `data` of the `preprocessor` has been moved to the 2nd argument as a property\
`v0.9.0`: `preprocessor: (content, { resourcePath, data }) => {}` <= NEW syntax\
`v0.8.0`: `preprocessor: (content, { resourcePath }, data) => {}` <= old syntax
- fix: avoids an additional query param for internal use in the module's `resource` property
- fix: remove info comments before inlined SVG
- docs: add description how to pass data into template using new option `entry`
## 0.8.0 (2023-02-01)
- feat: add `entry` plugin option, this has same API as Webpack entry, but have additional `data` property
- feat: pass custom data into `preprocessor` via additional `data` property of `entry` plugin option
- feat: add `entry` plugin option, this has same API as Webpack entry plus additional `data` property
- feat: add 3rd `data` argument of the `preprocessor` to pass template specific data:
```js
module.exports = {
plugins: [
new HtmlBundlerPlugin({
entry: { // <= NEW `entry` option
index: {
import: 'src/views/template.html',
data: { // <= NEW `data` property
title: 'Home',
},
},
},
}),
],
module: {
rules: [
{
test: /\.(html)$/,
loader: HtmlBundlerPlugin.loader,
options: {
preprocessor: (content, { resourcePath }, data) => { // <= NEW 3rd `data` argument
return render(content, data);
},
},
},
],
},
};
```
- feat: support split chunk

@@ -7,0 +45,0 @@

5

package.json
{
"name": "html-bundler-webpack-plugin",
"version": "0.8.0",
"version": "0.9.0",
"description": "HTML bundler plugin for webpack handels HTML templates as entry point and extracts CSS, JS, images from their sources loaded in HTML.",

@@ -83,2 +83,3 @@ "keywords": [

"css-loader": "^6.7.3",
"ejs": "^3.1.8",
"handlebars": "^4.7.7",

@@ -89,3 +90,3 @@ "jest": "^29.4.1",

"responsive-loader": "^3.1.2",
"sass": "^1.57.1",
"sass": "^1.58.0",
"sass-loader": "^13.2.0",

@@ -92,0 +93,0 @@ "sharp": "^0.31.3",

<div align="center">
<h1>
<img height="120" src="https://user-images.githubusercontent.com/30186107/29488525-f55a69d0-84da-11e7-8a39-5476f663b5eb.png">
<img height="120" src="https://webpack.js.org/assets/icon-square-big.svg">
<a href="https://github.com/webdiscus/html-bundler-webpack-plugin"><br>
<img height="200" src="https://raw.githubusercontent.com/webdiscus/html-bundler-webpack-plugin/master/images/plugin-logo.png">
<br>
<a href="https://github.com/webdiscus/html-bundler-webpack-plugin">
HTML Bundler Plugin for Webpack

@@ -19,9 +19,8 @@ </a>

The plugin allows to use an HTML file or a template as a starting point for collecting all the dependencies used in your web application.
The plugin make Webpack setup easily and intuitive.
This plugin allows to use an HTML file or a template as a starting point for collecting all the dependencies used in your web application.
This plugin does exactly what you want: automatically extracts JS, CSS, images, fonts from their sources loaded directly in HTML.
The generated HTML contains output hashed filenames of processed source files.
The purpose of this plugin is to make Webpack setup much easier and intuitiver than with other plugins like
`html-webpack-plugin` `mini-css-extract-plugin`.
💡 **Highlights**

@@ -33,3 +32,3 @@

- You can inline JS, CSS, SVG, images **without additional plugins and loaders**.
- You can use a template engine, e.g. [Nunjucks](https://mozilla.github.io/nunjucks/), [Handlebars](https://handlebarsjs.com) and others **without template loaders**
- You can use a template engine, e.g. [EJS](https://ejs.co), [Nunjucks](https://mozilla.github.io/nunjucks/), [Handlebars](https://handlebarsjs.com) and others **without template loaders**.
- This plugin works like the [pug-plugin](https://github.com/webdiscus/pug-plugin) but the entry point is a `HTML` template.

@@ -74,3 +73,3 @@

Add the HTML templates in the Webpack entry:
Add the HTML templates in the `entry` option (syntax is identical to [Webpack entry](https://webpack.js.org/configuration/entry-context/#entry)):

@@ -82,14 +81,14 @@ ```js

module.exports = {
entry: {
// define HTML templates here
index: './src/views/home/index.html', // output dist/index.html
},
resolve: {
alias: {
'@images': path.join(__dirname, './src/images'),
'@images': path.join(__dirname, 'src/images'),
},
},
plugins: [
// enable processing of HTML templates defined in Webpack entry
new HtmlBundlerPlugin(),
new HtmlBundlerPlugin({
entry: {
// define HTML templates here
index: 'src/views/home/index.html', // output dist/index.html
},
}),
],

@@ -111,7 +110,17 @@ module: {

---
1. [Install and Quick start](#install)
2. [Features](#features)
1. [Features](#features)
2. [Install and Quick start](#install)
3. [Plugin options](#plugin-options)
- [test](#option-test) (process only templates matching RegExp)
- [entry](#option-entry) (define HTML templates)
- [outputPath](#option-outputPath) (output path of HTML file)
- [filename](#option-filename) (output filename of HTML file)
- [css](#option-css) (output filename of extracted CSS)
- [js](#option-js) (output filename of extracted JS)
- [postprocess](#option-postprocess)
- [extractComments](#option-extractComments)
- [verbose](#option-verbose)
3. [Loader options](#loader-options)
- [sources](#loader-option-sources)
- [preprocessor](#loader-option-preprocessor) (for custom templates)
4. [Recipes](#recipes)

@@ -124,5 +133,4 @@ - [How to use source images in HTML](#recipe-use-images-in-html)

- [How to inline SVG, PNG images in HTML](#recipe-inline-image)
- [How to use a template engine, e.g. Handlebars](#recipe-template-engine)
- [How to pass data into template](#recipe-pass-data)
- [How to pass different data by multipage configuration](#recipe-pass-data-multipage)
- [How to use a template engine](#recipe-template-engine)
- [How to pass data into templates](#recipe-pass-data-to-templates)
- [How to use HMR live reload](#recipe-hmr)

@@ -133,4 +141,3 @@

- HTML file is the entry point for all resources (styles, scripts)
- handels HTML files defined in Webpack entry
- HTML template is the entry point for all resources (styles, scripts)
- extracts CSS from source style loaded in HTML via a `<link>` tag

@@ -189,11 +196,10 @@ - extracts JS from source script loaded in HTML via a `<script>` tag

entry: {
// define HTML files here
index: './src/views/home/index.html', // output dist/index.html
'pages/about': './src/views/about/index.html', // output dist/pages/about.html
// ...
},
plugins: [
new HtmlBundlerPlugin({
entry: {
// define HTML files here
index: 'src/views/home/index.html', // output dist/index.html
'pages/about': 'src/views/about/index.html', // output dist/pages/about.html
// ...
},
js: {

@@ -225,2 +231,8 @@ // output filename of extracted JS from source script loaded in HTML via `<script>` tag

> **Note**
>
> Since the version `0.9.0`, you can define HTML templates in the `entry` option of the plugin.
> If is used the `entry` option of the plugin, then the origin Webpack `entry` option should be undefined.
---

@@ -231,6 +243,3 @@

### `verbose`
Type: `boolean` Default: `false`<br>
Display information about extracted files.
<a id="option-test" name="option-test" href="#option-test"></a>
### `test`

@@ -242,3 +251,65 @@ Type: `RegExp` Default: `/\.html$/`<br>

<a id="plugin-option-outputPath" name="plugin-option-outputPath" href="#plugin-option-outputPath"></a>
<a id="option-entry" name="option-entry" href="#option-entry"></a>
### `entry`
Type: `object` is identical to [Webpack entry](https://webpack.js.org/configuration/entry-context/#entry)
plus additional `data` property.
Define your HTML files or templates in the entry option.
HTML is a starting point for collecting all the dependencies used in your web application.
Specify source scripts (JS, TS) and styles (CSS, SCSS, etc.) directly in HTML.
The plugin automatically extracts JS, CSS from their sources specified in HTML.
#### Simple syntax
The key of an entry object is the `output file` w/o extension, relative by the [`outputPath`](#option-outputPath) option.\
The value is the `source file`, absolute or relative by the Webpack config file.
```js
{
entry: {
index: 'src/views/home/index.html', // => dist/index.html
'pages/about/index': 'src/views/about.html', // => dist/pages/about/index.html
},
}
```
#### Advanced syntax
The entry value might be an object:
```ts
type entryValue = {
import: string,
filename: string
data: object,
}
```
- `import` - a source file, absolute or relative by the Webpack config file
- `filename` - an output file, relative by the 'outputPath' option
- `data` - an object with variables passed into [`preprocessor`](#loader-option-preprocessor) to render a template
Usage example:
```js
{
entry: {
'pages/about/index': { // output file as the key
import: 'src/views/about.html', // source template file
data: {
title: 'About',
}
},
contact: {
import: 'src/views/contact.html',
filename: 'pages/contact/index.html', // output file as the 'filename' property
},
},
}
```
<a id="option-outputPath" name="option-outputPath" href="#option-outputPath"></a>
### `outputPath`

@@ -248,6 +319,8 @@ Type: `string` Default: `webpack.options.output.path`<br>

<a id="plugin-option-filename" name="plugin-option-filename" href="#plugin-option-filename"></a>
<a id="option-filename" name="option-filename" href="#option-filename"></a>
### `filename`
Type: `string | Function` Default: `[name].html`<br>
The name of output file.
The output filename relative by the [`outputPath`](#option-outputPath) option.
- If type is `string` then following substitutions (see [output.filename](https://webpack.js.org/configuration/output/#template-strings) for chunk-level) are available in template string:

@@ -265,2 +338,4 @@ - `[id]` The ID of the chunk.

<a id="option-css" name="option-css" href="#option-css"></a>
### `css`

@@ -272,11 +347,14 @@ Type: `Object`\

test: /\.(css|scss|sass|less|styl)$/,
verbose: false,
filename: '[name].css',
outputPath: null,
verbose: false,
}
```
The `filename` property see by [filename option](#plugin-option-filename).
The `outputPath` property see by [outputPath option](#plugin-option-outputPath).
The option to extract CSS from a style source file loaded in the HTML tag:
- `test` - an RegEpx to process all source styles that pass test assertion
- `filename` - an output filename of extracted CSS. Details see by [filename option](#option-filename).\
- `outputPath` - an output path of extracted CSS. Details see by [outputPath option](#option-outputPath).
- `verbose` - enable/disable display process information for styles
This is the option to extract CSS from a style source file specified in the HTML tag:
```html

@@ -288,3 +366,3 @@ <link href="./style.scss" rel="stylesheet">

>
> Don't import source styles in JavaScript! Styles must be loaded directly in HTML.
> Don't import source styles in JavaScript! Styles must be specified directly in HTML.

@@ -316,2 +394,4 @@ The default CSS output filename is `[name].css`.

<a id="option-js" name="option-js" href="#option-js"></a>
### `js`

@@ -322,12 +402,15 @@ Type: `Object`\

{
verbose: false,
filename: '[name].js',
outputPath: null,
verbose: false,
}
```
The `filename` property see by [filename option](#plugin-option-filename).
The `outputPath` property see by [outputPath option](#plugin-option-outputPath).
The `test` property not exist because all JS files loaded in `<script>` tag are automatically detected.
The option to extract JS from a script source file loaded in the HTML tag:
- `filename` - an output filename of extracted JS. Details see by [filename option](#option-filename).\
- `outputPath` - an output path of extracted CSS. Details see by [outputPath option](#option-outputPath).
- `verbose` - enable/disable display process information for styles
The `test` property absent because all JS files specified in `<script>` tag are automatically detected.
This is the option to extract JS from a script source file specified in the HTML tag:
```html

@@ -357,22 +440,4 @@ <script src="./main.js"></script>

### `extractComments`
Type: `boolean` Default: `false`<br>
Enable / disable extraction of comments to `*.LICENSE.txt` file.
When using `splitChunks` optimization for node modules containing comments,
Webpack extracts those comments into a separate text file.
By default, the plugin don't create such unwanted text files.
But if you want to extract files like `*.LICENSE.txt`, set this option to `true`:
```js
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
plugins: [
new HtmlBundlerPlugin({
extractComments: true,
}),
],
};
```
<a id="option-postprocess" name="option-postprocess" href="#option-postprocess"></a>
### `postprocess`

@@ -420,2 +485,30 @@ Type:

<a id="option-extractComments" name="option-extractComments" href="#option-extractComments"></a>
### `extractComments`
Type: `boolean` Default: `false`<br>
Enable / disable extraction of comments to `*.LICENSE.txt` file.
When using `splitChunks` optimization for node modules containing comments,
Webpack extracts those comments into a separate text file.
By default, the plugin don't create such unwanted text files.
But if you want to extract files like `*.LICENSE.txt`, set this option to `true`:
```js
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
plugins: [
new HtmlBundlerPlugin({
extractComments: true,
}),
],
};
```
<a id="option-verbose" name="option-verbose" href="#option-verbose"></a>
### `verbose`
Type: `boolean` Default: `false`<br>
Display information about all processed files.
---

@@ -426,2 +519,3 @@

<a id="loader-option-sources" name="loader-option-sources" href="#loader-option-sources"></a>
### `sources`

@@ -605,2 +699,4 @@ Type:

<a id="loader-option-preprocessor" name="loader-option-preprocessor" href="#loader-option-preprocessor"></a>
### `preprocessor`

@@ -623,10 +719,11 @@ Type:

- `resourcePath: string` - a template file
- `data: object|null` - variables passed form [`entry`](#option-entry)
Complete API see by the [Loader Context](https://webpack.js.org/api/loaders/#the-loader-context).
The preprocessor is called before handling of the content.
This function can be used to replace a placeholder with a variable or compile the content with a template engine,
such as [Handlebars](https://handlebarsjs.com), [Nunjucks](https://mozilla.github.io/nunjucks).
The preprocessor is called for each entry file, before handling of the content.
This function can be used to compile the template with a template engine,
such as [EJS](https://ejs.co), [Handlebars](https://handlebarsjs.com), [Nunjucks](https://mozilla.github.io/nunjucks), etc.
For example, set variable in the template
For example, set a variable in the template
_index.html_

@@ -653,8 +750,15 @@ ```html

entry: {
index: './src/index.html',
},
plugins: [
new HtmlBundlerPlugin({
entry: {
index: { // => dist/index.html
import: './src/views/index.html',
data: {
title: 'Homepage',
}
},
},
}),
],
plugins: [new HtmlBundlerPlugin()],
module: {

@@ -666,3 +770,6 @@ rules: [

options: {
preprocessor: (content, loaderContext) => content.replace('{{ title }}', 'Homepage'),
preprocessor: (content, { data }) => {
// you can use here a template engine like EJS, Handlebars, Nunjucks, etc
return content.replace('{{ title }}', data.title);
},
},

@@ -676,9 +783,3 @@ },

> **Note**
>
> Using the `preprocessor` you can use anyone template engine without its loader.
>
> The `preprocessor` will be called for each entry file.
> For multipage configuration, you can use the `loaderContext.resourcePath` property to differentiate data for diverse pages.
> See the [usage example](#recipe-pass-data-multipage).
See the example [How to use a template engine](#recipe-template-engine).

@@ -956,3 +1057,3 @@ ---

You can inline images in two ways:
You can inline the images in two ways:
- force inline image using `?inline` query

@@ -994,2 +1095,12 @@ - auto inline by image size

Using the [preprocessor](#loader-option-preprocessor) you can compile the template with a template engine such as:
- [EJS](https://ejs.co),
- [Handlebars](https://handlebarsjs.com)
- [Nunjucks](https://mozilla.github.io/nunjucks/),
> **Note**
>
> For Pug templates use the [pug-plugin](https://github.com/webdiscus/pug-plugin).
> This plugin works on the same codebase but has additional Pug-specific features.
For example, using the Handlebars templating engine, there is an

@@ -1011,3 +1122,3 @@ _index.hbs_

Add the `preprocessor` option to compile the content with Handlebars.
Add the `preprocessor` option to compile the template.

@@ -1024,9 +1135,18 @@ ```js

entry: {
index: './src/views/home/index.hbs',
},
plugins: [
new HtmlBundlerPlugin({
test: /\.(html|hbs)$/, // add the option to match *.hbs files in entry, default is /\.html$/
entry: {
index: {
import: './src/views/home/index.hbs',
// pass data into the preprocessor
data: {
title: 'My Title',
headline: 'Breaking Bad',
firstname: 'Walter',
lastname: 'Heisenberg',
},
},
},
}),

@@ -1042,10 +1162,3 @@ ],

// add the preprocessor function to compile *.hbs files to HTML
// you can pass data here to all templates
preprocessor: (content, loaderContext) =>
Handlebars.compile(content)({
title: 'My Title',
headline: 'Breaking Bad',
firstname: 'Walter',
lastname: 'Heisenberg',
}),
preprocessor: (content, { data }) => Handlebars.compile(content)(data),
},

@@ -1059,13 +1172,9 @@ },

<a id="recipe-pass-data" name="recipe-pass-data" href="#recipe-pass-data"></a>
## How to pass data into template
You can pass variables into template using a lightweight template engine, e.g. [Handlebars](https://handlebarsjs.com).
See the usage example by [How to use a template engine](#recipe-template-engine) or [How to pass different data by multipage configuration](#recipe-pass-data-multipage).
<a id="recipe-pass-data-to-templates" name="recipe-pass-data-to-templates" href="#recipe-pass-data-to-templates"></a>
## How to pass data into templates
<a id="recipe-pass-data-multipage" name="recipe-pass-data-multipage" href="#recipe-pass-data-multipage"></a>
## How to pass different data by multipage configuration
You can pass variables into template using a template engine, e.g. [Handlebars](https://handlebarsjs.com).
For multiple page configuration, better to use the [Nunjucks](https://mozilla.github.io/nunjucks) templating engine maintained by Mozilla.
For multipage configuration, better to use the [Nunjucks](https://mozilla.github.io/nunjucks) templating engine maintained by Mozilla.
For example, you have several pages with variables.\

@@ -1097,2 +1206,3 @@ Both pages have the same layout _src/views/layouts/default.html_

{% block styles %}
<!-- load source style -->
<link href="./home.scss" rel="stylesheet">

@@ -1102,2 +1212,3 @@ {% endblock %}

{% block scripts %}
<!-- load source script -->
<script src="./home.js" defer="defer"></script>

@@ -1142,19 +1253,8 @@ {% endblock %}

/**
* Find template data by template file.
*
* @param {string} sourceFile
* @param {Object} data
* @return {Object}
*/
const findData = (sourceFile, data) => {
for (const [key, value] of Object.entries(data)) {
if (sourceFile.endsWith(key)) return value;
}
return {};
};
// note: data keys are different endings of source template files defined in entry
// Note:
// If your pages have a lot of variables, it's a good idea to define them separately
// to keep the configuration clean and clear.
const entryData = {
'home/index.html': {
// variables for home page
home: {
title: 'Home',

@@ -1165,3 +1265,4 @@ filmTitle: 'Breaking Bad',

},
'about/index.html': {
// variables for about page
about: {
title: 'About',

@@ -1185,7 +1286,2 @@ actors: [

},
entry: {
// define your templates here
index: 'src/views/pages/home/index.html', // => dist/index.html
about: 'src/views/pages/about/index.html', // => dist/about.html
},
resolve: {

@@ -1198,2 +1294,13 @@ alias: {

new HtmlBundlerPlugin({
entry: {
// define your templates here
index: { // => dist/index.html
import: 'src/views/pages/home/index.html',
data: entryData.home,
},
about: { // => dist/about.html
import: 'src/views/pages/about/index.html',
data: entryData.about,
},
},
js: {

@@ -1214,6 +1321,4 @@ filename: 'assets/js/[name].[contenthash:8].js',

options: {
preprocessor: (content, { resourcePath }) => {
// get template variables by template filename
const data = findData(resourcePath, entryData);
// render template with specific variables
preprocessor: (content, { data }) => {
// render template with page-specific variables defined in entry
return Nunjucks.renderString(content, data);

@@ -1220,0 +1325,0 @@ },

const vm = require('vm');
const path = require('path');
const NormalModule = require('webpack/lib/NormalModule');
const JavascriptParser = require('webpack/lib/javascript/JavascriptParser');

@@ -141,3 +142,4 @@ const JavascriptGenerator = require('webpack/lib/javascript/JavascriptGenerator');

// the id to bind loader with data passed into template via entry.data
entryDataId;
entryDataIndex;
entryDataCache = new Map();

@@ -191,6 +193,44 @@ // webpack's options and modules

/**
* Reset all initial values.
* Entries defined in plugin options are merged with Webpack entry option.
*
* @param {{}} options The Webpack options where entry contains additional 'data' property.
*/
initializeWebpackEntry(options) {
let { entry } = options;
const pluginEntry = this.options.entry;
// check whether the entry in config is empty, defaults Webpack set structure: `{ main: {} }`,
if (Object.keys(entry).length === 1 && Object.keys(Object.entries(entry)[0][1]).length === 0) {
// set empty entry to avoid Webpack error
entry = {};
}
if (pluginEntry) {
for (const key in pluginEntry) {
const entry = pluginEntry[key];
if (entry.import == null) {
pluginEntry[key] = { import: [entry] };
continue;
}
if (!Array.isArray(entry.import)) {
entry.import = [entry.import];
}
}
options.entry = { ...entry, ...pluginEntry };
// the 'layer' entry property is only allowed when 'experiments.layers' is enabled
options.experiments.layers = true;
}
}
/**
* Reset initial values.
*/
reset() {
this.entryDataId = 1;
// TODO: test hmr
this.entryDataIndex = 1;
this.entryDataCache.clear();
}

@@ -220,33 +260,2 @@

/**
* @param {{}} options The Webpack options where entry contains additional 'data' property.
*/
initializeWebpackEntry(options) {
let { entry } = options;
const pluginEntries = this.options.entry;
// check whether the entry in config is empty, defaults Webpack set structure: `{ main: {} }`,
if (Object.keys(entry).length === 1 && Object.keys(Object.entries(entry)[0][1]).length === 0) {
// reset entry
entry = {};
}
if (pluginEntries) {
for (const key in pluginEntries) {
const entry = pluginEntries[key];
if (entry['import'] == null) {
pluginEntries[key] = { import: [entry] };
continue;
}
if (!Array.isArray(entry.import)) {
entry.import = [entry.import];
}
}
options.entry = { ...entry, ...pluginEntries };
}
}
/**
* Apply plugin.

@@ -356,2 +365,16 @@ * @param {{}} compiler

// called after the module hook but right before the execution of a loader
NormalModule.getCompilationHooks(compilation).loader.tap(pluginName, (loaderContext, module) => {
if (typeof module.layer === 'string' && module.layer.startsWith('__entryDataId')) {
const [, entryDataId] = module.layer.split('=', 2);
loaderContext.entryData = this.entryDataCache.get(entryDataId);
loaderContext.data = this.entryDataCache.get(entryDataId);
}
// [RESERVED FALLBACK] if the experimental 'layer' option will be changed or removed in next Webpack version.
// if (module.__entryDataId) {
// loaderContext.entryData = this.entryDataCache.get(module.__entryDataId);
// }
});
// render source code of modules

@@ -428,6 +451,20 @@ compilation.hooks.renderManifest.tap(pluginName, this.renderManifest);

if (entry.data) {
entry.entryDataId = `${this.entryDataId}`;
entry.import[0] += importFile.indexOf('?') < 0 ? '?' : '&';
entry.import[0] += `__entryDataId=${this.entryDataId}`;
this.entryDataId++;
// IMPORTANT: when the entry contains same source file for many chunks, for example:
// {
// page1: { import: 'src/template.html', data: { title: 'A'} },
// page2: { import: 'src/template.html', data: { title: 'B'} },
// }
// add an unique identifier of the entry to execute a loader for all templates,
// otherwise Webpack call a loader only for the first template.
// See 'webpack/lib/NormalModule.js:identifier()'.
entry.layer = `__entryDataId=${this.entryDataIndex}`;
// [RESERVED FALLBACK] if the experimental 'layer' option will be changed or removed in next Webpack version.
// specify the entry data id as a query param
//entry.import[0] += importFile.indexOf('?') < 0 ? '?' : '&';
//entry.import[0] += `__entryDataId=${this.entryDataIndex}`;
this.entryDataCache.set(`${this.entryDataIndex}`, entry.data);
this.entryDataIndex++;
}

@@ -448,3 +485,30 @@

const { issuer } = contextInfo;
const [resourceFile] = request.split('?', 2);
// [RESERVED FALLBACK] if the experimental 'layer' option will be changed or removed in next Webpack version.
// Resolve the entry data id from the resource query added in the 'entryOption' hook
// to generate unique identifier of the module.
// It is ultra important when the entry contains same source file for many chunks.
// For example:
// { page1: 'src/template.html', page2: 'src/template.html' }
// const [, resourceQuery] = request.split('?', 2);
// if (resourceQuery) {
// const params = new URLSearchParams(resourceQuery);
// let queryString = '';
//
// if (params.has('__entryDataId')) {
// resolveData.__entryDataId = params.get('__entryDataId');
// // note: don't remove this param, because it serves for unique identifier of the module
// // when used entry data and the entry contains same source file for many chunks
// // remove the temporary private param from request
// //params.delete('__entryDataId');
// //params.forEach((value, key) => {
// // queryString += queryString ? '&' : '?';
// // queryString += value ? `${key}=${value}` : `${key}`;
// //});
// // recovery the original request w/o temporary private param
// //resolveData.request = resourceFile + queryString;
// }
// }
// save requests to issuer cache

@@ -457,5 +521,4 @@ if (!issuer) issuerCache.add(request);

if (issuer && issuer.length > 0) {
const [requestFile] = request.split('?', 1);
const extractCss = this.options.extractCss;
if (extractCss.enabled && extractCss.test.test(issuer) && requestFile.endsWith('.js')) {
if (extractCss.enabled && extractCss.test.test(issuer) && resourceFile.endsWith('.js')) {
// ignore runtime scripts of a loader, because a style can't have a javascript dependency

@@ -514,4 +577,10 @@ return false;

const { rawRequest, resource } = createData;
const issuer = resolveData.contextInfo.issuer;
const { issuer } = resolveData.contextInfo;
// [RESERVED FALLBACK] if the experimental 'layer' option will be changed or removed in next Webpack version.
// pass a resolved entry data id into the module
// if (resolveData.__entryDataId) {
// module.__entryDataId = resolveData.__entryDataId;
// }
if (!issuer || AssetInline.isDataUrl(rawRequest)) return;

@@ -518,0 +587,0 @@

@@ -243,3 +243,2 @@ const path = require('path');

const RawSource = compilation.compiler.webpack.sources.RawSource;
const NL = '\n';

@@ -251,5 +250,5 @@ for (const assetFile of this.inlineSvgIssueAssets) {

const html = asset.source();
const headPos = html.indexOf('<head');
const headEndPos = html.indexOf('</head>');
const hasHead = headPos >= 0 && headEndPos > headPos;
const headStartPos = html.indexOf('<head');
const headEndPos = html.indexOf('</head>', headStartPos);
const hasHead = headStartPos >= 0 && headEndPos > headStartPos;
let results = [];

@@ -280,6 +279,5 @@

const attrsString = attrsToString(attrs, [...excludeAttrs, 'title']);
const [filename] = path.basename(value).split('?', 1);
const titleStr = 'title' in attrs ? attrs['title'] : 'alt' in attrs ? attrs['alt'] : null;
const title = titleStr ? `<title>${titleStr}</title>` : '';
const inlineSvg = `${NL}<!-- inline: ${filename} -->${NL}<svg${attrsString}>${title}${cache.innerSVG}</svg>${NL}`;
const inlineSvg = `<svg${attrsString}>${title}${cache.innerSVG}</svg>`;

@@ -286,0 +284,0 @@ output += html.slice(pos, tagStartPos) + inlineSvg;

@@ -11,23 +11,2 @@ const { merge } = require('webpack-merge');

/**
* @param {{}} entries
* @param {string} resourceQuery
* @return {{}|null}
*/
const findEntryData = (entries, resourceQuery) => {
const params = new URLSearchParams(resourceQuery);
const entryDataId = params.get('__entryDataId');
if (entryDataId) {
for (let key in entries) {
const entry = entries[key];
if (entry.entryDataId === entryDataId) {
return entry.data;
}
}
}
return null;
};
/**
* @param {string} content The HTML template.

@@ -106,5 +85,3 @@ * @param {function(error: Error|null, result: string?)?} callback The asynchronous callback function.

if (preprocessor !== null) {
const data = findEntryData(webpackOptions.entry, loaderContext.resourceQuery);
content = preprocessor(content, loaderContext, data);
content = preprocessor(content, loaderContext);
}

@@ -157,2 +134,11 @@ } catch (error) {

// note: the 'entryData' is the custom property defined in plugin
// set the origin 'data' property of loader context,
// see https://webpack.js.org/api/loaders/#thisdata
if (loaderContext.entryData != null) {
const loader = loaderContext.loaders[loaderContext.loaderIndex];
loader.data = loaderContext.entryData;
delete loaderContext.entryData;
}
compile.call(loaderContext, content, (error, result) => {

@@ -159,0 +145,0 @@ if (error) {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc