Skip to content

Commit 89d8b15

Browse files
committed
Merge branch 'develop'
2 parents fe7a33c + df1cf02 commit 89d8b15

File tree

15 files changed

+376
-186
lines changed

15 files changed

+376
-186
lines changed

.eslintrc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
}],
3333
"import/extensions": ["error", {
3434
"js": "never",
35-
"ts": "never",
36-
}]
35+
"ts": "never"
36+
}],
37+
"class-methods-use-this": "off"
3738
},
3839
"overrides": [
3940
{
@@ -51,15 +52,15 @@
5152
"airbnb-base",
5253
"plugin:jest/recommended",
5354
"plugin:@typescript-eslint/eslint-recommended",
54-
"plugin:@typescript-eslint/recommended",
55+
"plugin:@typescript-eslint/recommended"
5556
],
5657
"env": { "node": true },
5758
"rules": {
5859
"@typescript-eslint/no-var-requires": ["off"],
5960
"no-console": ["off"],
6061
"import/extensions": ["error", {
6162
"js": "never",
62-
"ts": "never",
63+
"ts": "never"
6364
}]
6465
}
6566
}

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ on:
1313
jobs:
1414
test:
1515
name: Test
16-
runs-on: ubuntu-latest
1716
strategy:
1817
matrix:
19-
node-version: [14.x, 16.x, 18.x]
18+
node-version: [14.x, 16.x, 18.x, 20.x]
19+
os: [ubuntu-latest, windows-latest, macos-latest]
20+
runs-on: ${{ matrix.os }}
2021
env:
2122
HUSKY: 0
2223
steps:
@@ -28,6 +29,7 @@ jobs:
2829
node-version: ${{ matrix.node-version }}
2930
- name: Get yarn cache directory path
3031
id: yarn-cache-dir-path
32+
shell: bash
3133
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
3234
- name: Restore yarn cache
3335
uses: actions/cache@v3

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ yarn.lock
1515
.husky
1616
/scripts
1717
jest.config.js
18+
docs

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ module.exports = {
129129
};
130130
```
131131

132+
## Known limitations
133+
1. This plugin does not transform Web Worker syntax like `new Worker(new URL('./worker.js', import.meta.url));``. It simply embeds the source code processed by webpack into HTML files, and emits any JavaScript files that is not processed by the plugin.
134+
2. This plugin is designed to embed script content into HTML files for deployment to environments where only a single file can be uploaded, or where the script file itself is small enough that it doesn't warrant an additional HTTP request. It is not intended for use in development, and may fail if HMR is enabled.
135+
132136
## Contributors
133137

134138
Thanks goes to these wonderful people:
@@ -145,7 +149,7 @@ Thanks goes to these wonderful people:
145149
</td>
146150
<td align="center" valign="top" width="20%">
147151
<a href="https://github.com/SorsOps">
148-
<img src="https://avatars.githubusercontent.com/u/80043879?s=120&v=4" width="60px;" alt="@kmalakoff"/>
152+
<img src="https://avatars.githubusercontent.com/u/80043879?s=120&v=4" width="60px;" alt="@SorsOps"/>
149153
<br />
150154
<b>@SorsOps</b>
151155
</a>

__tests__/HtmlInlineScriptPlugin.test.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import preserveConfig from './cases/preserveAsset/webpack.config';
99
import multipleInstanceConfig from './cases/multiple-instance/webpack.config';
1010
import jsWithImportConfig from './cases/js-with-import/webpack.config';
1111
import webWorkerConfig from './cases/web-worker/webpack.config';
12-
import inlineWebWorkerConfig from './cases/inline-web-worker/webpack.config';
1312
import ignoreScriptsConfig from './cases/ignore-scripts/webpack.config';
1413
import ignoreHtmlsConfig from './cases/ignore-htmls/webpack.config';
1514
import ignoreScriptsAndHtmlsConfig from './cases/ignore-scripts-and-htmls/webpack.config';
1615
import filenameWithSpecialCharactersConfig from './cases/filename-with-special-characters/webpack.config';
1716
import escapeScriptTagEndConfig from './cases/escape-script-end-tag/webpack.config';
17+
import htmlInsideSubfolderConfig from './cases/html-inside-subfolder/webpack.config';
1818

1919
describe('HtmlInlineScriptPlugin', () => {
2020
it('should build simple webpack config without error', async () => {
@@ -206,31 +206,34 @@ describe('HtmlInlineScriptPlugin', () => {
206206
await webpackPromise;
207207
});
208208

209-
it('should build webpack config having inline web worker without error', async () => {
209+
it('should build webpack config that outputs html file inside subfolder without error', async () => {
210210
const webpackPromise = new Promise((resolve) => {
211-
const compiler = webpack(inlineWebWorkerConfig);
211+
const compiler = webpack(htmlInsideSubfolderConfig);
212212

213213
compiler.run((error, stats) => {
214214
expect(error).toBeNull();
215215

216216
const statsErrors = stats?.compilation.errors;
217217
expect(statsErrors?.length).toBe(0);
218218

219-
const result1 = fs.readFileSync(
220-
path.join(__dirname, 'cases/inline-web-worker/dist/index.html'),
219+
const result = fs.readFileSync(
220+
path.join(__dirname, 'cases/html-inside-subfolder/dist/frontend/index.html'),
221221
'utf8',
222222
);
223223

224-
const expected1 = fs.readFileSync(
225-
path.join(__dirname, 'cases/inline-web-worker/expected/index.html'),
224+
const expected = fs.readFileSync(
225+
path.join(__dirname, 'cases/html-inside-subfolder/expected/frontend/index.html'),
226226
'utf8',
227227
);
228+
expect(result).toBe(expected);
228229

229-
expect(result1).toBe(expected1);
230+
const expectedParentFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/expected/'));
231+
const generatedParentFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/dist/'));
232+
expect(expectedParentFileList.sort()).toEqual(generatedParentFileList.sort());
230233

231-
const expectedFileList = fs.readdirSync(path.join(__dirname, 'cases/inline-web-worker/expected/'));
232-
const generatedFileList = fs.readdirSync(path.join(__dirname, 'cases/inline-web-worker/dist/'));
233-
expect(expectedFileList.sort()).toEqual(generatedFileList.sort());
234+
const expectedChildFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/expected/'));
235+
const generatedChildFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/dist/'));
236+
expect(expectedChildFileList.sort()).toEqual(generatedChildFileList.sort());
234237

235238
resolve(true);
236239
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="language" content="English"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="minimum-scale=1,initial-scale=1,width=device-width,shrink-to-fit=no"/><title>webpack test</title><script defer="defer">console.log("Hello world");</script></head><body><p>This is minimal code to demonstrate webpack usage</p></body></html>

__tests__/cases/inline-web-worker/fixtures/index.html renamed to __tests__/cases/html-inside-subfolder/fixtures/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010
</head>
1111
<body>
1212
<p>This is minimal code to demonstrate webpack usage</p>
13-
<button id="button">Run Action</button>
1413
</body>
1514
</html>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// eslint-disable-next-line no-console
2+
console.log('Hello world');

__tests__/cases/inline-web-worker/webpack.config.ts renamed to __tests__/cases/html-inside-subfolder/webpack.config.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,15 @@ const config: Configuration = {
88
entry: path.join(__dirname, './fixtures/index.js'),
99
output: {
1010
path: path.join(__dirname, './dist'),
11-
filename: '[name].js',
12-
publicPath: './'
11+
filename: '[name].js'
1312
},
1413
plugins: [
1514
new HtmlWebpackPlugin({
16-
template: path.resolve(__dirname, './fixtures/index.html')
15+
template: path.resolve(__dirname, './fixtures/index.html'),
16+
filename: path.join(__dirname, './dist/frontend/index.html')
1717
}),
1818
new Self()
19-
],
20-
module: {
21-
rules: [
22-
{
23-
resourceQuery: /raw/,
24-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
25-
// @ts-ignore - according to assets-loader, it is a proper usage to use 'asset/source'
26-
type: 'asset/source'
27-
}
28-
]
29-
}
19+
]
3020
};
3121

3222
export default config;

__tests__/cases/inline-web-worker/expected/index.html

Lines changed: 0 additions & 1 deletion
This file was deleted.

__tests__/cases/inline-web-worker/fixtures/index.js

Lines changed: 0 additions & 36 deletions
This file was deleted.

__tests__/cases/inline-web-worker/fixtures/worker.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"jest": "^26.6.3",
4949
"lint-staged": "^13.0.3",
5050
"pinst": "^3.0.0",
51-
"prettier": "^2.0.5",
51+
"prettier": "^3.0.1",
5252
"ts-jest": "^26.5.3",
5353
"typescript": "^4.1.3"
5454
},

src/HtmlInlineScriptPlugin.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import path from 'path';
12
import { Compilation } from 'webpack';
23
import type { Compiler, WebpackPluginInstance } from 'webpack';
34
import htmlWebpackPlugin from 'html-webpack-plugin';
@@ -37,7 +38,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
3738
const {
3839
scriptMatchPattern = [/.+[.]js$/],
3940
htmlMatchPattern = [/.+[.]html$/],
40-
assetPreservePattern = [],
41+
assetPreservePattern = []
4142
} = options;
4243

4344
this.scriptMatchPattern = scriptMatchPattern;
@@ -59,7 +60,6 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
5960
return this.assetPreservePattern.some((test) => assetName.match(test));
6061
}
6162

62-
6363
shouldProcessHtml(
6464
templateName: string
6565
): boolean {
@@ -102,18 +102,48 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
102102
};
103103
}
104104

105-
apply(compiler: Compiler): void {
106-
let publicPath = compiler.options?.output?.publicPath as string || '';
105+
getPublicPath(
106+
compilation: Compilation,
107+
htmlFileName: string,
108+
customPublicPath: string
109+
): string {
110+
const webpackPublicPath = compilation.getAssetPath(
111+
compilation.outputOptions.publicPath as string,
112+
{ hash: compilation.hash }
113+
);
114+
// Webpack 5 introduced "auto" as default value
115+
const isPublicPathDefined = webpackPublicPath !== 'auto';
116+
117+
let publicPath = '';
118+
119+
if (customPublicPath !== 'auto') {
120+
// If the html-webpack-plugin options contain a custom public path uset it
121+
publicPath = customPublicPath;
122+
} else if (isPublicPathDefined) {
123+
// If a hard coded public path exists in webpack config use it
124+
publicPath = webpackPublicPath;
125+
} else if (compilation.options.output.path) {
126+
// If no public path for webpack and html-webpack-plugin was set get a relative url path
127+
publicPath = path.relative(
128+
path.resolve(compilation.options.output.path, path.dirname(htmlFileName)),
129+
compilation.options.output.path
130+
).split(path.sep).join('/');
131+
}
107132

108133
if (publicPath && !publicPath.endsWith('/')) {
109134
publicPath += '/';
110135
}
111136

137+
return publicPath;
138+
}
139+
140+
apply(compiler: Compiler): void {
112141
compiler.hooks.compilation.tap(`${PLUGIN_PREFIX}_compilation`, (compilation) => {
113142
const hooks = htmlWebpackPlugin.getHooks(compilation);
114143

115144
hooks.alterAssetTags.tap(`${PLUGIN_PREFIX}_alterAssetTags`, (data) => {
116145
const htmlFileName = data.plugin.options?.filename;
146+
const publicPath = this.getPublicPath(compilation, data.outputName, data.publicPath);
117147

118148
if (htmlFileName && !this.shouldProcessHtml(htmlFileName)) {
119149
this.ignoredHtmlFiles.push(htmlFileName);

0 commit comments

Comments
 (0)