Skip to content

Commit

Permalink
Parcel plugin dev dep cache invalidation and hot reloading (#5802)
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett authored Mar 1, 2021
1 parent c2a98c1 commit 806cc65
Show file tree
Hide file tree
Showing 58 changed files with 2,148 additions and 1,137 deletions.
1 change: 0 additions & 1 deletion packages/core/core/src/AssetGraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export function nodeFromAssetGroup(assetGroup: AssetGroup): AssetGroupNode {
code: assetGroup.code,
pipeline: assetGroup.pipeline,
query: assetGroup.query ? objectSortedEntries(assetGroup.query) : null,
invalidations: assetGroup.invalidations,
}),
type: 'asset_group',
value: assetGroup,
Expand Down
132 changes: 0 additions & 132 deletions packages/core/core/src/ConfigLoader.js

This file was deleted.

25 changes: 7 additions & 18 deletions packages/core/core/src/InternalConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,44 @@ import type {
FilePath,
PackageName,
ConfigResult,
DevDepOptions,
} from '@parcel/types';
import {md5FromString} from '@parcel/utils';
import type {Config, Environment} from './types';

type ConfigOpts = {|
plugin: PackageName,
isSource: boolean,
searchPath: FilePath,
env: Environment,
result?: ConfigResult,
includedFiles?: Set<FilePath>,
invalidateOnFileCreate?: Array<FileCreateInvalidation>,
devDeps?: Map<PackageName, ?string>,
shouldRehydrate?: boolean,
shouldReload?: boolean,
devDeps?: Array<DevDepOptions>,
shouldInvalidateOnStartup?: boolean,
|};

export function createConfig({
plugin,
isSource,
searchPath,
env,
result,
includedFiles,
invalidateOnFileCreate,
devDeps,
shouldRehydrate,
shouldReload,
shouldInvalidateOnStartup,
}: ConfigOpts): Config {
return {
id: md5FromString(plugin + searchPath + env.id + String(isSource)),
isSource,
searchPath,
env,
result: result ?? null,
resultHash: null,
includedFiles: includedFiles ?? new Set(),
invalidateOnFileCreate: invalidateOnFileCreate ?? [],
pkg: null,
pkgFilePath: null,
devDeps: devDeps ?? new Map(),
shouldRehydrate: shouldRehydrate ?? false,
shouldReload: shouldReload ?? false,
devDeps: devDeps ?? [],
shouldInvalidateOnStartup: shouldInvalidateOnStartup ?? false,
};
}

export function addDevDependency(
config: Config,
name: PackageName,
version?: string,
) {
config.devDeps.set(name, version);
}
19 changes: 14 additions & 5 deletions packages/core/core/src/ParcelConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type SerializedParcelConfig = {|
options: ParcelOptions,
|};

type LoadedPlugin<T> = {|
export type LoadedPlugin<T> = {|
name: string,
version: Semver,
plugin: T,
Expand Down Expand Up @@ -101,7 +101,7 @@ export default class ParcelConfig {

loadPlugin<T>(
node: ParcelPluginNode,
): Promise<{|plugin: T, version: Semver|}> {
): Promise<{|plugin: T, version: Semver, resolveFrom: FilePath|}> {
let plugin = this.pluginCache.get(node.packageName);
if (plugin) {
return plugin;
Expand All @@ -113,22 +113,27 @@ export default class ParcelConfig {
node.keyPath,
this.options,
);

this.pluginCache.set(node.packageName, plugin);
return plugin;
}

invalidatePlugin(packageName: PackageName) {
this.pluginCache.delete(packageName);
}

loadPlugins<T>(
plugins: PureParcelConfigPipeline,
): Promise<Array<LoadedPlugin<T>>> {
return Promise.all(
plugins.map(async p => {
let {plugin, version} = await this.loadPlugin<T>(p);
let {plugin, version, resolveFrom} = await this.loadPlugin<T>(p);
return {
name: p.packageName,
plugin,
version,
resolveFrom: p.resolveFrom,
keyPath: p.keyPath,
resolveFrom,
};
}),
);
Expand Down Expand Up @@ -231,7 +236,11 @@ export default class ParcelConfig {
return this.bundler.packageName;
}
getBundler(): Promise<{|version: Semver, plugin: Bundler|}> {
getBundler(): Promise<{|
version: Semver,
plugin: Bundler,
resolveFrom: FilePath,
|}> {
if (!this.bundler) {
throw new Error('No bundler specified in .parcelrc config');
}
Expand Down
22 changes: 21 additions & 1 deletion packages/core/core/src/RequestTracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ export type RunAPI = {|
invalidateOnOptionChange: string => void,
getInvalidations(): Array<RequestInvalidation>,
storeResult: (result: mixed, cacheKey?: string) => void,
getRequestResult<T>(id: string): Async<?T>,
getSubRequests(): Array<StoredRequest>,
canSkipSubrequest(string): boolean,
runRequest: <TInput, TResult>(
subRequest: Request<TInput, TResult>,
Expand Down Expand Up @@ -478,11 +480,27 @@ export class RequestGraph extends Graph<
return {type: 'file', filePath: node.value.filePath};
case 'env':
return {type: 'env', key: node.value.key};
case 'option':
return {type: 'option', key: node.value.key};
}
})
.filter(Boolean);
}

getSubRequests(requestId: string): Array<StoredRequest> {
if (!this.hasNode(requestId)) {
return [];
}

let requestNode = this.getRequestNode(requestId);
let subRequests = this.getNodesConnectedFrom(requestNode, 'subrequest');

return subRequests.map(node => {
invariant(node.type === 'request');
return node.value;
});
}

invalidateFileNameNode(
node: FileNameNode,
filePath: FilePath,
Expand Down Expand Up @@ -753,7 +771,7 @@ export default class RequestTracker {
createAPI(requestId: string): {|api: RunAPI, subRequests: Set<NodeId>|} {
let subRequests = new Set();
let invalidations = this.graph.getInvalidations(requestId);
let api = {
let api: RunAPI = {
invalidateOnFileCreate: input =>
this.graph.invalidateOnFileCreate(requestId, input),
invalidateOnFileDelete: filePath =>
Expand All @@ -773,6 +791,8 @@ export default class RequestTracker {
storeResult: (result, cacheKey) => {
this.storeResult(requestId, result, cacheKey);
},
getSubRequests: () => this.graph.getSubRequests(requestId),
getRequestResult: <T>(id): Async<?T> => this.getRequestResult<T>(id),
canSkipSubrequest: id => {
if (this.hasValidResult(id)) {
subRequests.add(id);
Expand Down
Loading

0 comments on commit 806cc65

Please sign in to comment.