Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parcel plugin dev dep cache invalidation and hot reloading #5802

Merged
merged 21 commits into from Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
caeb12c
Track dev deps of transformers
devongovett Feb 8, 2021
e2919be
Merge branch 'v2' of github.com:parcel-bundler/parcel into dev-dep-in…
devongovett Feb 14, 2021
ce495e7
Move plugin cache just before returning to avoid race conditions
devongovett Feb 14, 2021
6fb3272
Fix paths on windows
devongovett Feb 15, 2021
0d17250
Refactor config loading and add dev deps for plugins
devongovett Feb 16, 2021
055fae0
Fix unit tests
devongovett Feb 16, 2021
3c41e86
Add tests for postcss plugin invalidation
devongovett Feb 16, 2021
3ff170e
Add posthtml plugin dev dependencies
devongovett Feb 17, 2021
50a0122
Invalidate when a closer config is added
devongovett Feb 17, 2021
58fb42e
Reuse config dev deps that didn't change and provide default for conf…
devongovett Feb 18, 2021
c06567d
Refactor to handle config dev deps and transformer dev deps in one place
devongovett Feb 19, 2021
54ffc2d
Fix invalidating require cache on windows
devongovett Feb 21, 2021
8503782
Merge branch 'v2' of github.com:parcel-bundler/parcel into dev-dep-in…
devongovett Feb 21, 2021
3a1ad5a
Fix lint
devongovett Feb 21, 2021
59557ec
Merge branch 'v2' into dev-dep-invalidation
devongovett Feb 25, 2021
76ae8dd
Fix unit test
devongovett Feb 25, 2021
ad42126
Merge branch 'v2' into dev-dep-invalidation
devongovett Feb 26, 2021
b348433
Upgrade babel core, remove unnecessary invalidations
devongovett Feb 27, 2021
4dc8e07
Remove unnecessary awaits
devongovett Feb 27, 2021
a2eb5b5
Add comment to explain invalidateParcelPlugin option
devongovett Feb 27, 2021
f3e3ae2
Merge branch 'v2' of github.com:parcel-bundler/parcel into dev-dep-in…
devongovett Mar 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/core/core/src/AssetGraph.js
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
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
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
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