@rollup-extras/plugin-html 2.0.0 → 2.1.0
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 +6 -0
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +35 -1
- package/package.json +1 -1
- package/shared.js +4 -0
package/README.md
CHANGED
|
@@ -108,6 +108,12 @@ Optional, boolean, default: undefined.
|
|
|
108
108
|
|
|
109
109
|
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
110
|
|
|
111
|
+
### modulepreload
|
|
112
|
+
|
|
113
|
+
Optional, boolean, default: true.
|
|
114
|
+
|
|
115
|
+
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.
|
|
116
|
+
|
|
111
117
|
### injectIntoHead
|
|
112
118
|
|
|
113
119
|
Optional, RegExp | function | boolean, default: `(fileName: string) => fileName.endsWith(cssExtention)`.
|
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,
|
|
@@ -235,6 +237,7 @@ export default function (options = {}) {
|
|
|
235
237
|
logger.finish('html file generated');
|
|
236
238
|
} catch (e) {
|
|
237
239
|
logger.finish('html generation failed', LogLevel.error, e);
|
|
240
|
+
throw e;
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
243
|
|
|
@@ -279,6 +282,17 @@ export default function (options = {}) {
|
|
|
279
282
|
type: 'asset',
|
|
280
283
|
});
|
|
281
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
|
+
}
|
|
282
296
|
}
|
|
283
297
|
}
|
|
284
298
|
}
|
|
@@ -344,3 +358,23 @@ function defaultTemplateFactory(template, assets) {
|
|
|
344
358
|
const bodyIndex = template.toLowerCase().indexOf(bodyClosingElement);
|
|
345
359
|
return `${template.substring(0, bodyIndex)}${bodyElements.join('')}${template.substring(bodyIndex)}`;
|
|
346
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;
|