@rollup-extras/plugin-html 1.4.5 → 2.0.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 +2 -2
- package/{dist/asset-factories.mjs → asset-factories.js} +18 -12
- package/index.d.ts +67 -0
- package/index.d.ts.map +31 -0
- package/index.js +346 -0
- package/package.json +15 -24
- package/shared.js +24 -0
- package/asset-factories/package.json +0 -5
- package/dist/asset-factories.cjs +0 -61
- package/dist/asset-factories.d.ts +0 -6
- package/dist/index.cjs +0 -280
- package/dist/index.d.ts +0 -7
- package/dist/index.mjs +0 -278
- package/dist/shared.cjs +0 -31
- package/dist/shared.d.ts +0 -5
- package/dist/shared.mjs +0 -26
- package/dist/types.d.ts +0 -37
package/dist/asset-factories.cjs
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var logger$1 = require('@niceties/logger');
|
|
4
|
-
var shared = require('./shared.cjs');
|
|
5
|
-
|
|
6
|
-
const noopPredicate = () => false;
|
|
7
|
-
let logger;
|
|
8
|
-
function simpleES5Script(predicateSource) {
|
|
9
|
-
const predicate = getPredicate(predicateSource);
|
|
10
|
-
return (fileName) => {
|
|
11
|
-
if (predicate(fileName)) {
|
|
12
|
-
return shared.getNonModuleScriptElement(fileName, false);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
function simpleES5FallbackScript(predicateSource) {
|
|
17
|
-
const predicate = getPredicate(predicateSource);
|
|
18
|
-
return (fileName) => {
|
|
19
|
-
if (predicate(fileName)) {
|
|
20
|
-
return shared.getNonModuleScriptElement(fileName, true);
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function simpleModuleScript(predicateSource) {
|
|
25
|
-
const predicate = getPredicate(predicateSource);
|
|
26
|
-
return (fileName) => {
|
|
27
|
-
if (predicate(fileName)) {
|
|
28
|
-
return shared.getModuleScriptElement(fileName);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
function combineAssetFactories(...factories) {
|
|
33
|
-
return (fileName, content, type) => {
|
|
34
|
-
for (const factory of factories) {
|
|
35
|
-
const result = factory(fileName, content, type);
|
|
36
|
-
if (result) {
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function getPredicate(predicateSource) {
|
|
43
|
-
let predicate = shared.toAssetPredicate(predicateSource);
|
|
44
|
-
if (!predicate) {
|
|
45
|
-
const logger = getLogger();
|
|
46
|
-
logger(`${predicateSource} is not valid, using noopPredicate`, 2 /* LogLevel.warn */);
|
|
47
|
-
predicate = noopPredicate;
|
|
48
|
-
}
|
|
49
|
-
return predicate;
|
|
50
|
-
}
|
|
51
|
-
function getLogger() {
|
|
52
|
-
if (!logger) {
|
|
53
|
-
logger = logger$1.createLogger('@rollup-extras/plugin-html/asset-factories');
|
|
54
|
-
}
|
|
55
|
-
return logger;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
exports.combineAssetFactories = combineAssetFactories;
|
|
59
|
-
exports.simpleES5FallbackScript = simpleES5FallbackScript;
|
|
60
|
-
exports.simpleES5Script = simpleES5Script;
|
|
61
|
-
exports.simpleModuleScript = simpleModuleScript;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { AssetFactory, PredicateSource } from './types';
|
|
2
|
-
import type { InternalModuleFormat } from 'rollup';
|
|
3
|
-
export declare function simpleES5Script(predicateSource: PredicateSource): (fileName: string) => string | undefined;
|
|
4
|
-
export declare function simpleES5FallbackScript(predicateSource: PredicateSource): (fileName: string) => string | undefined;
|
|
5
|
-
export declare function simpleModuleScript(predicateSource: PredicateSource): (fileName: string) => string | undefined;
|
|
6
|
-
export declare function combineAssetFactories(...factories: AssetFactory[]): (fileName: string, content: string | Uint8Array, type: 'asset' | InternalModuleFormat) => string | import("./types").AssetDescriptor | Promise<string | import("./types").AssetDescriptor | undefined> | undefined;
|
package/dist/index.cjs
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var fs = require('fs/promises');
|
|
4
|
-
var oldStyleFs = require('fs');
|
|
5
|
-
var path = require('path');
|
|
6
|
-
var options = require('@rollup-extras/utils/options');
|
|
7
|
-
var logger = require('@rollup-extras/utils/logger');
|
|
8
|
-
var mutliConfigPluginBase = require('@rollup-extras/utils/mutli-config-plugin-base');
|
|
9
|
-
var shared = require('./shared.cjs');
|
|
10
|
-
|
|
11
|
-
const defaultTemplate = '<!DOCTYPE html><html><head></head><body></body></html>';
|
|
12
|
-
const headClosingElement = '</head>';
|
|
13
|
-
const bodyClosingElement = '</body>';
|
|
14
|
-
const cssExtention = '.css';
|
|
15
|
-
const defaults = {
|
|
16
|
-
pluginName: '@rollup-extras/plugin-html',
|
|
17
|
-
outputFile: 'index.html',
|
|
18
|
-
watch: true,
|
|
19
|
-
useWriteBundle: false,
|
|
20
|
-
emitFile: 'auto',
|
|
21
|
-
injectIntoHead: (fileName) => fileName.endsWith(cssExtention),
|
|
22
|
-
ignore: shared.toAssetPredicate(false),
|
|
23
|
-
templateFactory: ((template, assets, defaultTemplateFactory) => defaultTemplateFactory(template, assets))
|
|
24
|
-
};
|
|
25
|
-
const factories = { logger, injectIntoHead: predicateFactory, ignore: predicateFactory };
|
|
26
|
-
function index (options$1 = {}) {
|
|
27
|
-
const { pluginName, outputFile, template, watch, emitFile, conditionalLoading, logger, useWriteBundle, logLevel, useEmittedTemplate, injectIntoHead, ignore, assetsFactory, templateFactory } = options.getOptionsObject(options$1, {
|
|
28
|
-
...defaults,
|
|
29
|
-
useEmittedTemplate: !('template' in options$1),
|
|
30
|
-
logLevel: options$1.verbose ? 1 /* LogLevel.info */ : 0 /* LogLevel.verbose */
|
|
31
|
-
}, factories), hasCustomTemplateFactory = 'templateFactory' in options$1;
|
|
32
|
-
let templateString = defaultTemplate, hasTemplateFile = false;
|
|
33
|
-
if (template) {
|
|
34
|
-
if (isUsableByDefaultTemplateFactory(template)) {
|
|
35
|
-
templateString = template;
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
if (watch) {
|
|
39
|
-
try {
|
|
40
|
-
// using sync fs call because we need to return plugin object immidiately
|
|
41
|
-
useNewTemplate(oldStyleFs.readFileSync(template, { encoding: 'utf8' }));
|
|
42
|
-
hasTemplateFile = true;
|
|
43
|
-
}
|
|
44
|
-
catch (e) {
|
|
45
|
-
handleTemplateReadError(e);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
templateString = new Promise(resolve => {
|
|
50
|
-
fs.readFile(template, { encoding: 'utf8' })
|
|
51
|
-
.then((newTemplateString) => {
|
|
52
|
-
if (!isUsableByDefaultTemplateFactory(newTemplateString) && !hasCustomTemplateFactory) {
|
|
53
|
-
warnAboutUsingDefaultTemplate();
|
|
54
|
-
resolve(defaultTemplate);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
resolve(newTemplateString);
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
.catch(handleTemplateReadError);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
let initialDir = '', fileNameInInitialDir, assets = freshAssets();
|
|
66
|
-
const processedFiles = new Set();
|
|
67
|
-
const instance = mutliConfigPluginBase.multiConfigPluginBase(useWriteBundle, pluginName, generateBundle, updateAssets);
|
|
68
|
-
const baseRenderStart = instance.renderStart;
|
|
69
|
-
const baseAddInstance = instance.api.addInstance;
|
|
70
|
-
instance.renderStart = function (outputOptions, inputOptions) {
|
|
71
|
-
logger('started collecting information', 0 /* LogLevel.verbose */);
|
|
72
|
-
initialDir = outputOptions.dir ?? '';
|
|
73
|
-
fileNameInInitialDir = path.join(initialDir, outputFile);
|
|
74
|
-
return baseRenderStart.call(this, outputOptions, inputOptions);
|
|
75
|
-
};
|
|
76
|
-
instance.api.addInstance = () => {
|
|
77
|
-
const instance = baseAddInstance();
|
|
78
|
-
if (hasTemplateFile && watch) {
|
|
79
|
-
instance.buildStart = buildStart;
|
|
80
|
-
}
|
|
81
|
-
return instance;
|
|
82
|
-
};
|
|
83
|
-
if (hasTemplateFile && watch) {
|
|
84
|
-
instance.buildStart = async function () {
|
|
85
|
-
try {
|
|
86
|
-
useNewTemplate(await fs.readFile(template, { encoding: 'utf8' }));
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
handleTemplateReadError(e);
|
|
90
|
-
}
|
|
91
|
-
await buildStart.apply(this);
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
return instance;
|
|
95
|
-
async function updateAssets(options, bundle, remainingConfigsCount, remainingOutputsCount) {
|
|
96
|
-
await getAssets(options, bundle);
|
|
97
|
-
const statistics = Object.keys(assets)
|
|
98
|
-
.map(key => ({ key, count: assets[key].length }))
|
|
99
|
-
.filter(item => item.count)
|
|
100
|
-
.map(({ key, count }) => `${key}: ${count}`)
|
|
101
|
-
.join(', ');
|
|
102
|
-
logger(`assets collected: [${statistics}], remaining: ${remainingOutputsCount} outputs, ${remainingConfigsCount} configs`, 0 /* LogLevel.verbose */);
|
|
103
|
-
const dir = options.dir ?? '', fileName = path.relative(dir, fileNameInInitialDir);
|
|
104
|
-
if (fileName in bundle) {
|
|
105
|
-
if (useEmittedTemplate) {
|
|
106
|
-
logger(`using exiting emitted ${fileName} as an input for out templateFactory`, 0 /* LogLevel.verbose */);
|
|
107
|
-
const source = bundle[fileName].type === 'asset' ? bundle[fileName].source.toString() : bundle[fileName].code;
|
|
108
|
-
useNewTemplate(source);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
logger(`removing exiting emitted ${fileName}`, 0 /* LogLevel.verbose */);
|
|
112
|
-
}
|
|
113
|
-
if (remainingConfigsCount === 0 && emitFile && !useWriteBundle) {
|
|
114
|
-
delete bundle[fileName];
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
function freshAssets() {
|
|
119
|
-
return {
|
|
120
|
-
asset: [],
|
|
121
|
-
es: [],
|
|
122
|
-
iife: [],
|
|
123
|
-
umd: []
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
function useNewTemplate(newTemplateString) {
|
|
127
|
-
if (!isUsableByDefaultTemplateFactory(newTemplateString) && !hasCustomTemplateFactory) {
|
|
128
|
-
warnAboutUsingDefaultTemplate();
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
templateString = newTemplateString;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function handleTemplateReadError(e) {
|
|
135
|
-
if (e?.code === 'ENOENT') {
|
|
136
|
-
logger('template nor a file or string', 2 /* LogLevel.warn */, e);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
logger('error reading template', 2 /* LogLevel.warn */, e);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
function warnAboutUsingDefaultTemplate() {
|
|
143
|
-
logger('template is unusable by default template factory, using default one', 2 /* LogLevel.warn */);
|
|
144
|
-
}
|
|
145
|
-
async function buildStart() {
|
|
146
|
-
this.addWatchFile(template);
|
|
147
|
-
}
|
|
148
|
-
async function generateBundle(options) {
|
|
149
|
-
logger.start('generating html', logLevel);
|
|
150
|
-
try {
|
|
151
|
-
const dir = options.dir ?? '', fileName = path.relative(dir, fileNameInInitialDir);
|
|
152
|
-
const depromisifiedTemplateString = await templateString, source = await templateFactory(depromisifiedTemplateString, assets, defaultTemplateFactory);
|
|
153
|
-
if (!emitFile || fileName.startsWith('..') || useWriteBundle) {
|
|
154
|
-
if (emitFile && emitFile !== 'auto') {
|
|
155
|
-
logger('cannot emitFile because it is outside of current output.dir, using writeFile instead', 0 /* LogLevel.verbose */);
|
|
156
|
-
}
|
|
157
|
-
await fs.mkdir(path.dirname(fileNameInInitialDir), { recursive: true });
|
|
158
|
-
await fs.writeFile(fileNameInInitialDir, source);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
this.emitFile({
|
|
162
|
-
type: 'asset',
|
|
163
|
-
fileName,
|
|
164
|
-
source
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
// reset assets and configs for the next iteration
|
|
168
|
-
assets = freshAssets();
|
|
169
|
-
processedFiles.clear();
|
|
170
|
-
logger.finish('html file generated');
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
logger.finish('html generation failed', 3 /* LogLevel.error */, e);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
async function getAssets(options, bundle) {
|
|
177
|
-
const dir = options.dir ?? '';
|
|
178
|
-
for (const fileName of Object.keys(bundle)) {
|
|
179
|
-
const relativeToRootAssetPath = path.join(dir, fileName);
|
|
180
|
-
const assetPath = path.relative(initialDir, relativeToRootAssetPath);
|
|
181
|
-
if (ignore(relativeToRootAssetPath) || processedFiles.has(relativeToRootAssetPath)) {
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
processedFiles.add(relativeToRootAssetPath);
|
|
185
|
-
if (bundle[fileName].type === 'asset') {
|
|
186
|
-
if (await useAssetFactory(assetPath, relativeToRootAssetPath, bundle[fileName].source, 'asset')) {
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
if (fileName.endsWith(cssExtention)) {
|
|
190
|
-
assets.asset.push({
|
|
191
|
-
html: shared.getLinkElement(assetPath),
|
|
192
|
-
head: injectIntoHead(relativeToRootAssetPath),
|
|
193
|
-
type: 'asset'
|
|
194
|
-
});
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else if (bundle[fileName].type === 'chunk') {
|
|
199
|
-
const chunk = bundle[fileName];
|
|
200
|
-
if (chunk.isEntry) {
|
|
201
|
-
if (await useAssetFactory(assetPath, relativeToRootAssetPath, chunk.code, options.format)) {
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
if (options.format === 'es' || options.format === 'iife' || options.format === 'umd') {
|
|
205
|
-
assets[options.format].push({
|
|
206
|
-
html: (assets) => {
|
|
207
|
-
let useConditionalLoading = conditionalLoading;
|
|
208
|
-
useConditionalLoading ??= !!((assets.iife.length
|
|
209
|
-
|| assets.umd.length)
|
|
210
|
-
&& assets.es.length);
|
|
211
|
-
return (options.format === 'iife' || options.format === 'umd') ? shared.getNonModuleScriptElement(assetPath, !!useConditionalLoading) : shared.getModuleScriptElement(assetPath);
|
|
212
|
-
},
|
|
213
|
-
head: injectIntoHead(relativeToRootAssetPath),
|
|
214
|
-
type: 'asset'
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
async function useAssetFactory(fileName, relativeToRootAssetPath, source, format) {
|
|
222
|
-
if (assetsFactory) {
|
|
223
|
-
try {
|
|
224
|
-
let asset = await assetsFactory(fileName, source, format);
|
|
225
|
-
if (asset) {
|
|
226
|
-
if (typeof asset === 'string') {
|
|
227
|
-
asset = {
|
|
228
|
-
html: asset,
|
|
229
|
-
head: injectIntoHead(relativeToRootAssetPath),
|
|
230
|
-
type: format
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
if (!assets[asset.type]) {
|
|
234
|
-
assets[asset.type] = [];
|
|
235
|
-
}
|
|
236
|
-
assets[asset.type].push(asset);
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
catch (e) {
|
|
241
|
-
logger('exception in assetFactory', 2 /* LogLevel.warn */, e);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
function isUsableByDefaultTemplateFactory(template) {
|
|
248
|
-
return template.indexOf(headClosingElement) >= 0 && template.indexOf(bodyClosingElement) >= 0;
|
|
249
|
-
}
|
|
250
|
-
function predicateFactory(options, field) {
|
|
251
|
-
if (options[field] != null) {
|
|
252
|
-
const predicate = shared.toAssetPredicate(options[field]);
|
|
253
|
-
if (predicate) {
|
|
254
|
-
return predicate;
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
options.logger && options.logger(`${field} option ignored because it is not a function, RegExp, string or boolean`, 2 /* LogLevel.warn */);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return defaults[field];
|
|
261
|
-
}
|
|
262
|
-
function defaultTemplateFactory(template, assets) {
|
|
263
|
-
const assetsAsArray = assets.asset
|
|
264
|
-
.concat((assets.iife.length ? assets.iife : assets.umd))
|
|
265
|
-
.concat(assets.es)
|
|
266
|
-
.map((asset) => {
|
|
267
|
-
if (typeof asset.html === 'function') {
|
|
268
|
-
asset.html = asset.html(assets);
|
|
269
|
-
}
|
|
270
|
-
return asset;
|
|
271
|
-
});
|
|
272
|
-
const headElements = assetsAsArray.filter(asset => asset.head).map(asset => asset.html);
|
|
273
|
-
const bodyElements = assetsAsArray.filter(asset => !asset.head).map(asset => asset.html);
|
|
274
|
-
const headIndex = template.toLowerCase().indexOf(headClosingElement);
|
|
275
|
-
template = `${template.substring(0, headIndex)}${headElements.join('')}${template.substring(headIndex)}`;
|
|
276
|
-
const bodyIndex = template.toLowerCase().indexOf(bodyClosingElement);
|
|
277
|
-
return `${template.substring(0, bodyIndex)}${bodyElements.join('')}${template.substring(bodyIndex)}`;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
module.exports = index;
|
package/dist/index.d.ts
DELETED
package/dist/index.mjs
DELETED
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import oldStyleFs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { getOptionsObject } from '@rollup-extras/utils/options';
|
|
5
|
-
import logger from '@rollup-extras/utils/logger';
|
|
6
|
-
import { multiConfigPluginBase } from '@rollup-extras/utils/mutli-config-plugin-base';
|
|
7
|
-
import { g as getLinkElement, a as getNonModuleScriptElement, b as getModuleScriptElement, t as toAssetPredicate } from './shared.mjs';
|
|
8
|
-
|
|
9
|
-
const defaultTemplate = '<!DOCTYPE html><html><head></head><body></body></html>';
|
|
10
|
-
const headClosingElement = '</head>';
|
|
11
|
-
const bodyClosingElement = '</body>';
|
|
12
|
-
const cssExtention = '.css';
|
|
13
|
-
const defaults = {
|
|
14
|
-
pluginName: '@rollup-extras/plugin-html',
|
|
15
|
-
outputFile: 'index.html',
|
|
16
|
-
watch: true,
|
|
17
|
-
useWriteBundle: false,
|
|
18
|
-
emitFile: 'auto',
|
|
19
|
-
injectIntoHead: (fileName) => fileName.endsWith(cssExtention),
|
|
20
|
-
ignore: toAssetPredicate(false),
|
|
21
|
-
templateFactory: ((template, assets, defaultTemplateFactory) => defaultTemplateFactory(template, assets))
|
|
22
|
-
};
|
|
23
|
-
const factories = { logger, injectIntoHead: predicateFactory, ignore: predicateFactory };
|
|
24
|
-
function index (options = {}) {
|
|
25
|
-
const { pluginName, outputFile, template, watch, emitFile, conditionalLoading, logger, useWriteBundle, logLevel, useEmittedTemplate, injectIntoHead, ignore, assetsFactory, templateFactory } = getOptionsObject(options, {
|
|
26
|
-
...defaults,
|
|
27
|
-
useEmittedTemplate: !('template' in options),
|
|
28
|
-
logLevel: options.verbose ? 1 /* LogLevel.info */ : 0 /* LogLevel.verbose */
|
|
29
|
-
}, factories), hasCustomTemplateFactory = 'templateFactory' in options;
|
|
30
|
-
let templateString = defaultTemplate, hasTemplateFile = false;
|
|
31
|
-
if (template) {
|
|
32
|
-
if (isUsableByDefaultTemplateFactory(template)) {
|
|
33
|
-
templateString = template;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
if (watch) {
|
|
37
|
-
try {
|
|
38
|
-
// using sync fs call because we need to return plugin object immidiately
|
|
39
|
-
useNewTemplate(oldStyleFs.readFileSync(template, { encoding: 'utf8' }));
|
|
40
|
-
hasTemplateFile = true;
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
handleTemplateReadError(e);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
templateString = new Promise(resolve => {
|
|
48
|
-
fs.readFile(template, { encoding: 'utf8' })
|
|
49
|
-
.then((newTemplateString) => {
|
|
50
|
-
if (!isUsableByDefaultTemplateFactory(newTemplateString) && !hasCustomTemplateFactory) {
|
|
51
|
-
warnAboutUsingDefaultTemplate();
|
|
52
|
-
resolve(defaultTemplate);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
resolve(newTemplateString);
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
.catch(handleTemplateReadError);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
let initialDir = '', fileNameInInitialDir, assets = freshAssets();
|
|
64
|
-
const processedFiles = new Set();
|
|
65
|
-
const instance = multiConfigPluginBase(useWriteBundle, pluginName, generateBundle, updateAssets);
|
|
66
|
-
const baseRenderStart = instance.renderStart;
|
|
67
|
-
const baseAddInstance = instance.api.addInstance;
|
|
68
|
-
instance.renderStart = function (outputOptions, inputOptions) {
|
|
69
|
-
logger('started collecting information', 0 /* LogLevel.verbose */);
|
|
70
|
-
initialDir = outputOptions.dir ?? '';
|
|
71
|
-
fileNameInInitialDir = path.join(initialDir, outputFile);
|
|
72
|
-
return baseRenderStart.call(this, outputOptions, inputOptions);
|
|
73
|
-
};
|
|
74
|
-
instance.api.addInstance = () => {
|
|
75
|
-
const instance = baseAddInstance();
|
|
76
|
-
if (hasTemplateFile && watch) {
|
|
77
|
-
instance.buildStart = buildStart;
|
|
78
|
-
}
|
|
79
|
-
return instance;
|
|
80
|
-
};
|
|
81
|
-
if (hasTemplateFile && watch) {
|
|
82
|
-
instance.buildStart = async function () {
|
|
83
|
-
try {
|
|
84
|
-
useNewTemplate(await fs.readFile(template, { encoding: 'utf8' }));
|
|
85
|
-
}
|
|
86
|
-
catch (e) {
|
|
87
|
-
handleTemplateReadError(e);
|
|
88
|
-
}
|
|
89
|
-
await buildStart.apply(this);
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
return instance;
|
|
93
|
-
async function updateAssets(options, bundle, remainingConfigsCount, remainingOutputsCount) {
|
|
94
|
-
await getAssets(options, bundle);
|
|
95
|
-
const statistics = Object.keys(assets)
|
|
96
|
-
.map(key => ({ key, count: assets[key].length }))
|
|
97
|
-
.filter(item => item.count)
|
|
98
|
-
.map(({ key, count }) => `${key}: ${count}`)
|
|
99
|
-
.join(', ');
|
|
100
|
-
logger(`assets collected: [${statistics}], remaining: ${remainingOutputsCount} outputs, ${remainingConfigsCount} configs`, 0 /* LogLevel.verbose */);
|
|
101
|
-
const dir = options.dir ?? '', fileName = path.relative(dir, fileNameInInitialDir);
|
|
102
|
-
if (fileName in bundle) {
|
|
103
|
-
if (useEmittedTemplate) {
|
|
104
|
-
logger(`using exiting emitted ${fileName} as an input for out templateFactory`, 0 /* LogLevel.verbose */);
|
|
105
|
-
const source = bundle[fileName].type === 'asset' ? bundle[fileName].source.toString() : bundle[fileName].code;
|
|
106
|
-
useNewTemplate(source);
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
logger(`removing exiting emitted ${fileName}`, 0 /* LogLevel.verbose */);
|
|
110
|
-
}
|
|
111
|
-
if (remainingConfigsCount === 0 && emitFile && !useWriteBundle) {
|
|
112
|
-
delete bundle[fileName];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function freshAssets() {
|
|
117
|
-
return {
|
|
118
|
-
asset: [],
|
|
119
|
-
es: [],
|
|
120
|
-
iife: [],
|
|
121
|
-
umd: []
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
function useNewTemplate(newTemplateString) {
|
|
125
|
-
if (!isUsableByDefaultTemplateFactory(newTemplateString) && !hasCustomTemplateFactory) {
|
|
126
|
-
warnAboutUsingDefaultTemplate();
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
templateString = newTemplateString;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function handleTemplateReadError(e) {
|
|
133
|
-
if (e?.code === 'ENOENT') {
|
|
134
|
-
logger('template nor a file or string', 2 /* LogLevel.warn */, e);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
logger('error reading template', 2 /* LogLevel.warn */, e);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function warnAboutUsingDefaultTemplate() {
|
|
141
|
-
logger('template is unusable by default template factory, using default one', 2 /* LogLevel.warn */);
|
|
142
|
-
}
|
|
143
|
-
async function buildStart() {
|
|
144
|
-
this.addWatchFile(template);
|
|
145
|
-
}
|
|
146
|
-
async function generateBundle(options) {
|
|
147
|
-
logger.start('generating html', logLevel);
|
|
148
|
-
try {
|
|
149
|
-
const dir = options.dir ?? '', fileName = path.relative(dir, fileNameInInitialDir);
|
|
150
|
-
const depromisifiedTemplateString = await templateString, source = await templateFactory(depromisifiedTemplateString, assets, defaultTemplateFactory);
|
|
151
|
-
if (!emitFile || fileName.startsWith('..') || useWriteBundle) {
|
|
152
|
-
if (emitFile && emitFile !== 'auto') {
|
|
153
|
-
logger('cannot emitFile because it is outside of current output.dir, using writeFile instead', 0 /* LogLevel.verbose */);
|
|
154
|
-
}
|
|
155
|
-
await fs.mkdir(path.dirname(fileNameInInitialDir), { recursive: true });
|
|
156
|
-
await fs.writeFile(fileNameInInitialDir, source);
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
this.emitFile({
|
|
160
|
-
type: 'asset',
|
|
161
|
-
fileName,
|
|
162
|
-
source
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
// reset assets and configs for the next iteration
|
|
166
|
-
assets = freshAssets();
|
|
167
|
-
processedFiles.clear();
|
|
168
|
-
logger.finish('html file generated');
|
|
169
|
-
}
|
|
170
|
-
catch (e) {
|
|
171
|
-
logger.finish('html generation failed', 3 /* LogLevel.error */, e);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
async function getAssets(options, bundle) {
|
|
175
|
-
const dir = options.dir ?? '';
|
|
176
|
-
for (const fileName of Object.keys(bundle)) {
|
|
177
|
-
const relativeToRootAssetPath = path.join(dir, fileName);
|
|
178
|
-
const assetPath = path.relative(initialDir, relativeToRootAssetPath);
|
|
179
|
-
if (ignore(relativeToRootAssetPath) || processedFiles.has(relativeToRootAssetPath)) {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
processedFiles.add(relativeToRootAssetPath);
|
|
183
|
-
if (bundle[fileName].type === 'asset') {
|
|
184
|
-
if (await useAssetFactory(assetPath, relativeToRootAssetPath, bundle[fileName].source, 'asset')) {
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
if (fileName.endsWith(cssExtention)) {
|
|
188
|
-
assets.asset.push({
|
|
189
|
-
html: getLinkElement(assetPath),
|
|
190
|
-
head: injectIntoHead(relativeToRootAssetPath),
|
|
191
|
-
type: 'asset'
|
|
192
|
-
});
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else if (bundle[fileName].type === 'chunk') {
|
|
197
|
-
const chunk = bundle[fileName];
|
|
198
|
-
if (chunk.isEntry) {
|
|
199
|
-
if (await useAssetFactory(assetPath, relativeToRootAssetPath, chunk.code, options.format)) {
|
|
200
|
-
continue;
|
|
201
|
-
}
|
|
202
|
-
if (options.format === 'es' || options.format === 'iife' || options.format === 'umd') {
|
|
203
|
-
assets[options.format].push({
|
|
204
|
-
html: (assets) => {
|
|
205
|
-
let useConditionalLoading = conditionalLoading;
|
|
206
|
-
useConditionalLoading ??= !!((assets.iife.length
|
|
207
|
-
|| assets.umd.length)
|
|
208
|
-
&& assets.es.length);
|
|
209
|
-
return (options.format === 'iife' || options.format === 'umd') ? getNonModuleScriptElement(assetPath, !!useConditionalLoading) : getModuleScriptElement(assetPath);
|
|
210
|
-
},
|
|
211
|
-
head: injectIntoHead(relativeToRootAssetPath),
|
|
212
|
-
type: 'asset'
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
async function useAssetFactory(fileName, relativeToRootAssetPath, source, format) {
|
|
220
|
-
if (assetsFactory) {
|
|
221
|
-
try {
|
|
222
|
-
let asset = await assetsFactory(fileName, source, format);
|
|
223
|
-
if (asset) {
|
|
224
|
-
if (typeof asset === 'string') {
|
|
225
|
-
asset = {
|
|
226
|
-
html: asset,
|
|
227
|
-
head: injectIntoHead(relativeToRootAssetPath),
|
|
228
|
-
type: format
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
if (!assets[asset.type]) {
|
|
232
|
-
assets[asset.type] = [];
|
|
233
|
-
}
|
|
234
|
-
assets[asset.type].push(asset);
|
|
235
|
-
return true;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
catch (e) {
|
|
239
|
-
logger('exception in assetFactory', 2 /* LogLevel.warn */, e);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return false;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
function isUsableByDefaultTemplateFactory(template) {
|
|
246
|
-
return template.indexOf(headClosingElement) >= 0 && template.indexOf(bodyClosingElement) >= 0;
|
|
247
|
-
}
|
|
248
|
-
function predicateFactory(options, field) {
|
|
249
|
-
if (options[field] != null) {
|
|
250
|
-
const predicate = toAssetPredicate(options[field]);
|
|
251
|
-
if (predicate) {
|
|
252
|
-
return predicate;
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
options.logger && options.logger(`${field} option ignored because it is not a function, RegExp, string or boolean`, 2 /* LogLevel.warn */);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
return defaults[field];
|
|
259
|
-
}
|
|
260
|
-
function defaultTemplateFactory(template, assets) {
|
|
261
|
-
const assetsAsArray = assets.asset
|
|
262
|
-
.concat((assets.iife.length ? assets.iife : assets.umd))
|
|
263
|
-
.concat(assets.es)
|
|
264
|
-
.map((asset) => {
|
|
265
|
-
if (typeof asset.html === 'function') {
|
|
266
|
-
asset.html = asset.html(assets);
|
|
267
|
-
}
|
|
268
|
-
return asset;
|
|
269
|
-
});
|
|
270
|
-
const headElements = assetsAsArray.filter(asset => asset.head).map(asset => asset.html);
|
|
271
|
-
const bodyElements = assetsAsArray.filter(asset => !asset.head).map(asset => asset.html);
|
|
272
|
-
const headIndex = template.toLowerCase().indexOf(headClosingElement);
|
|
273
|
-
template = `${template.substring(0, headIndex)}${headElements.join('')}${template.substring(headIndex)}`;
|
|
274
|
-
const bodyIndex = template.toLowerCase().indexOf(bodyClosingElement);
|
|
275
|
-
return `${template.substring(0, bodyIndex)}${bodyElements.join('')}${template.substring(bodyIndex)}`;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export { index as default };
|
package/dist/shared.cjs
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function getLinkElement(fileName) {
|
|
4
|
-
return `<link rel="stylesheet" href="${fileName}" type="text/css">`;
|
|
5
|
-
}
|
|
6
|
-
function getNonModuleScriptElement(fileName, conditionalLoading) {
|
|
7
|
-
return `<script src="${fileName}" type="text/javascript"${conditionalLoading ? ' nomodule' : ''}></script>`;
|
|
8
|
-
}
|
|
9
|
-
function getModuleScriptElement(fileName) {
|
|
10
|
-
return `<script src="${fileName}" type="module"></script>`;
|
|
11
|
-
}
|
|
12
|
-
function toAssetPredicate(sourceOption) {
|
|
13
|
-
if (typeof sourceOption === 'boolean') {
|
|
14
|
-
return () => sourceOption;
|
|
15
|
-
}
|
|
16
|
-
else if (typeof sourceOption === 'function') {
|
|
17
|
-
return sourceOption;
|
|
18
|
-
}
|
|
19
|
-
else if (sourceOption instanceof RegExp) {
|
|
20
|
-
return (fileName) => sourceOption.test(fileName);
|
|
21
|
-
}
|
|
22
|
-
else if (typeof sourceOption === 'string') {
|
|
23
|
-
return (fileName) => fileName.endsWith(sourceOption);
|
|
24
|
-
}
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
exports.getLinkElement = getLinkElement;
|
|
29
|
-
exports.getModuleScriptElement = getModuleScriptElement;
|
|
30
|
-
exports.getNonModuleScriptElement = getNonModuleScriptElement;
|
|
31
|
-
exports.toAssetPredicate = toAssetPredicate;
|
package/dist/shared.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { AssetPredicate, PredicateSource } from './types';
|
|
2
|
-
export declare function getLinkElement(fileName: string): string;
|
|
3
|
-
export declare function getNonModuleScriptElement(fileName: string, conditionalLoading: boolean): string;
|
|
4
|
-
export declare function getModuleScriptElement(fileName: string): string;
|
|
5
|
-
export declare function toAssetPredicate(sourceOption: PredicateSource): AssetPredicate | undefined;
|