Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
icelam committed Aug 9, 2023
2 parents fe7a33c + df1cf02 commit 89d8b15
Show file tree
Hide file tree
Showing 15 changed files with 376 additions and 186 deletions.
9 changes: 5 additions & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
}],
"import/extensions": ["error", {
"js": "never",
"ts": "never",
}]
"ts": "never"
}],
"class-methods-use-this": "off"
},
"overrides": [
{
Expand All @@ -51,15 +52,15 @@
"airbnb-base",
"plugin:jest/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended"
],
"env": { "node": true },
"rules": {
"@typescript-eslint/no-var-requires": ["off"],
"no-console": ["off"],
"import/extensions": ["error", {
"js": "never",
"ts": "never",
"ts": "never"
}]
}
}
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ on:
jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [14.x, 16.x, 18.x, 20.x]
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
env:
HUSKY: 0
steps:
Expand All @@ -28,6 +29,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Get yarn cache directory path
id: yarn-cache-dir-path
shell: bash
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Restore yarn cache
uses: actions/cache@v3
Expand Down
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ yarn.lock
.husky
/scripts
jest.config.js
docs
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ module.exports = {
};
```

## Known limitations
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.
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.

## Contributors

Thanks goes to these wonderful people:
Expand All @@ -145,7 +149,7 @@ Thanks goes to these wonderful people:
</td>
<td align="center" valign="top" width="20%">
<a href="https://github.com/SorsOps">
<img src="https://avatars.githubusercontent.com/u/80043879?s=120&v=4" width="60px;" alt="@kmalakoff"/>
<img src="https://avatars.githubusercontent.com/u/80043879?s=120&v=4" width="60px;" alt="@SorsOps"/>
<br />
<b>@SorsOps</b>
</a>
Expand Down
25 changes: 14 additions & 11 deletions __tests__/HtmlInlineScriptPlugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import preserveConfig from './cases/preserveAsset/webpack.config';
import multipleInstanceConfig from './cases/multiple-instance/webpack.config';
import jsWithImportConfig from './cases/js-with-import/webpack.config';
import webWorkerConfig from './cases/web-worker/webpack.config';
import inlineWebWorkerConfig from './cases/inline-web-worker/webpack.config';
import ignoreScriptsConfig from './cases/ignore-scripts/webpack.config';
import ignoreHtmlsConfig from './cases/ignore-htmls/webpack.config';
import ignoreScriptsAndHtmlsConfig from './cases/ignore-scripts-and-htmls/webpack.config';
import filenameWithSpecialCharactersConfig from './cases/filename-with-special-characters/webpack.config';
import escapeScriptTagEndConfig from './cases/escape-script-end-tag/webpack.config';
import htmlInsideSubfolderConfig from './cases/html-inside-subfolder/webpack.config';

describe('HtmlInlineScriptPlugin', () => {
it('should build simple webpack config without error', async () => {
Expand Down Expand Up @@ -206,31 +206,34 @@ describe('HtmlInlineScriptPlugin', () => {
await webpackPromise;
});

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

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

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

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

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

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

const expectedFileList = fs.readdirSync(path.join(__dirname, 'cases/inline-web-worker/expected/'));
const generatedFileList = fs.readdirSync(path.join(__dirname, 'cases/inline-web-worker/dist/'));
expect(expectedFileList.sort()).toEqual(generatedFileList.sort());
const expectedChildFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/expected/'));
const generatedChildFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/dist/'));
expect(expectedChildFileList.sort()).toEqual(generatedChildFileList.sort());

resolve(true);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +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>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@
</head>
<body>
<p>This is minimal code to demonstrate webpack usage</p>
<button id="button">Run Action</button>
</body>
</html>
2 changes: 2 additions & 0 deletions __tests__/cases/html-inside-subfolder/fixtures/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-console
console.log('Hello world');
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,15 @@ const config: Configuration = {
entry: path.join(__dirname, './fixtures/index.js'),
output: {
path: path.join(__dirname, './dist'),
filename: '[name].js',
publicPath: './'
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './fixtures/index.html')
template: path.resolve(__dirname, './fixtures/index.html'),
filename: path.join(__dirname, './dist/frontend/index.html')
}),
new Self()
],
module: {
rules: [
{
resourceQuery: /raw/,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - according to assets-loader, it is a proper usage to use 'asset/source'
type: 'asset/source'
}
]
}
]
};

export default config;
1 change: 0 additions & 1 deletion __tests__/cases/inline-web-worker/expected/index.html

This file was deleted.

36 changes: 0 additions & 36 deletions __tests__/cases/inline-web-worker/fixtures/index.js

This file was deleted.

7 changes: 0 additions & 7 deletions __tests__/cases/inline-web-worker/fixtures/worker.js

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"jest": "^26.6.3",
"lint-staged": "^13.0.3",
"pinst": "^3.0.0",
"prettier": "^2.0.5",
"prettier": "^3.0.1",
"ts-jest": "^26.5.3",
"typescript": "^4.1.3"
},
Expand Down
38 changes: 34 additions & 4 deletions src/HtmlInlineScriptPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path';
import { Compilation } from 'webpack';
import type { Compiler, WebpackPluginInstance } from 'webpack';
import htmlWebpackPlugin from 'html-webpack-plugin';
Expand Down Expand Up @@ -37,7 +38,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
const {
scriptMatchPattern = [/.+[.]js$/],
htmlMatchPattern = [/.+[.]html$/],
assetPreservePattern = [],
assetPreservePattern = []
} = options;

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


shouldProcessHtml(
templateName: string
): boolean {
Expand Down Expand Up @@ -102,18 +102,48 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
};
}

apply(compiler: Compiler): void {
let publicPath = compiler.options?.output?.publicPath as string || '';
getPublicPath(
compilation: Compilation,
htmlFileName: string,
customPublicPath: string
): string {
const webpackPublicPath = compilation.getAssetPath(
compilation.outputOptions.publicPath as string,
{ hash: compilation.hash }
);
// Webpack 5 introduced "auto" as default value
const isPublicPathDefined = webpackPublicPath !== 'auto';

let publicPath = '';

if (customPublicPath !== 'auto') {
// If the html-webpack-plugin options contain a custom public path uset it
publicPath = customPublicPath;
} else if (isPublicPathDefined) {
// If a hard coded public path exists in webpack config use it
publicPath = webpackPublicPath;
} else if (compilation.options.output.path) {
// If no public path for webpack and html-webpack-plugin was set get a relative url path
publicPath = path.relative(
path.resolve(compilation.options.output.path, path.dirname(htmlFileName)),
compilation.options.output.path
).split(path.sep).join('/');
}

if (publicPath && !publicPath.endsWith('/')) {
publicPath += '/';
}

return publicPath;
}

apply(compiler: Compiler): void {
compiler.hooks.compilation.tap(`${PLUGIN_PREFIX}_compilation`, (compilation) => {
const hooks = htmlWebpackPlugin.getHooks(compilation);

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

if (htmlFileName && !this.shouldProcessHtml(htmlFileName)) {
this.ignoredHtmlFiles.push(htmlFileName);
Expand Down
Loading

0 comments on commit 89d8b15

Please sign in to comment.