Skip to content

Commit 584738c

Browse files
committed
Add the crossorigin property to the external
1 parent 658ecba commit 584738c

File tree

3 files changed

+67
-35
lines changed

3 files changed

+67
-35
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ meta: {
123123

124124
```js
125125
{
126+
crossorigin?: 'anonymous' | 'use-credentials'
126127
file: string
127128
type?: undefined | 'css' | 'js'
128129
pos: 'before' | 'after'
@@ -132,7 +133,8 @@ meta: {
132133
An array of additional files that will be injected to the output HTML document. Only CSS and JS files
133134
are accepted. The optional `type` property points which type of file is injected. If type is `undefined`
134135
then it is detected based on the file extension. The `pos` property points when the file is inserted:
135-
before processing the budnled files or after.
136+
before processing the bundled files or after. The optional `crossorigin` property points whether to place
137+
the CORS attribute to the generated tag.
136138

137139
##### Example
138140

example/rollup.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export default {
2222
externals: [{
2323
file: 'https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css',
2424
pos: 'before',
25+
crossorigin: 'use-credentials',
2526
}],
2627
preload: ['lib'],
2728
minify: {

src/index.ts

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
3843
interface IExternal {
44+
crossorigin?: Crossorigin
3945
file: string
4046
type?: InjectType
4147
pos: ExternalPosition
4248
}
4349

44-
type ExtrenalsProcessor = (pos: ExternalPosition) => void
45-
4650
interface 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+
114167
export 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

Comments
 (0)