1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _assert = _interopRequireDefault(require("assert"));
|
9 |
|
10 | var _path = _interopRequireDefault(require("path"));
|
11 |
|
12 | var _nullthrows = _interopRequireDefault(require("nullthrows"));
|
13 |
|
14 | var _utils = require("@parcel/utils");
|
15 |
|
16 | var _logger = require("@parcel/logger");
|
17 |
|
18 | var _diagnostic = _interopRequireWildcard(require("@parcel/diagnostic"));
|
19 |
|
20 | var _ConfigLoader = _interopRequireDefault(require("./ConfigLoader"));
|
21 |
|
22 | var _Dependency = require("./Dependency");
|
23 |
|
24 | var _ParcelConfig = _interopRequireDefault(require("./ParcelConfig"));
|
25 |
|
26 | var _ResolverRunner = _interopRequireDefault(require("./ResolverRunner"));
|
27 |
|
28 | var _Asset = require("./public/Asset");
|
29 |
|
30 | var _InternalAsset = _interopRequireWildcard(require("./InternalAsset"));
|
31 |
|
32 | var _summarizeRequest = _interopRequireDefault(require("./summarizeRequest"));
|
33 |
|
34 | var _PluginOptions = _interopRequireDefault(require("./public/PluginOptions"));
|
35 |
|
36 | var _constants = require("./constants");
|
37 |
|
38 | function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
39 |
|
40 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
41 |
|
42 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
43 |
|
44 | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
45 |
|
46 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
47 |
|
48 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
49 |
|
50 | class Transformation {
|
51 | constructor({
|
52 | report,
|
53 | request,
|
54 | options,
|
55 | workerApi
|
56 | }) {
|
57 | _defineProperty(this, "request", void 0);
|
58 |
|
59 | _defineProperty(this, "configLoader", void 0);
|
60 |
|
61 | _defineProperty(this, "configRequests", void 0);
|
62 |
|
63 | _defineProperty(this, "options", void 0);
|
64 |
|
65 | _defineProperty(this, "impactfulOptions", void 0);
|
66 |
|
67 | _defineProperty(this, "workerApi", void 0);
|
68 |
|
69 | _defineProperty(this, "parcelConfig", void 0);
|
70 |
|
71 | _defineProperty(this, "report", void 0);
|
72 |
|
73 | this.configRequests = [];
|
74 | this.configLoader = new _ConfigLoader.default(options);
|
75 | this.options = options;
|
76 | this.report = report;
|
77 | this.request = request;
|
78 | this.workerApi = workerApi;
|
79 |
|
80 | let {
|
81 | minify,
|
82 | hot,
|
83 | scopeHoist
|
84 | } = this.options;
|
85 | this.impactfulOptions = {
|
86 | minify,
|
87 | hot,
|
88 | scopeHoist
|
89 | };
|
90 | }
|
91 |
|
92 | async loadConfig(configRequest) {
|
93 | let result = await this.configLoader.load(configRequest);
|
94 | this.configRequests.push({
|
95 | request: configRequest,
|
96 | result
|
97 | });
|
98 | return result;
|
99 | }
|
100 |
|
101 | async run() {
|
102 | this.report({
|
103 | type: 'buildProgress',
|
104 | phase: 'transforming',
|
105 | filePath: this.request.filePath
|
106 | });
|
107 | let asset = await this.loadAsset();
|
108 | let pipeline = await this.loadPipeline(this.request.filePath, asset.value.isSource, this.request.pipeline);
|
109 | let results = await this.runPipelines(pipeline, asset);
|
110 | let assets = results.map(a => a.value);
|
111 |
|
112 | for (let {
|
113 | request,
|
114 | result
|
115 | } of this.configRequests) {
|
116 | let plugin = request.plugin != null && (await this.parcelConfig.loadPlugin(request.plugin));
|
117 |
|
118 | if (plugin && plugin.preSerializeConfig) {
|
119 | plugin.preSerializeConfig({
|
120 | config: result
|
121 | });
|
122 | }
|
123 | }
|
124 |
|
125 | return {
|
126 | assets,
|
127 | configRequests: this.configRequests
|
128 | };
|
129 | }
|
130 |
|
131 | async loadAsset() {
|
132 | let {
|
133 | filePath,
|
134 | env,
|
135 | code,
|
136 | pipeline,
|
137 | sideEffects
|
138 | } = this.request;
|
139 | let {
|
140 | content,
|
141 | size,
|
142 | hash,
|
143 | isSource
|
144 | } = await (0, _summarizeRequest.default)(this.options.inputFS, this.request);
|
145 |
|
146 |
|
147 | let idBase = code != null ? hash : filePath;
|
148 | return new _InternalAsset.default({
|
149 | idBase,
|
150 | value: (0, _InternalAsset.createAsset)({
|
151 | idBase,
|
152 | filePath,
|
153 | isSource,
|
154 | type: _path.default.extname(filePath).slice(1),
|
155 | hash,
|
156 | pipeline,
|
157 | env,
|
158 | stats: {
|
159 | time: 0,
|
160 | size
|
161 | },
|
162 | sideEffects
|
163 | }),
|
164 | options: this.options,
|
165 | content
|
166 | });
|
167 | }
|
168 |
|
169 | async runPipelines(pipeline, initialAsset) {
|
170 | var _ref;
|
171 |
|
172 | let initialType = initialAsset.value.type;
|
173 | let initialAssetCacheKey = this.getCacheKey([initialAsset], pipeline.configs);
|
174 | let initialCacheEntry = await this.readFromCache(initialAssetCacheKey);
|
175 | let assets = initialCacheEntry || (await this.runPipeline(pipeline, initialAsset));
|
176 |
|
177 | if (!initialCacheEntry) {
|
178 | await this.writeToCache(initialAssetCacheKey, assets, pipeline.configs);
|
179 | }
|
180 |
|
181 | let finalAssets = [];
|
182 |
|
183 | for (let asset of assets) {
|
184 | let nextPipeline;
|
185 |
|
186 | if (asset.value.type !== initialType) {
|
187 | nextPipeline = await this.loadNextPipeline({
|
188 | filePath: initialAsset.value.filePath,
|
189 | isSource: asset.value.isSource,
|
190 | nextType: asset.value.type,
|
191 | currentPipeline: pipeline
|
192 | });
|
193 | }
|
194 |
|
195 | if (nextPipeline) {
|
196 | let nextPipelineAssets = await this.runPipelines(nextPipeline, asset);
|
197 | finalAssets = finalAssets.concat(nextPipelineAssets);
|
198 | } else {
|
199 | finalAssets.push(asset);
|
200 | }
|
201 | }
|
202 |
|
203 | if (!pipeline.postProcess) {
|
204 | return finalAssets;
|
205 | }
|
206 |
|
207 | let processedCacheEntry = await this.readFromCache(this.getCacheKey(finalAssets, pipeline.configs));
|
208 | (0, _assert.default)(pipeline.postProcess != null);
|
209 | let processedFinalAssets = (_ref = processedCacheEntry !== null && processedCacheEntry !== void 0 ? processedCacheEntry : await pipeline.postProcess(finalAssets)) !== null && _ref !== void 0 ? _ref : [];
|
210 |
|
211 | if (!processedCacheEntry) {
|
212 | await this.writeToCache(this.getCacheKey(processedFinalAssets, pipeline.configs), processedFinalAssets, pipeline.configs);
|
213 | }
|
214 |
|
215 | return processedFinalAssets;
|
216 | }
|
217 |
|
218 | async runPipeline(pipeline, initialAsset) {
|
219 | let initialType = initialAsset.value.type;
|
220 | let inputAssets = [initialAsset];
|
221 | let resultingAssets;
|
222 | let finalAssets = [];
|
223 |
|
224 | for (let transformer of pipeline.transformers) {
|
225 | resultingAssets = [];
|
226 |
|
227 | for (let asset of inputAssets) {
|
228 | if (asset.value.type !== initialType && (await this.loadNextPipeline({
|
229 | filePath: initialAsset.value.filePath,
|
230 | isSource: asset.value.isSource,
|
231 | nextType: asset.value.type,
|
232 | currentPipeline: pipeline
|
233 | }))) {
|
234 | finalAssets.push(asset);
|
235 | continue;
|
236 | }
|
237 |
|
238 | try {
|
239 | let transformerResults = await runTransformer(pipeline, asset, transformer.plugin, transformer.name, transformer.config);
|
240 |
|
241 | for (let result of transformerResults) {
|
242 | resultingAssets.push(asset.createChildAsset(result));
|
243 | }
|
244 | } catch (e) {
|
245 | throw new _diagnostic.default({
|
246 | diagnostic: (0, _diagnostic.errorToDiagnostic)(e, transformer.name)
|
247 | });
|
248 | }
|
249 | }
|
250 |
|
251 | inputAssets = resultingAssets;
|
252 | }
|
253 |
|
254 | finalAssets = finalAssets.concat(resultingAssets);
|
255 | return Promise.all(finalAssets.map(asset => finalize((0, _nullthrows.default)(asset), (0, _nullthrows.default)(pipeline.generate))));
|
256 | }
|
257 |
|
258 | async readFromCache(cacheKey) {
|
259 | if (this.options.disableCache || this.request.code != null) {
|
260 | return null;
|
261 | }
|
262 |
|
263 | let cachedAssets = await this.options.cache.get(cacheKey);
|
264 |
|
265 | if (!cachedAssets) {
|
266 | return null;
|
267 | }
|
268 |
|
269 | return cachedAssets.map(value => new _InternalAsset.default({
|
270 | value,
|
271 | options: this.options
|
272 | }));
|
273 | }
|
274 |
|
275 | async writeToCache(cacheKey, assets, configs) {
|
276 | await Promise.all(
|
277 | assets.map(asset => asset.commit((0, _utils.md5FromObject)({
|
278 | impactfulOptions: this.impactfulOptions,
|
279 | configs: getImpactfulConfigInfo(configs)
|
280 | }))));
|
281 | this.options.cache.set(cacheKey, assets.map(a => a.value));
|
282 | }
|
283 |
|
284 | getCacheKey(assets, configs) {
|
285 | let assetsKeyInfo = assets.map(a => ({
|
286 | filePath: a.value.filePath,
|
287 | hash: a.value.hash
|
288 | }));
|
289 | return (0, _utils.md5FromObject)({
|
290 | parcelVersion: _constants.PARCEL_VERSION,
|
291 | assets: assetsKeyInfo,
|
292 | configs: getImpactfulConfigInfo(configs),
|
293 | env: this.request.env,
|
294 | impactfulOptions: this.impactfulOptions
|
295 | });
|
296 | }
|
297 |
|
298 | async loadPipeline(filePath, isSource, pipelineName) {
|
299 | let configRequest = {
|
300 | filePath,
|
301 | env: this.request.env,
|
302 | isSource,
|
303 | pipeline: pipelineName,
|
304 | meta: {
|
305 | actionType: 'transformation'
|
306 | }
|
307 | };
|
308 | let configs = new Map();
|
309 | let config = await this.loadConfig(configRequest);
|
310 | let result = (0, _nullthrows.default)(config.result);
|
311 | let parcelConfig = new _ParcelConfig.default(config.result, this.options.packageManager);
|
312 |
|
313 | this.parcelConfig = parcelConfig;
|
314 | configs.set('parcel', config);
|
315 |
|
316 | for (let [moduleName] of config.devDeps) {
|
317 | let plugin = await parcelConfig.loadPlugin(moduleName);
|
318 |
|
319 | if (plugin.loadConfig) {
|
320 | let thirdPartyConfig = await this.loadTransformerConfig({
|
321 | filePath,
|
322 | plugin: moduleName,
|
323 | parcelConfigPath: result.filePath,
|
324 | isSource
|
325 | });
|
326 | configs.set(moduleName, thirdPartyConfig);
|
327 | }
|
328 | }
|
329 |
|
330 | let transformers = await parcelConfig.getTransformers(filePath, pipelineName);
|
331 | let pipeline = {
|
332 | id: transformers.map(t => t.name).join(':'),
|
333 | transformers: transformers.map(transformer => {
|
334 | var _configs$get;
|
335 |
|
336 | return {
|
337 | name: transformer.name,
|
338 | config: (_configs$get = configs.get(transformer.name)) === null || _configs$get === void 0 ? void 0 : _configs$get.result,
|
339 | plugin: transformer.plugin
|
340 | };
|
341 | }),
|
342 | configs,
|
343 | options: this.options,
|
344 | resolverRunner: new _ResolverRunner.default({
|
345 | config: new _ParcelConfig.default((0, _nullthrows.default)((0, _nullthrows.default)(configs.get('parcel')).result), this.options.packageManager),
|
346 | options: this.options
|
347 | }),
|
348 | pluginOptions: new _PluginOptions.default(this.options),
|
349 | workerApi: this.workerApi
|
350 | };
|
351 | return pipeline;
|
352 | }
|
353 |
|
354 | async loadNextPipeline({
|
355 | filePath,
|
356 | isSource,
|
357 | nextType,
|
358 | currentPipeline
|
359 | }) {
|
360 | let nextFilePath = filePath.slice(0, -_path.default.extname(filePath).length) + '.' + nextType;
|
361 | let nextPipeline = await this.loadPipeline(nextFilePath, isSource, this.request.pipeline);
|
362 |
|
363 | if (nextPipeline.id === currentPipeline.id) {
|
364 | return null;
|
365 | }
|
366 |
|
367 | return nextPipeline;
|
368 | }
|
369 |
|
370 | loadTransformerConfig({
|
371 | filePath,
|
372 | plugin,
|
373 | parcelConfigPath,
|
374 | isSource
|
375 | }) {
|
376 | let configRequest = {
|
377 | filePath,
|
378 | env: this.request.env,
|
379 | plugin,
|
380 | isSource,
|
381 | meta: {
|
382 | parcelConfigPath
|
383 | }
|
384 | };
|
385 | return this.loadConfig(configRequest);
|
386 | }
|
387 |
|
388 | }
|
389 |
|
390 | exports.default = Transformation;
|
391 |
|
392 | async function runTransformer(pipeline, asset, transformer, transformerName, preloadedConfig) {
|
393 | const logger = new _logger.PluginLogger({
|
394 | origin: transformerName
|
395 | });
|
396 |
|
397 | const resolve = async (from, to) => {
|
398 | return (0, _nullthrows.default)((await pipeline.resolverRunner.resolve((0, _Dependency.createDependency)({
|
399 | env: asset.value.env,
|
400 | moduleSpecifier: to,
|
401 | sourcePath: from
|
402 | })))).filePath;
|
403 | };
|
404 |
|
405 |
|
406 | let config = preloadedConfig;
|
407 |
|
408 | if (transformer.getConfig) {
|
409 |
|
410 | config = await transformer.getConfig({
|
411 | asset: new _Asset.MutableAsset(asset),
|
412 | options: pipeline.pluginOptions,
|
413 | resolve,
|
414 | logger
|
415 | });
|
416 | }
|
417 |
|
418 |
|
419 |
|
420 | if (asset.ast && (!transformer.canReuseAST || !transformer.canReuseAST({
|
421 | ast: asset.ast,
|
422 | options: pipeline.pluginOptions,
|
423 | logger
|
424 | })) && pipeline.generate) {
|
425 | let output = await pipeline.generate(new _Asset.MutableAsset(asset));
|
426 | asset.content = output.code;
|
427 | asset.ast = null;
|
428 | }
|
429 |
|
430 |
|
431 | if (!asset.ast && transformer.parse) {
|
432 | asset.ast = await transformer.parse({
|
433 | asset: new _Asset.MutableAsset(asset),
|
434 | config,
|
435 | options: pipeline.pluginOptions,
|
436 | resolve,
|
437 | logger
|
438 | });
|
439 | }
|
440 |
|
441 |
|
442 | let results = await normalizeAssets((
|
443 | await transformer.transform({
|
444 | asset: new _Asset.MutableAsset(asset),
|
445 | config,
|
446 | options: pipeline.pluginOptions,
|
447 | resolve,
|
448 | logger
|
449 | })));
|
450 |
|
451 | pipeline.generate = input => {
|
452 | if (transformer.generate) {
|
453 | return Promise.resolve(transformer.generate({
|
454 | asset: input,
|
455 | config,
|
456 | options: pipeline.pluginOptions,
|
457 | resolve,
|
458 | logger
|
459 | }));
|
460 | }
|
461 |
|
462 | throw new Error('Asset has an AST but no generate method is available on the transform');
|
463 | };
|
464 |
|
465 |
|
466 | let postProcess = transformer.postProcess;
|
467 |
|
468 | if (postProcess) {
|
469 | pipeline.postProcess = async assets => {
|
470 | let results = await postProcess.call(transformer, {
|
471 | assets: assets.map(asset => new _Asset.MutableAsset(asset)),
|
472 | config,
|
473 | options: pipeline.pluginOptions,
|
474 | resolve,
|
475 | logger
|
476 | });
|
477 | return Promise.all(results.map(result => asset.createChildAsset(result)));
|
478 | };
|
479 | }
|
480 |
|
481 | return results;
|
482 | }
|
483 |
|
484 | async function finalize(asset, generate) {
|
485 | if (asset.ast && generate) {
|
486 | let result = await generate(new _Asset.MutableAsset(asset));
|
487 | return asset.createChildAsset(_objectSpread({
|
488 | type: asset.value.type,
|
489 | uniqueKey: asset.value.uniqueKey
|
490 | }, result));
|
491 | }
|
492 |
|
493 | return asset;
|
494 | }
|
495 |
|
496 | function normalizeAssets(results) {
|
497 | return results.map(result => {
|
498 | if (!(result instanceof _Asset.MutableAsset)) {
|
499 | return result;
|
500 | }
|
501 |
|
502 | let internalAsset = (0, _Asset.assetToInternalAsset)(result);
|
503 | return {
|
504 | type: result.type,
|
505 | content: internalAsset.content,
|
506 | ast: result.ast,
|
507 | map: internalAsset.map,
|
508 |
|
509 | dependencies: [...internalAsset.value.dependencies.values()],
|
510 | includedFiles: result.getIncludedFiles(),
|
511 |
|
512 | env: result.env,
|
513 | isIsolated: result.isIsolated,
|
514 | isInline: result.isInline,
|
515 | pipeline: internalAsset.value.pipeline,
|
516 | meta: result.meta,
|
517 | uniqueKey: internalAsset.value.uniqueKey
|
518 | };
|
519 | });
|
520 | }
|
521 |
|
522 | function getImpactfulConfigInfo(configs) {
|
523 | let impactfulConfigInfo = {};
|
524 |
|
525 | for (let [configType, {
|
526 | devDeps,
|
527 | resultHash
|
528 | }] of configs) {
|
529 | let devDepsObject = {};
|
530 |
|
531 | for (let [moduleName, version] of devDeps) {
|
532 | devDepsObject[moduleName] = version;
|
533 | }
|
534 |
|
535 | impactfulConfigInfo[configType] = {
|
536 | devDeps: devDepsObject,
|
537 | resultHash
|
538 | };
|
539 | }
|
540 |
|
541 | return impactfulConfigInfo;
|
542 | } |
\ | No newline at end of file |