Skip to content

Commit f2edce1

Browse files
committed
fix: multi-entry issue
runjuu#14
1 parent a02fb6f commit f2edce1

File tree

3 files changed

+66
-34
lines changed

3 files changed

+66
-34
lines changed

package.json

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
},
4545
"homepage": "https://github.com/Runjuu/html-inline-css-webpack-plugin#readme",
4646
"devDependencies": {
47+
"@types/lodash": "^4.14.137",
4748
"@types/webpack": "^4.4.0",
4849
"husky": "^1.3.1",
4950
"lint-staged": "^8.1.0",
@@ -54,5 +55,8 @@
5455
"tslint-sonarts": "^1.8.0",
5556
"typescript": "^3.2.2",
5657
"webpack": "^4.11.1"
58+
},
59+
"dependencies": {
60+
"lodash": "^4.17.15"
5761
}
5862
}

src/index.ts

+52-34
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { Compiler, Configuration } from 'webpack'
1+
import { SyncHook } from 'tapable'
2+
import { Compiler } from 'webpack'
3+
import { escapeRegExp } from 'lodash'
24

35
interface File {
46
[key: string]: string
@@ -13,6 +15,15 @@ interface Compilation {
1315
assets: { [key: string]: Asset }
1416
}
1517

18+
interface HtmlWebpackPluginData {
19+
html: string
20+
outputName: string
21+
assets: {
22+
publicPath: string
23+
css: string[]
24+
}
25+
}
26+
1627
interface ReplaceConfig {
1728
position?: 'before' | 'after'
1829
removeTarget?: boolean
@@ -59,10 +70,17 @@ export default class Plugin {
5970

6071
private css: File = {}
6172

62-
private html: File = {}
63-
6473
constructor(private readonly config: Config = {}) {}
6574

75+
private getCSSFile(cssLink: string, publicPath: string) {
76+
// Link pattern: publicPath + fileName + '?' + hash
77+
const fileName = cssLink
78+
.replace(new RegExp(`^${escapeRegExp(publicPath)}`), '')
79+
.replace(/\?.+$/g, '')
80+
81+
return this.css[fileName]
82+
}
83+
6684
private isCurrentFileNeedsToBeInlined(fileName: string): boolean {
6785
if (typeof this.config.filter === 'function') {
6886
return this.config.filter(fileName)
@@ -73,55 +91,55 @@ export default class Plugin {
7391

7492
private prepare({ assets }: Compilation) {
7593
const isCSS = is('css')
76-
const isHTML = is('html')
77-
const { leaveCSSFile } = this.config
7894

7995
Object.keys(assets).forEach((fileName) => {
8096
if (isCSS(fileName) && this.isCurrentFileNeedsToBeInlined(fileName)) {
8197
this.css[fileName] = assets[fileName].source()
82-
if (!leaveCSSFile) {
98+
if (!this.config.leaveCSSFile) {
8399
delete assets[fileName]
84100
}
85101
}
86-
87-
if (isHTML(fileName) && this.isCurrentFileNeedsToBeInlined(fileName)) {
88-
this.html[fileName] = assets[fileName].source()
89-
}
90102
})
91103
}
92104

93-
private process({ assets }: Compilation, { output }: Configuration) {
94-
const publicPath = (output && output.publicPath) || ''
105+
private process(data: HtmlWebpackPluginData) {
95106
const { replace: replaceConfig = DEFAULT_REPLACE_CONFIG } = this.config
96107

97-
Object.keys(this.html).forEach((htmlFileName) => {
98-
let html = this.html[htmlFileName]
99-
100-
Object.keys(this.css).forEach((key) => {
101-
html = Plugin.addStyle(html, this.css[key], replaceConfig)
102-
html = Plugin.removeLinkTag(html, publicPath + key)
108+
// check if current html needs to be inlined
109+
if (this.isCurrentFileNeedsToBeInlined(data.outputName)) {
110+
data.assets.css.forEach((cssLink) => {
111+
data.html = Plugin.addStyle(
112+
data.html,
113+
this.getCSSFile(cssLink, data.assets.publicPath),
114+
replaceConfig,
115+
)
103116
})
104117

105-
html = Plugin.cleanUp(html, replaceConfig)
106-
107-
assets[htmlFileName] = {
108-
source() {
109-
return html
110-
},
111-
size() {
112-
return html.length
113-
},
114-
}
115-
})
118+
data.html = Plugin.cleanUp(data.html, replaceConfig)
119+
data.assets.css.length = 0 // prevent generate <link /> tag
120+
}
116121
}
117122

118123
apply(compiler: Compiler) {
119-
compiler.hooks.emit.tapAsync(
124+
compiler.hooks.compilation.tap(
120125
'html-inline-css-webpack-plugin',
121-
(compilation: Compilation, callback: () => void) => {
122-
this.prepare(compilation)
123-
this.process(compilation, compiler.options)
124-
callback()
126+
(compilation) => {
127+
if ('htmlWebpackPluginBeforeHtmlProcessing' in compilation.hooks) {
128+
const hook: SyncHook<HtmlWebpackPluginData> =
129+
// @ts-ignore Error:(130, 27) TS2339: Property 'htmlWebpackPluginBeforeHtmlProcessing' does not exist on type 'CompilationHooks'.
130+
compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing
131+
hook.tap(
132+
'html-inline-css-webpack-plugin-html-webpack-plugin-before-html-processing',
133+
(data: HtmlWebpackPluginData) => {
134+
this.prepare(compilation)
135+
this.process(data)
136+
},
137+
)
138+
} else {
139+
throw new Error(
140+
'`html-webpack-plugin` should be ordered first before html-inline-css-webpack-plugin',
141+
)
142+
}
125143
},
126144
)
127145
}

yarn.lock

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
dependencies:
2424
any-observable "^0.3.0"
2525

26+
"@types/lodash@^4.14.137":
27+
version "4.14.137"
28+
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.137.tgz#8a4804937dc6462274ffcc088df8f14fc1b368e2"
29+
integrity sha512-g4rNK5SRKloO+sUGbuO7aPtwbwzMgjK+bm9BBhLD7jGUiGR7zhwYEhSln/ihgYQBeIJ5j7xjyaYzrWTcu3UotQ==
30+
2631
"@types/node@*":
2732
version "10.3.1"
2833
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.1.tgz#51092fbacaed768a122a293814474fbf6e5e8b6d"
@@ -1763,6 +1768,11 @@ locate-path@^3.0.0:
17631768
p-locate "^3.0.0"
17641769
path-exists "^3.0.0"
17651770

1771+
lodash@^4.17.15:
1772+
version "4.17.15"
1773+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
1774+
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
1775+
17661776
lodash@^4.17.5:
17671777
version "4.17.14"
17681778
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"

0 commit comments

Comments
 (0)