Skip to content

Commit 658a63f

Browse files
committed
feat(refactor): Improve compatibility
1 parent 5d34c0b commit 658a63f

File tree

1 file changed

+52
-38
lines changed

1 file changed

+52
-38
lines changed

src/index.ts

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,74 @@
11
import { Compiler } from 'webpack';
22

3-
interface Module {
4-
type?: string
5-
content: string
6-
}
3+
type File = {
4+
[key: string]: string
5+
};
76

8-
interface Compilation {
9-
modules: Module[]
10-
}
7+
type Asset = {
8+
source(): string
9+
size(): number
10+
};
1111

12-
interface PluginData {
13-
html: string
14-
assets: { css: string[] }
12+
interface Compilation {
13+
assets: { [key: string]: Asset }
1514
}
1615

1716
export default class Plugin
1817
{
19-
20-
static makeReg(fileName: string) {
21-
return new RegExp(`<link[^>]+href=['"]${fileName}['"][^>]+(>|\/>|><\/link>)`);
18+
static addStyle(html: string, style: string) {
19+
return html.replace('</head>', `<style>${style}</style></head>`);
2220
}
2321

24-
static getStyleString(modules: Module[]): string {
25-
return modules
26-
.filter(({ type = '' }) => type.includes('mini-css-extract-plugin'))
27-
.reduce((result, { content = '' }) => {
28-
return result + content;
29-
}, '');
22+
static removeLinkTag(html: string, cssFileName: string) {
23+
return html.replace(
24+
new RegExp(`<link[^>]+href=['"]${cssFileName}['"][^>]+(>|\/>|><\/link>)`),
25+
'',
26+
);
3027
}
3128

32-
static addStyleInToHTML(compilation: Compilation, pluginData: PluginData) {
33-
const style = this.getStyleString(compilation.modules);
34-
pluginData.html = pluginData.html
35-
.replace('</head>', `<style>\n${style}\n</style></head>`);
36-
}
29+
private css: File = {};
30+
private html: File = {};
3731

38-
static removeLinkTag(pluginData: PluginData) {
39-
pluginData.assets.css.forEach((fileName: string) => {
40-
pluginData.html = pluginData.html
41-
.replace(this.makeReg(fileName), '');
32+
private prepare({ assets }: Compilation) {
33+
const isCSS = is('css');
34+
const isHTML = is('html');
35+
36+
Object.keys(assets).forEach((fileName) => {
37+
if (isCSS(fileName)) {
38+
this.css[fileName] = assets[fileName].source();
39+
delete assets[fileName];
40+
} else if (isHTML(fileName)) {
41+
this.html[fileName] = assets[fileName].source();
42+
}
4243
});
4344
}
4445

45-
static replace(compilation: Compilation, pluginData: PluginData, callback: (...args: any[]) => void) {
46-
Plugin.removeLinkTag(pluginData);
47-
Plugin.addStyleInToHTML(compilation, pluginData);
48-
callback(null, pluginData);
46+
private process({ assets }: Compilation) {
47+
Object.keys(this.html).forEach((htmlFileName) => {
48+
let html = this.html[htmlFileName];
49+
50+
Object.keys(this.css).forEach((key) => {
51+
html = Plugin.addStyle(html, this.css[key]);
52+
html = Plugin.removeLinkTag(html, key);
53+
});
54+
55+
assets[htmlFileName] = {
56+
source() { return html },
57+
size() { return html.length },
58+
};
59+
});
4960
}
5061

5162
apply(compiler: Compiler) {
52-
compiler.hooks.compilation.tap('HtmlReplaceWebpackPlugin', (compilation: any) => {
53-
compilation.hooks.htmlWebpackPluginAfterHtmlProcessing
54-
.tapAsync(
55-
'html-webpack-plugin-before-html-processing',
56-
Plugin.replace.bind(Plugin, compilation)
57-
);
63+
compiler.hooks.emit.tapAsync('html-inline-css-webpack-plugin', (compilation: Compilation, callback: () => void) => {
64+
this.prepare(compilation);
65+
this.process(compilation);
66+
callback();
5867
});
5968
}
69+
}
70+
71+
function is(filenameExtension: string) {
72+
const reg = new RegExp(`\.${filenameExtension}$`);
73+
return (fileName: string) => reg.test(fileName);
6074
}

0 commit comments

Comments
 (0)