1
- import { parse } from 'url' ;
2
-
3
- import { compile } from 'es6-templates' ;
4
- import { minify } from 'html-minifier-terser' ;
5
- import { getOptions , isUrlRequest } from 'loader-utils' ;
1
+ import { getOptions } from 'loader-utils' ;
6
2
import validateOptions from 'schema-utils' ;
7
3
4
+ import { attributePlugin , interpolatePlugin , minimizerPlugin } from './plugins' ;
5
+ import Warning from './Warning' ;
6
+
8
7
import {
9
- getLinks ,
10
- getUniqueIdent ,
11
- replaceLinkWithIdent ,
8
+ pluginRunner ,
12
9
isProductionMode ,
13
10
getImportCode ,
14
11
getExportCode ,
15
12
} from './utils' ;
16
13
17
14
import schema from './options.json' ;
18
15
19
- export const raw = true ;
20
-
21
- export default function htmlLoader ( source ) {
16
+ export default function htmlLoader ( content ) {
22
17
const options = getOptions ( this ) || { } ;
23
18
24
19
validateOptions ( schema , options , {
25
20
name : 'HTML Loader' ,
26
21
baseDataPath : 'options' ,
27
22
} ) ;
28
23
29
- let content = source . toString ( ) ;
30
-
31
- const links = getLinks ( content , options . attributes ) ;
32
- const replacers = new Map ( ) ;
33
-
34
- let offset = 0 ;
24
+ const plugins = [ ] ;
35
25
36
- for ( const link of links ) {
37
- if ( link . value && isUrlRequest ( link . value , options . root ) ) {
38
- const uri = parse ( link . value ) ;
26
+ const attributes =
27
+ typeof options . attributes === 'undefined' ? true : options . attributes ;
39
28
40
- if ( typeof uri . hash !== 'undefined' ) {
41
- uri . hash = null ;
42
- link . value = uri . format ( ) ;
43
- link . length = link . value . length ;
44
- }
45
-
46
- const ident = getUniqueIdent ( replacers ) ;
47
-
48
- replacers . set ( ident , link . value ) ;
49
-
50
- content = replaceLinkWithIdent ( content , link , ident , offset ) ;
51
-
52
- offset += ident . length - link . length ;
53
- }
29
+ if ( attributes ) {
30
+ plugins . push ( attributePlugin ( options ) ) ;
54
31
}
55
32
56
33
const minimize =
@@ -59,46 +36,40 @@ export default function htmlLoader(source) {
59
36
: options . minimize ;
60
37
61
38
if ( minimize ) {
62
- const minimizeOptions =
63
- typeof minimize === 'boolean'
64
- ? {
65
- collapseWhitespace : true ,
66
- conservativeCollapse : true ,
67
- keepClosingSlash : true ,
68
- minifyCSS : true ,
69
- minifyJS : true ,
70
- removeAttributeQuotes : true ,
71
- removeComments : true ,
72
- removeScriptTypeAttributes : true ,
73
- removeStyleLinkTypeAttributes : true ,
74
- useShortDoctype : true ,
75
- }
76
- : minimize ;
77
-
78
- try {
79
- content = minify ( content , minimizeOptions ) ;
80
- } catch ( error ) {
81
- this . emitError ( error ) ;
82
- }
39
+ plugins . push ( minimizerPlugin ( options ) ) ;
40
+ }
41
+
42
+ const { interpolate } = options ;
43
+
44
+ if ( interpolate ) {
45
+ plugins . push ( interpolatePlugin ( options ) ) ;
46
+ }
47
+
48
+ const { html, messages, warnings, errors } = pluginRunner ( plugins ) . process (
49
+ content
50
+ ) ;
51
+
52
+ for ( const warning of warnings ) {
53
+ this . emitWarning ( new Warning ( warning ) ) ;
54
+ }
55
+
56
+ for ( const error of errors ) {
57
+ this . emitError ( new Error ( error ) ) ;
83
58
}
84
59
85
- if ( options . interpolate ) {
86
- try {
87
- // Double escape quotes so that they are not unescaped completely in the template string
88
- content = compile (
89
- `\`${ content . replace ( / \\ " / g, '\\\\"' ) . replace ( / \\ ' / g, "\\\\\\'" ) } \``
90
- ) . code ;
91
- } catch ( error ) {
92
- this . emitError ( error ) ;
60
+ const replacers = [ ] ;
93
61
94
- content = JSON . stringify ( content ) ;
62
+ for ( const message of messages ) {
63
+ // eslint-disable-next-line default-case
64
+ switch ( message . type ) {
65
+ case 'replacer' :
66
+ replacers . push ( message . value ) ;
67
+ break ;
95
68
}
96
- } else {
97
- content = JSON . stringify ( content ) ;
98
69
}
99
70
100
- const importCode = getImportCode ( this , content , replacers , options ) ;
101
- const exportCode = getExportCode ( content , replacers , options ) ;
71
+ const importCode = getImportCode ( this , html , replacers , options ) ;
72
+ const exportCode = getExportCode ( html , replacers , options ) ;
102
73
103
74
return `${ importCode } ${ exportCode } ;` ;
104
75
}
0 commit comments