@rollup-extras/plugin-html 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/asset-factories.js +9 -4
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +46 -13
- package/package.json +1 -1
- package/shared.js +4 -0
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
1
3
|
# Plugin Html
|
|
2
4
|
|
|
3
5
|
Rollup plugin to inject assets names into html template.
|
|
@@ -108,6 +110,12 @@ Optional, boolean, default: undefined.
|
|
|
108
110
|
|
|
109
111
|
Defines if the plugin adds `nomodule` attributes for non-modular js chunks. By default, it is done only if we have an `es` output in one of the bundles processed by the plugin. Also plugin values `iife` outputs higher than `umd` and if we have both filters out `umd` ones. This can be changed only by providing a custom `assetFactory`.
|
|
110
112
|
|
|
113
|
+
### modulepreload
|
|
114
|
+
|
|
115
|
+
Optional, boolean, default: true.
|
|
116
|
+
|
|
117
|
+
When enabled and the output format is `es`, the plugin automatically injects `<link rel="modulepreload">` tags into `<head>` for all static dependencies (including transitive ones) of each entry chunk. This eliminates the browser's sequential module discovery waterfall, allowing all chunks to be fetched in parallel as soon as the HTML is parsed.
|
|
118
|
+
|
|
111
119
|
### injectIntoHead
|
|
112
120
|
|
|
113
121
|
Optional, RegExp | function | boolean, default: `(fileName: string) => fileName.endsWith(cssExtention)`.
|
package/asset-factories.js
CHANGED
|
@@ -35,10 +35,15 @@ export function simpleModuleScript(predicateSource) {
|
|
|
35
35
|
|
|
36
36
|
export function combineAssetFactories(...factories) {
|
|
37
37
|
return (fileName, content, type) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
return next(0);
|
|
39
|
+
|
|
40
|
+
function next(start) {
|
|
41
|
+
for (let index = start; index < factories.length; index++) {
|
|
42
|
+
const result = factories[index](fileName, content, type);
|
|
43
|
+
if (result instanceof Promise) {
|
|
44
|
+
return result.then(asset => asset || next(index + 1));
|
|
45
|
+
}
|
|
46
|
+
if (result) return result;
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
};
|
package/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ declare module '@rollup-extras/plugin-html' {
|
|
|
33
33
|
useWriteBundle?: boolean;
|
|
34
34
|
useEmittedTemplate?: boolean;
|
|
35
35
|
conditionalLoading?: boolean;
|
|
36
|
+
modulepreload?: boolean;
|
|
36
37
|
injectIntoHead?: PredicateSource;
|
|
37
38
|
ignore?: PredicateSource;
|
|
38
39
|
assetsFactory?: AssetFactory;
|
package/index.d.ts.map
CHANGED
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
null,
|
|
27
27
|
null
|
|
28
28
|
],
|
|
29
|
-
"mappings": "
|
|
29
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCQgBW,eAAeA;;iBASfC,uBAAuBA;;iBASvBC,kBAAkBA;;iBASlBC,qBAAqBA;;;;;;;;",
|
|
30
30
|
"ignoreList": []
|
|
31
31
|
}
|
package/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import logger from '@rollup-extras/utils/logger';
|
|
|
7
7
|
import { multiConfigPluginBase } from '@rollup-extras/utils/multi-config-plugin-base';
|
|
8
8
|
import { getOptionsObject } from '@rollup-extras/utils/options';
|
|
9
9
|
|
|
10
|
-
import { getLinkElement, getModuleScriptElement, getNonModuleScriptElement, toAssetPredicate } from './shared.js';
|
|
10
|
+
import { getLinkElement, getModulePreloadElement, getModuleScriptElement, getNonModuleScriptElement, toAssetPredicate } from './shared.js';
|
|
11
11
|
|
|
12
12
|
const defaultTemplate = '<!DOCTYPE html><html><head></head><body></body></html>';
|
|
13
13
|
const headClosingElement = '</head>';
|
|
@@ -20,6 +20,7 @@ const defaults = {
|
|
|
20
20
|
watch: true,
|
|
21
21
|
useWriteBundle: false,
|
|
22
22
|
emitFile: 'auto',
|
|
23
|
+
modulepreload: true,
|
|
23
24
|
injectIntoHead: (( fileName) => fileName.endsWith(cssExtention)),
|
|
24
25
|
ignore: (toAssetPredicate(false)),
|
|
25
26
|
templateFactory: (
|
|
@@ -42,6 +43,7 @@ export default function (options = {}) {
|
|
|
42
43
|
watch,
|
|
43
44
|
emitFile,
|
|
44
45
|
conditionalLoading,
|
|
46
|
+
modulepreload,
|
|
45
47
|
logger,
|
|
46
48
|
useWriteBundle,
|
|
47
49
|
logLevel,
|
|
@@ -77,18 +79,18 @@ export default function (options = {}) {
|
|
|
77
79
|
handleTemplateReadError(e);
|
|
78
80
|
}
|
|
79
81
|
} else {
|
|
80
|
-
templateString =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
templateString = readFile(template, { encoding: 'utf8' })
|
|
83
|
+
.then(newTemplateString => {
|
|
84
|
+
if (!isUsableByDefaultTemplateFactory(newTemplateString) && !hasCustomTemplateFactory) {
|
|
85
|
+
warnAboutUsingDefaultTemplate();
|
|
86
|
+
return defaultTemplate;
|
|
87
|
+
}
|
|
88
|
+
return newTemplateString;
|
|
89
|
+
})
|
|
90
|
+
.catch(e => {
|
|
91
|
+
handleTemplateReadError(e);
|
|
92
|
+
return defaultTemplate;
|
|
93
|
+
});
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
}
|
|
@@ -280,6 +282,17 @@ export default function (options = {}) {
|
|
|
280
282
|
type: 'asset',
|
|
281
283
|
});
|
|
282
284
|
}
|
|
285
|
+
if (modulepreload && options.format === 'es') {
|
|
286
|
+
const transitiveImports = collectTransitiveImports(bundle, fileName);
|
|
287
|
+
for (const importFileName of transitiveImports) {
|
|
288
|
+
const importAssetPath = relative(initialDir, join(dir, importFileName));
|
|
289
|
+
(assets.asset).push({
|
|
290
|
+
html: getModulePreloadElement(importAssetPath),
|
|
291
|
+
head: true,
|
|
292
|
+
type: 'asset',
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
283
296
|
}
|
|
284
297
|
}
|
|
285
298
|
}
|
|
@@ -345,3 +358,23 @@ function defaultTemplateFactory(template, assets) {
|
|
|
345
358
|
const bodyIndex = template.toLowerCase().indexOf(bodyClosingElement);
|
|
346
359
|
return `${template.substring(0, bodyIndex)}${bodyElements.join('')}${template.substring(bodyIndex)}`;
|
|
347
360
|
}
|
|
361
|
+
|
|
362
|
+
function collectTransitiveImports(bundle, entryFileName) {
|
|
363
|
+
|
|
364
|
+
const collected = new Set();
|
|
365
|
+
|
|
366
|
+
const queue = [... (bundle[entryFileName]).imports];
|
|
367
|
+
while (queue.length > 0) {
|
|
368
|
+
const importFileName = (queue.pop());
|
|
369
|
+
|
|
370
|
+
if (collected.has(importFileName)) {
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
collected.add(importFileName);
|
|
374
|
+
const chunk = bundle[importFileName];
|
|
375
|
+
if (chunk?.type === 'chunk') {
|
|
376
|
+
queue.push(...chunk.imports);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return collected;
|
|
380
|
+
}
|
package/package.json
CHANGED
package/shared.js
CHANGED
|
@@ -10,6 +10,10 @@ export function getModuleScriptElement(fileName) {
|
|
|
10
10
|
return `<script src="${fileName}" type="module"></script>`;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export function getModulePreloadElement(fileName) {
|
|
14
|
+
return `<link rel="modulepreload" href="${fileName}">`;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
export function toAssetPredicate(sourceOption) {
|
|
14
18
|
if (typeof sourceOption === 'boolean') {
|
|
15
19
|
return () => sourceOption;
|