/
Pipeline.js
117 lines (100 loc) Β· 3.11 KB
/
Pipeline.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
const Parser = require('./Parser');
const path = require('path');
/**
* A Pipeline composes multiple Asset types together.
*/
class Pipeline {
constructor(options) {
this.options = options;
this.parser = new Parser(options);
}
async process(path, isWarmUp) {
let options = this.options;
if (isWarmUp) {
options = Object.assign({isWarmUp}, options);
}
let asset = this.parser.getAsset(path, options);
let generated = await this.processAsset(asset);
let generatedMap = {};
for (let rendition of generated) {
generatedMap[rendition.type] = rendition.value;
}
return {
id: asset.id,
dependencies: Array.from(asset.dependencies.values()),
generated: generatedMap,
hash: asset.hash,
cacheData: asset.cacheData
};
}
async processAsset(asset) {
try {
await asset.process();
} catch (err) {
throw asset.generateErrorMessage(err);
}
let inputType = path.extname(asset.name).slice(1);
let generated = [];
for (let rendition of this.iterateRenditions(asset)) {
let {type, value} = rendition;
if (typeof value !== 'string' || rendition.final) {
generated.push(rendition);
continue;
}
// Find an asset type for the rendition type.
// If the asset is not already an instance of this asset type, process it.
let AssetType = this.parser.findParser(
asset.name.slice(0, -inputType.length) + type,
true
);
if (!(asset instanceof AssetType)) {
let opts = Object.assign({}, asset.options, {rendition});
let subAsset = new AssetType(asset.name, opts);
subAsset.id = asset.id;
subAsset.contents = value;
subAsset.dependencies = asset.dependencies;
subAsset.cacheData = Object.assign(asset.cacheData, subAsset.cacheData);
let processed = await this.processAsset(subAsset);
if (rendition.meta) {
for (let res of processed) {
res.meta = rendition.meta;
}
}
generated = generated.concat(processed);
} else {
generated.push(rendition);
}
}
// Post process. This allows assets a chance to modify the output produced by sub-asset types.
try {
generated = await asset.postProcess(generated);
} catch (err) {
throw asset.generateErrorMessage(err);
}
asset.generated = generated;
asset.hash = await asset.generateHash();
return generated;
}
*iterateRenditions(asset) {
if (Array.isArray(asset.generated)) {
return yield* asset.generated;
}
if (typeof asset.generated === 'string') {
return yield {
type: asset.type,
value: asset.generated
};
}
// Backward compatibility support for the old API.
// Assume all renditions are final - don't compose asset types together.
for (let type in asset.generated) {
yield {
type,
value: asset.generated[type],
// for scope hoisting, we need to post process all JS
final: !(type === 'js' && this.options.scopeHoist)
};
}
}
}
module.exports = Pipeline;