@@ -30,19 +30,23 @@ const enum InjectType {
3030 js = 'js' ,
3131}
3232
33- const enum ExternalPosition {
33+ enum ExternalPosition {
3434 before = 'before' ,
3535 after = 'after' ,
3636}
3737
38+ enum Crossorigin {
39+ anonymous = 'anonymous' ,
40+ usecredentials = 'use-credentials' ,
41+ }
42+
3843interface IExternal {
44+ crossorigin ?: Crossorigin
3945 file : string
4046 type ?: InjectType
4147 pos : ExternalPosition
4248}
4349
44- type ExtrenalsProcessor = ( pos : ExternalPosition ) => void
45-
4650interface IPluginOptions {
4751 template : string
4852 file ?: string
@@ -111,6 +115,55 @@ const formatSupportsModules = (f?: ModuleFormat) => (
111115 || f === 'module'
112116)
113117
118+ const checkEnum = < T extends { } > ( enumobj : T , val ?: string ) => (
119+ ! val || Object . values ( enumobj ) . includes ( val )
120+ )
121+
122+ const injectCSSandJSFactory = (
123+ head : HTMLElement ,
124+ body : HTMLElement ,
125+ modules ?: boolean ,
126+ ) => {
127+ const typeModule = modules ? 'type="module" ' : ''
128+
129+ return (
130+ fileName : string ,
131+ type : InjectType | string ,
132+ pos ?: Inject ,
133+ crossorigin ?: Crossorigin ,
134+ ) => {
135+ const cors = crossorigin ? `crossorigin="${ crossorigin } " ` : ''
136+ if ( type === InjectType . css ) {
137+ const parent = pos === Inject . body ? body : head
138+ addNewLine ( parent )
139+ parent . appendChild ( new HTMLElement ( 'link' , { } , `rel="stylesheet" ${ cors } href="/${ fileName } "` ) )
140+ } else {
141+ const parent = pos === Inject . head ? head : body
142+ addNewLine ( parent )
143+ parent . appendChild ( new HTMLElement ( 'script' , { } , `${ typeModule } ${ cors } src="/${ fileName } "` ) )
144+ }
145+ }
146+ }
147+
148+ type ExtrenalsProcessor = ( pos : ExternalPosition ) => void
149+
150+ const extrenalsProcessorFactory = (
151+ injectCSSandJS : ReturnType < typeof injectCSSandJSFactory > ,
152+ externals ?: IExternal [ ] ,
153+ ) : ExtrenalsProcessor => {
154+ if ( ! externals ) {
155+ // tslint:disable-next-line: no-empty
156+ return ( _pos ) => { }
157+ }
158+ return ( processPos ) => {
159+ for ( const { pos, file, type, crossorigin} of externals ) {
160+ if ( pos === processPos ) {
161+ injectCSSandJS ( file , type || path . extname ( file ) . slice ( 1 ) , undefined , crossorigin )
162+ }
163+ }
164+ }
165+ }
166+
114167export default ( {
115168 template,
116169 file,
@@ -150,10 +203,13 @@ export default ({
150203 }
151204
152205 if ( externals ) {
153- for ( const { pos} of externals ) {
154- if ( pos !== ExternalPosition . before && pos !== ExternalPosition . after ) {
206+ for ( const { pos, crossorigin } of externals ) {
207+ if ( ! checkEnum ( ExternalPosition , pos ) ) {
155208 this . error ( 'Invalid position for the extrenal: ' + pos )
156209 }
210+ if ( ! checkEnum ( Crossorigin , crossorigin ) ) {
211+ this . error ( 'Invalid crossorigin argument for the extrenal: ' + crossorigin )
212+ }
157213 }
158214 }
159215
@@ -248,35 +304,8 @@ consider to use the esm format or switch off the option`)
248304 }
249305 }
250306
251- const injectCSSandJS = ( fileName : string , type : string , pos : Inject | undefined = undefined ) => {
252- const cssParent = pos !== Inject . body ? head : body
253- const jsParent = pos !== Inject . head ? body : head
254- switch ( type ) {
255- case InjectType . css :
256- addNewLine ( cssParent )
257- cssParent . appendChild ( new HTMLElement ( 'link' , { } , `rel="stylesheet" href="/${ fileName } "` ) )
258- break
259- case InjectType . js :
260- addNewLine ( jsParent )
261- const typeModule = modules ? 'type="module" ' : ''
262- jsParent . appendChild ( new HTMLElement ( 'script' , { } , `${ typeModule } src="/${ fileName } "` ) )
263- break
264- default :
265- break
266- }
267- }
268-
269- const processExternals : ExtrenalsProcessor = externals ?
270- ( pos ) => {
271- for ( const external of externals ) {
272- if ( external . pos === pos ) {
273- injectCSSandJS ( external . file , external . type || path . extname ( external . file ) . slice ( 1 ) )
274- }
275- }
276- }
277- :
278- // tslint:disable-next-line: no-empty
279- ( _pos ) => { }
307+ const injectCSSandJS = injectCSSandJSFactory ( head , body , modules )
308+ const processExternals = extrenalsProcessorFactory ( injectCSSandJS , externals )
280309
281310 // Inject externals before
282311 processExternals ( ExternalPosition . before )
0 commit comments