-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathbase-plugin.ts
More file actions
113 lines (98 loc) · 2.93 KB
/
base-plugin.ts
File metadata and controls
113 lines (98 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import type { Compilation } from 'webpack'
import {
type Config,
type StyleTagFactory,
DEFAULT_REPLACE_CONFIG,
type FileCache,
type ReplaceConfig,
} from '../types'
import { isCSS, escapeRegExp } from '../utils'
export class BasePlugin {
private publicPathRegexMap = new Map<string, RegExp>()
protected readonly replaceConfig: ReplaceConfig
protected readonly styleTagFactory: StyleTagFactory
protected cssStyleCache: FileCache = {}
constructor(protected readonly config: Config = {}) {
this.replaceConfig = config.replace || DEFAULT_REPLACE_CONFIG
this.styleTagFactory =
config.styleTagFactory ||
(({ style }) => `<style type="text/css">${style}</style>`)
}
protected prepare({ assets }: Compilation) {
for (const fileName of Object.keys(assets)) {
if (isCSS(fileName) && this.isCurrentFileNeedsToBeInlined(fileName)) {
const source = assets[fileName].source()
this.cssStyleCache[fileName] =
typeof source === 'string' ? source : source.toString()
if (!this.config.leaveCSSFile) {
delete assets[fileName]
}
}
}
}
protected getCSSStyle({
cssLink,
publicPath,
}: {
cssLink: string
publicPath: string
}): string | undefined {
let publicPathRegex = this.publicPathRegexMap.get(publicPath)
if (publicPathRegex === undefined) {
publicPathRegex = new RegExp(`^${escapeRegExp(publicPath)}`)
this.publicPathRegexMap.set(publicPath, publicPathRegex)
}
// Link pattern: publicPath + fileName + '?' + hash
const fileName = cssLink.replace(publicPathRegex, '').replace(/\?.+$/g, '')
if (this.isCurrentFileNeedsToBeInlined(fileName)) {
const style = this.cssStyleCache[fileName]
if (style === undefined) {
console.error(
`Can not get css style for ${cssLink}. It may be a bug of html-inline-css-webpack-plugin.`,
)
}
return style
} else {
return undefined
}
}
protected isCurrentFileNeedsToBeInlined(fileName: string): boolean {
if (typeof this.config.filter === 'function') {
return this.config.filter(fileName)
} else {
return true
}
}
protected addStyle({
html,
htmlFileName,
style,
}: {
html: string
htmlFileName: string
style: string
}) {
const replaceValues = [
this.styleTagFactory({ style }),
this.replaceConfig.target,
]
if (this.replaceConfig.position === 'after') {
replaceValues.reverse()
}
const replaced = html.replace(
this.replaceConfig.target,
replaceValues.join(''),
)
if (replaced === html) {
throw new Error(
`Can not inject css style into "${htmlFileName}", as there is not replace target "${this.replaceConfig.target}"`,
)
}
return replaced
}
protected cleanUp(html: string) {
return this.replaceConfig.removeTarget
? html.replace(this.replaceConfig.target, '')
: html
}
}