diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0caa1300..39d69f8b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node: ['10.x', '12.x', '14.x'] + node: ['10.x', '12.x', '14.x', '16.x', '18.x', '20.x'] os: [ubuntu-latest, windows-latest, macOS-latest] webpack: ['5'] diff --git a/CHANGELOG.md b/CHANGELOG.md index d75a79b0..2f9b39fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [5.5.3](https://github.com/jantimon/html-webpack-plugin/compare/v5.5.2...v5.5.3) (2023-06-10) + + +### Bug Fixes + +* don't add extra meta tag if it exists ([#1802](https://github.com/jantimon/html-webpack-plugin/issues/1802)) ([8f92788](https://github.com/jantimon/html-webpack-plugin/commit/8f927889a3a98d06472b662135954457385cc926)) +* pass all Node.js globals to templates ([#1796](https://github.com/jantimon/html-webpack-plugin/issues/1796)) ([f269fc0](https://github.com/jantimon/html-webpack-plugin/commit/f269fc01fe619c5a98388017770040dae6263928)) +* **types:** fix type for `chunkSortMode` ([#1798](https://github.com/jantimon/html-webpack-plugin/issues/1798)) ([6ad0e55](https://github.com/jantimon/html-webpack-plugin/commit/6ad0e556276da22b17747b15eb0e52bb9aa77c75)) + ### [5.5.2](https://github.com/jantimon/html-webpack-plugin/compare/v5.5.1...v5.5.2) (2023-06-08) @@ -70,7 +79,7 @@ All notable changes to this project will be documented in this file. See [standa ### ⚠ BREAKING CHANGES * Drop support for `webpack` 4 and `node` <= 10 - For older webpack or node versions please use `html-webpack-plugin` 4.x -* Entry javascript resources are now beeing loaded deferred in the `` tag to improve the page load performance by default - You can set the `scriptLoading` option to `'blocking'` to keep the previous behaviour +* Entry javascript resources are now being loaded deferred in the `` tag to improve the page load performance by default - You can set the `scriptLoading` option to `'blocking'` to keep the previous behaviour * Setting publicPath to `''` (an empty string) will no longer calculate a relative path from the html file to the assets anymore - You can set the `publicPath` option to `'auto'` to keep the previous behaviour * Plugins for `html-webpack-plugin` which add additional assetTags should provide a `meta` attribute * Drop support for `appcache-webpack-plugin` @@ -99,6 +108,13 @@ clean-webpack-plugin ([6b3d087](https://github.com/jantimon/html-webpack-plugin/ * generate html files even if no webpack entry exists ([2693dfa](https://github.com/jantimon/html-webpack-plugin/commit/2693dfaf4c94625eab86afadfd0e4d8822092d6b)) * keep binary format when adding assets ([7e2b208](https://github.com/jantimon/html-webpack-plugin/commit/7e2b208634e26299c509e0c6b3189e01e4c3d3df)), closes [#1537](https://github.com/jantimon/html-webpack-plugin/issues/1537) +## [4.5.2](https://github.com/jantimon/html-webpack-plugin/compare/v4.5.1...v4.5.2) (2021-02-18) + + +### Bug Fixes + +* more robust variable value extraction to add support for webpack >= 5.22.0 ([1aabaf9](https://github.com/jantimon/html-webpack-plugin/commit/1aabaf99820257cbe7d3efccb62b42254ad35e04)) + ### [4.5.1](https://github.com/jantimon/html-webpack-plugin/compare/v4.5.0...v4.5.1) (2021-01-03) diff --git a/README.md b/README.md index a7fd28a5..7797f5cd 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ [![npm][npm]][npm-url] [![node][node]][node-url] ![npm](https://img.shields.io/npm/dw/html-webpack-plugin.svg) -[![deps][deps]][deps-url] [![tests][tests]][tests-url] [![Backers on Open Collective](https://opencollective.com/html-webpack-plugin/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/html-webpack-plugin/sponsors/badge.svg)](#sponsors)
- + @@ -90,6 +89,7 @@ The `html-webpack-plugin` provides [hooks](https://github.com/jantimon/html-webp * [html-webpack-skip-assets-plugin](https://github.com/swimmadude66/html-webpack-skip-assets-plugin) Skip adding certain output files to the html file. Built as a drop-in replacement for [html-webpack-exclude-assets-plugin](https://www.npmjs.com/package/html-webpack-exclude-assets-plugin) and works with newer [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) versions * [html-webpack-inject-preload](https://github.com/principalstudio/html-webpack-inject-preload) allows to add preload links <link rel='preload'> anywhere you want. * [inject-body-webpack-plugin](https://github.com/Jaid/inject-body-webpack-plugin) is a simple method of injecting a custom HTML string into the body. + * [html-webpack-plugin-django](https://github.com/TommasoAmici/html-webpack-plugin-django) a Webpack plugin to inject Django static tags.

Usage

@@ -661,8 +661,5 @@ This project uses the [semistandard code style](https://github.com/Flet/semistan [node]: https://img.shields.io/node/v/html-webpack-plugin.svg [node-url]: https://nodejs.org -[deps]: https://david-dm.org/jantimon/html-webpack-plugin.svg -[deps-url]: https://david-dm.org/jantimon/html-webpack-plugin - [tests]: https://github.com/jantimon/html-webpack-plugin/workflows/CI/badge.svg [tests-url]: https://github.com/jantimon/html-webpack-plugin/actions?query=workflow%3ACI diff --git a/index.js b/index.js index de9a6294..4452f636 100644 --- a/index.js +++ b/index.js @@ -76,7 +76,8 @@ class HtmlWebpackPlugin { // Default metaOptions if no template is provided if (!userOptions.template && options.templateContent === false && options.meta) { const defaultMeta = { - // From https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag + // TODO remove in the next major release + // From https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag viewport: 'width=device-width, initial-scale=1' }; options.meta = Object.assign({}, options.meta, defaultMeta, userOptions.meta); @@ -132,8 +133,56 @@ class HtmlWebpackPlugin { HTML_WEBPACK_PLUGIN: true, require: require, htmlWebpackPluginPublicPath: publicPath, - URL: require('url').URL, - __filename: templateWithoutLoaders + __filename: templateWithoutLoaders, + __dirname: path.dirname(templateWithoutLoaders), + AbortController: global.AbortController, + AbortSignal: global.AbortSignal, + Blob: global.Blob, + Buffer: global.Buffer, + ByteLengthQueuingStrategy: global.ByteLengthQueuingStrategy, + BroadcastChannel: global.BroadcastChannel, + CompressionStream: global.CompressionStream, + CountQueuingStrategy: global.CountQueuingStrategy, + Crypto: global.Crypto, + CryptoKey: global.CryptoKey, + CustomEvent: global.CustomEvent, + DecompressionStream: global.DecompressionStream, + Event: global.Event, + EventTarget: global.EventTarget, + File: global.File, + FormData: global.FormData, + Headers: global.Headers, + MessageChannel: global.MessageChannel, + MessageEvent: global.MessageEvent, + MessagePort: global.MessagePort, + PerformanceEntry: global.PerformanceEntry, + PerformanceMark: global.PerformanceMark, + PerformanceMeasure: global.PerformanceMeasure, + PerformanceObserver: global.PerformanceObserver, + PerformanceObserverEntryList: global.PerformanceObserverEntryList, + PerformanceResourceTiming: global.PerformanceResourceTiming, + ReadableByteStreamController: global.ReadableByteStreamController, + ReadableStream: global.ReadableStream, + ReadableStreamBYOBReader: global.ReadableStreamBYOBReader, + ReadableStreamBYOBRequest: global.ReadableStreamBYOBRequest, + ReadableStreamDefaultController: global.ReadableStreamDefaultController, + ReadableStreamDefaultReader: global.ReadableStreamDefaultReader, + Response: global.Response, + Request: global.Request, + SubtleCrypto: global.SubtleCrypto, + DOMException: global.DOMException, + TextDecoder: global.TextDecoder, + TextDecoderStream: global.TextDecoderStream, + TextEncoder: global.TextEncoder, + TextEncoderStream: global.TextEncoderStream, + TransformStream: global.TransformStream, + TransformStreamDefaultController: global.TransformStreamDefaultController, + URL: global.URL, + URLSearchParams: global.URLSearchParams, + WebAssembly: global.WebAssembly, + WritableStream: global.WritableStream, + WritableStreamDefaultController: global.WritableStreamDefaultController, + WritableStreamDefaultWriter: global.WritableStreamDefaultWriter }); const vmScript = new vm.Script(source, { filename: templateWithoutLoaders }); // Evaluate code and cast to string @@ -664,10 +713,7 @@ function hookIntoCompiler (compiler, options, plugin) { const entryPointUnfilteredFiles = compilation.entrypoints.get(entryName).getFiles(); const entryPointFiles = entryPointUnfilteredFiles.filter((chunkFile) => { - // compilation.getAsset was introduced in webpack 4.4.0 - // once the support pre webpack 4.4.0 is dropped please - // remove the following guard: - const asset = compilation.getAsset && compilation.getAsset(chunkFile); + const asset = compilation.getAsset(chunkFile); if (!asset) { return true; } @@ -921,8 +967,15 @@ function hookIntoCompiler (compiler, options, plugin) { const htmlRegExp = /(]*>)/i; const headRegExp = /(<\/head\s*>)/i; const bodyRegExp = /(<\/body\s*>)/i; + const metaViewportRegExp = /]+name=["']viewport["'][^>]*>/i; const body = assetTags.bodyTags.map((assetTagObject) => htmlTagObjectToString(assetTagObject, options.xhtml)); - const head = assetTags.headTags.map((assetTagObject) => htmlTagObjectToString(assetTagObject, options.xhtml)); + const head = assetTags.headTags.filter((item) => { + if (item.tagName === 'meta' && item.attributes && item.attributes.name === 'viewport' && metaViewportRegExp.test(html)) { + return false; + } + + return true; + }).map((assetTagObject) => htmlTagObjectToString(assetTagObject, options.xhtml)); if (body.length) { if (bodyRegExp.test(html)) { diff --git a/package.json b/package.json index 360b2f32..e89e1a63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "html-webpack-plugin", - "version": "5.5.2", + "version": "5.5.3", "license": "MIT", "description": "Simplifies creation of HTML files to serve your webpack bundles", "author": "Jan Nicklas (https://github.com/jantimon)", @@ -28,7 +28,7 @@ ] }, "devDependencies": { - "@types/node": "11.13.9", + "@types/node": "^20.2.5", "commitizen": "^4.2.4", "css-loader": "5.0.1", "cz-conventional-changelog": "2.1.0", diff --git a/spec/basic.spec.js b/spec/basic.spec.js index b325f7cd..8c725fd9 100644 --- a/spec/basic.spec.js +++ b/spec/basic.spec.js @@ -1958,6 +1958,21 @@ describe('HtmlWebpackPlugin', () => { }, [//], null, done); }); + it('avoid duplicate meta tags for default template', done => { + testHtmlPlugin({ + mode: 'production', + entry: path.join(__dirname, 'fixtures/index.js'), + context: path.join(__dirname, 'fixtures'), + output: { + path: OUTPUT_DIR, + filename: 'index_bundle.js' + }, + plugins: [ + new HtmlWebpackPlugin() + ] + }, [/src\/index\.ejs<\/title><script defer="defer" src="index_bundle.js"><\/script><\/head>/], null, done); + }); + it('adds a meta tag with short notation', done => { testHtmlPlugin({ mode: 'production', @@ -2302,6 +2317,23 @@ describe('HtmlWebpackPlugin', () => { }, ['templateParams keys: "compilation,webpackConfig,htmlWebpackPlugin"'], null, done); }); + it('should add the webpack compilation object as a property of the templateParam object with cjs', done => { + testHtmlPlugin({ + mode: 'production', + entry: path.join(__dirname, 'fixtures/index.js'), + output: { + path: OUTPUT_DIR, + filename: 'index_bundle.js' + }, + plugins: [ + new HtmlWebpackPlugin({ + template: path.join(__dirname, 'fixtures/templateParam.cjs'), + inject: false + }) + ] + }, ['templateParams keys: "compilation,webpackConfig,htmlWebpackPlugin"'], null, done); + }); + it('should allow to disable template parameters', done => { testHtmlPlugin({ mode: 'production', diff --git a/spec/fixtures/src/index.ejs b/spec/fixtures/src/index.ejs index 3887cb1b..599e7bcd 100644 --- a/spec/fixtures/src/index.ejs +++ b/spec/fixtures/src/index.ejs @@ -2,6 +2,7 @@ <html> <head> <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover"> <title>src/index.ejs diff --git a/spec/fixtures/templateParam.cjs b/spec/fixtures/templateParam.cjs new file mode 100644 index 00000000..32135ecb --- /dev/null +++ b/spec/fixtures/templateParam.cjs @@ -0,0 +1,21 @@ +module.exports = function (templateParams) { + const version = parseInt(process.version.match(/^v(\d+)/)[1]); + + if (typeof URL !== 'function') { + throw new Error('Error'); + } + + if (typeof URLSearchParams !== 'function') { + throw new Error('Error'); + } + + if (version >= 11 && typeof TextEncoder !== 'function') { + throw new Error('Error'); + } + + if (version >= 11 && typeof TextDecoder !== 'function') { + throw new Error('Error'); + } + + return 'templateParams keys: "' + Object.keys(templateParams).join(',') + '"'; +}; diff --git a/spec/fixtures/templateParam.js b/spec/fixtures/templateParam.js index 6580c457..32135ecb 100644 --- a/spec/fixtures/templateParam.js +++ b/spec/fixtures/templateParam.js @@ -1,3 +1,21 @@ module.exports = function (templateParams) { + const version = parseInt(process.version.match(/^v(\d+)/)[1]); + + if (typeof URL !== 'function') { + throw new Error('Error'); + } + + if (typeof URLSearchParams !== 'function') { + throw new Error('Error'); + } + + if (version >= 11 && typeof TextEncoder !== 'function') { + throw new Error('Error'); + } + + if (version >= 11 && typeof TextDecoder !== 'function') { + throw new Error('Error'); + } + return 'templateParams keys: "' + Object.keys(templateParams).join(',') + '"'; }; diff --git a/typings.d.ts b/typings.d.ts index b07bc354..8440fe8e 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -52,6 +52,8 @@ declare namespace HtmlWebpackPlugin { */ chunksSortMode?: | "auto" + // `none` is deprecated and an alias for `auto` now. + | "none" | "manual" | ((entryNameA: string, entryNameB: string) => number); /**