@@ -19,7 +19,8 @@ import {
19
19
isDataUrl ,
20
20
isExternalUrl ,
21
21
normalizePath ,
22
- processSrcSet
22
+ processSrcSet ,
23
+ removeComments
23
24
} from '../utils'
24
25
import type { ResolvedConfig } from '../config'
25
26
import { toOutputFilePathInHtml } from '../build'
@@ -48,9 +49,9 @@ const inlineImportRE =
48
49
const htmlLangRE = / \. (?: h t m l | h t m ) $ /
49
50
50
51
const importMapRE =
51
- / [ \t ] * < s c r i p t [ ^ > ] * t y p e \s * = \s * (?: " i m p o r t m a p " | ' i m p o r t m a p ' | i m p o r t m a p ) [ ^ > ] * > .* ?< \/ s c r i p t > / is
52
+ / < s c r i p t [ ^ > ] * t y p e \s * = \s * (?: " i m p o r t m a p " | ' i m p o r t m a p ' | i m p o r t m a p ) [ ^ > ] * > .* ?< \/ s c r i p t > / is
52
53
const moduleScriptRE =
53
- / [ \t ] * < s c r i p t [ ^ > ] * t y p e \s * = \s * (?: " m o d u l e " | ' m o d u l e ' | m o d u l e ) [ ^ > ] * > / i
54
+ / < s c r i p t [ ^ > ] * t y p e \s * = \s * (?: " m o d u l e " | ' m o d u l e ' | m o d u l e ) [ ^ > ] * > / i
54
55
55
56
export const isHTMLProxy = ( id : string ) : boolean => htmlProxyRE . test ( id )
56
57
@@ -986,11 +987,10 @@ export async function applyHtmlTransforms(
986
987
}
987
988
988
989
const importRE = / \b i m p o r t \s * ( " [ ^ " ] * [ ^ \\ ] " | ' [ ^ ' ] * [ ^ \\ ] ' ) ; * / g
989
- const commentRE = / \/ \* [ \s \S ] * ?\* \/ | \/ \/ .* $ / gm
990
990
function isEntirelyImport ( code : string ) {
991
991
// only consider "side-effect" imports, which match <script type=module> semantics exactly
992
992
// the regexes will remove too little in some exotic cases, but false-negatives are alright
993
- return ! code . replace ( importRE , '' ) . replace ( commentRE , '' ) . trim ( ) . length
993
+ return ! removeComments ( code . replace ( importRE , '' ) ) . trim ( ) . length
994
994
}
995
995
996
996
function getBaseInHTML ( urlRelativePath : string , config : ResolvedConfig ) {
@@ -1004,14 +1004,14 @@ function getBaseInHTML(urlRelativePath: string, config: ResolvedConfig) {
1004
1004
: config . base
1005
1005
}
1006
1006
1007
- const headInjectRE = / ( [ \t ] * ) < \/ h e a d > / i
1008
- const headPrependInjectRE = / ( [ \t ] * ) < h e a d [ ^ > ] * > / i
1007
+ const headInjectRE = / < \/ h e a d > / i
1008
+ const headPrependInjectRE = / < h e a d [ ^ > ] * > / i
1009
1009
1010
1010
const htmlInjectRE = / < \/ h t m l > / i
1011
- const htmlPrependInjectRE = / ( [ \t ] * ) < h t m l [ ^ > ] * > / i
1011
+ const htmlPrependInjectRE = / < h t m l [ ^ > ] * > / i
1012
1012
1013
- const bodyInjectRE = / ( [ \t ] * ) < \/ b o d y > / i
1014
- const bodyPrependInjectRE = / ( [ \t ] * ) < b o d y [ ^ > ] * > / i
1013
+ const bodyInjectRE = / < \/ b o d y > / i
1014
+ const bodyPrependInjectRE = / < b o d y [ ^ > ] * > / i
1015
1015
1016
1016
const doctypePrependInjectRE = / < ! d o c t y p e h t m l > / i
1017
1017
@@ -1025,32 +1025,43 @@ function injectToHead(
1025
1025
if ( prepend ) {
1026
1026
// inject as the first element of head
1027
1027
if ( headPrependInjectRE . test ( html ) ) {
1028
- return html . replace (
1029
- headPrependInjectRE ,
1030
- ( match , p1 ) => `${ match } \n${ serializeTags ( tags , incrementIndent ( p1 ) ) } `
1031
- )
1028
+ return html . replace ( headPrependInjectRE , ( match , offset ) => {
1029
+ const indent = getIndent ( html , offset )
1030
+ return `${ match } \n${ serializeTags ( tags , incrementIndent ( indent ) ) } `
1031
+ } )
1032
1032
}
1033
1033
} else {
1034
1034
// inject before head close
1035
1035
if ( headInjectRE . test ( html ) ) {
1036
1036
// respect indentation of head tag
1037
- return html . replace (
1038
- headInjectRE ,
1039
- ( match , p1 ) => `${ serializeTags ( tags , incrementIndent ( p1 ) ) } ${ match } `
1040
- )
1037
+ return html . replace ( headInjectRE , ( match , offset ) => {
1038
+ const indent = getIndent ( html , offset )
1039
+ return `\n${ serializeTags (
1040
+ tags ,
1041
+ incrementIndent ( indent )
1042
+ ) } ${ indent } ${ match } `
1043
+ } )
1041
1044
}
1042
1045
// try to inject before the body tag
1043
1046
if ( bodyPrependInjectRE . test ( html ) ) {
1044
- return html . replace (
1045
- bodyPrependInjectRE ,
1046
- ( match , p1 ) => `${ serializeTags ( tags , p1 ) } \n${ match } `
1047
- )
1047
+ return html . replace ( bodyPrependInjectRE , ( match , offset ) => {
1048
+ const indent = getIndent ( html , offset )
1049
+ return `${ serializeTags ( tags , indent ) } \n${ match } `
1050
+ } )
1048
1051
}
1049
1052
}
1050
1053
// if no head tag is present, we prepend the tag for both prepend and append
1051
1054
return prependInjectFallback ( html , tags )
1052
1055
}
1053
1056
1057
+ function getIndent ( html : string , pos : number ) {
1058
+ let indent = ''
1059
+ for ( ; pos >= 0 && ( html [ pos ] === ' ' || html [ pos ] === '\t' ) ; pos -- ) {
1060
+ indent += html [ pos ]
1061
+ }
1062
+ return indent
1063
+ }
1064
+
1054
1065
function injectToBody (
1055
1066
html : string ,
1056
1067
tags : HtmlTagDescriptor [ ] ,
@@ -1061,26 +1072,29 @@ function injectToBody(
1061
1072
if ( prepend ) {
1062
1073
// inject after body open
1063
1074
if ( bodyPrependInjectRE . test ( html ) ) {
1064
- return html . replace (
1065
- bodyPrependInjectRE ,
1066
- ( match , p1 ) => `${ match } \n${ serializeTags ( tags , incrementIndent ( p1 ) ) } `
1067
- )
1075
+ return html . replace ( bodyPrependInjectRE , ( match , offset ) => {
1076
+ const indent = getIndent ( html , offset )
1077
+ return `${ match } \n${ serializeTags ( tags , incrementIndent ( indent ) ) } `
1078
+ } )
1068
1079
}
1069
1080
// if no there is no body tag, inject after head or fallback to prepend in html
1070
1081
if ( headInjectRE . test ( html ) ) {
1071
- return html . replace (
1072
- headInjectRE ,
1073
- ( match , p1 ) => `${ match } \n${ serializeTags ( tags , p1 ) } `
1074
- )
1082
+ return html . replace ( headInjectRE , ( match , offset ) => {
1083
+ const indent = getIndent ( html , offset )
1084
+ return `${ match } \n${ serializeTags ( tags , indent ) } `
1085
+ } )
1075
1086
}
1076
1087
return prependInjectFallback ( html , tags )
1077
1088
} else {
1078
1089
// inject before body close
1079
1090
if ( bodyInjectRE . test ( html ) ) {
1080
- return html . replace (
1081
- bodyInjectRE ,
1082
- ( match , p1 ) => `${ serializeTags ( tags , incrementIndent ( p1 ) ) } ${ match } `
1083
- )
1091
+ return html . replace ( bodyInjectRE , ( match , offset ) => {
1092
+ const indent = getIndent ( match , offset )
1093
+ return `\n${ serializeTags (
1094
+ tags ,
1095
+ incrementIndent ( indent )
1096
+ ) } ${ indent } ${ match } `
1097
+ } )
1084
1098
}
1085
1099
// if no body tag is present, append to the html tag, or at the end of the file
1086
1100
if ( htmlInjectRE . test ( html ) ) {
0 commit comments