UNPKG

@parcel/core

Version:
190 lines (164 loc) • 5.53 kB
// @flow strict-local import type { Bundle, ParcelOptions, ProcessedParcelConfig, RequestInvalidation, } from './types'; import type {SharedReference, WorkerApi} from '@parcel/workers'; import {loadConfig as configCache} from '@parcel/utils'; import type {DevDepSpecifier} from './requests/DevDepRequest'; import invariant from 'assert'; import nullthrows from 'nullthrows'; import BundleGraph from './BundleGraph'; import Transformation, { type TransformationOpts, type TransformationResult, } from './Transformation'; import {reportWorker, report} from './ReporterRunner'; import PackagerRunner, {type RunPackagerRunnerResult} from './PackagerRunner'; import Validation, {type ValidationOpts} from './Validation'; import ParcelConfig from './ParcelConfig'; import {registerCoreWithSerializer} from './registerCoreWithSerializer'; import {clearBuildCaches} from './buildCache'; import {init as initSourcemaps} from '@parcel/source-map'; import {init as initRust} from '@parcel/rust'; import WorkerFarm from '@parcel/workers'; import {setFeatureFlags} from '@parcel/feature-flags'; import '@parcel/cache'; // register with serializer import '@parcel/package-manager'; import '@parcel/fs'; // $FlowFixMe if (process.env.PARCEL_BUILD_REPL && process.browser) { /* eslint-disable import/no-extraneous-dependencies, monorepo/no-internal-import */ require('@parcel/repl/src/parcel/BrowserPackageManager.js'); // $FlowFixMe require('@parcel/repl/src/parcel/ExtendedMemoryFS.js'); /* eslint-enable import/no-extraneous-dependencies, monorepo/no-internal-import */ } registerCoreWithSerializer(); // Remove the workerApi type from the TransformationOpts and ValidationOpts types: // https://github.com/facebook/flow/issues/2835 type WorkerTransformationOpts = {| ...$Diff<TransformationOpts, {|workerApi: mixed, options: ParcelOptions|}>, optionsRef: SharedReference, configCachePath: string, |}; type WorkerValidationOpts = {| ...$Diff<ValidationOpts, {|workerApi: mixed, options: ParcelOptions|}>, optionsRef: SharedReference, configCachePath: string, |}; // TODO: this should eventually be replaced by an in memory cache layer let parcelConfigCache = new Map(); function loadOptions(ref, workerApi) { return nullthrows( ((workerApi.getSharedReference( ref, // $FlowFixMe ): any): ParcelOptions), ); } async function loadConfig(cachePath, options) { let config = parcelConfigCache.get(cachePath); if (config && config.options === options) { return config; } let processedConfig = nullthrows( await options.cache.get<ProcessedParcelConfig>(cachePath), ); config = new ParcelConfig(processedConfig, options); parcelConfigCache.set(cachePath, config); setFeatureFlags(options.featureFlags); return config; } export function clearConfigCache() { configCache.clear(); clearBuildCaches(); } export async function runTransform( workerApi: WorkerApi, opts: WorkerTransformationOpts, ): Promise<TransformationResult> { let {optionsRef, configCachePath, ...rest} = opts; let options = loadOptions(optionsRef, workerApi); let config = await loadConfig(configCachePath, options); return new Transformation({ workerApi, options, config, ...rest, }).run(); } export async function runValidate( workerApi: WorkerApi, opts: WorkerValidationOpts, ): Promise<void> { let {optionsRef, configCachePath, ...rest} = opts; let options = loadOptions(optionsRef, workerApi); let config = await loadConfig(configCachePath, options); return new Validation({ workerApi, report: reportWorker.bind(null, workerApi), options, config, ...rest, }).run(); } export async function runPackage( workerApi: WorkerApi, { bundle, bundleGraphReference, configCachePath, optionsRef, previousDevDeps, invalidDevDeps, previousInvalidations, }: {| bundle: Bundle, bundleGraphReference: SharedReference, configCachePath: string, optionsRef: SharedReference, previousDevDeps: Map<string, string>, invalidDevDeps: Array<DevDepSpecifier>, previousInvalidations: Array<RequestInvalidation>, |}, ): Promise<RunPackagerRunnerResult> { let bundleGraph = workerApi.getSharedReference(bundleGraphReference); invariant(bundleGraph instanceof BundleGraph); let options = loadOptions(optionsRef, workerApi); let parcelConfig = await loadConfig(configCachePath, options); let runner = new PackagerRunner({ config: parcelConfig, options, report: WorkerFarm.isWorker() ? reportWorker.bind(null, workerApi) : report, previousDevDeps, previousInvalidations, }); return runner.run(bundleGraph, bundle, invalidDevDeps); } export async function childInit() { await initSourcemaps; await initRust?.(); } const PKG_RE = /node_modules[/\\]((?:@[^/\\]+[/\\][^/\\]+)|[^/\\]+)(?!.*[/\\]node_modules[/\\])/; export function invalidateRequireCache(workerApi: WorkerApi, file: string) { if (process.env.PARCEL_BUILD_ENV === 'test') { // Delete this module and all children in the same node_modules folder let module = require.cache[file]; if (module) { delete require.cache[file]; let pkg = file.match(PKG_RE)?.[1]; for (let child of module.children) { if (pkg === child.id.match(PKG_RE)?.[1]) { invalidateRequireCache(workerApi, child.id); } } } parcelConfigCache.clear(); return; } throw new Error('invalidateRequireCache is only for tests'); }