Skip to content

Commit

Permalink
Merge branch 'v2' into add-multi-module-compilation-for-elm
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristophP committed May 9, 2022
2 parents 004a394 + e51955f commit 3c9eb60
Show file tree
Hide file tree
Showing 18 changed files with 449 additions and 75 deletions.
67 changes: 65 additions & 2 deletions packages/core/core/src/Transformation.js
Expand Up @@ -74,9 +74,14 @@ import {
toProjectPath,
} from './projectPath';
import {invalidateOnFileCreateToInternal} from './utils';
import invariant from 'assert';

type GenerateFunc = (input: UncommittedAsset) => Promise<GenerateOutput>;

type PostProcessFunc = (
Array<UncommittedAsset>,
) => Promise<Array<UncommittedAsset> | null>;

export type TransformationOpts = {|
options: ParcelOptions,
config: ParcelConfig,
Expand Down Expand Up @@ -336,7 +341,34 @@ export default class Transformation {
}
}

return finalAssets;
if (!pipeline.postProcess) {
return finalAssets;
}

let pipelineHash = await this.getPipelineHash(pipeline);
let invalidationHash = await getInvalidationHash(
finalAssets.flatMap(asset => asset.getInvalidations()),
this.options,
);
let processedCacheEntry = await this.readFromCache(
this.getCacheKey(finalAssets, invalidationHash, pipelineHash),
);

invariant(pipeline.postProcess != null);
let processedFinalAssets: Array<UncommittedAsset> =
processedCacheEntry ?? (await pipeline.postProcess(finalAssets)) ?? [];

if (!processedCacheEntry) {
await this.writeToCache(
this.getCacheKey(processedFinalAssets, invalidationHash, pipelineHash),
processedFinalAssets,

invalidationHash,
pipelineHash,
);
}

return processedFinalAssets;
}

async getPipelineHash(pipeline: Pipeline): Promise<string> {
Expand Down Expand Up @@ -426,6 +458,8 @@ export default class Transformation {
transformer.plugin,
transformer.name,
transformer.config,
transformer.configKeyPath,
this.parcelConfig,
);

for (let result of transformerResults) {
Expand Down Expand Up @@ -695,6 +729,8 @@ export default class Transformation {
transformer: Transformer<mixed>,
transformerName: string,
preloadedConfig: ?Config,
configKeyPath?: string,
parcelConfig: ParcelConfig,
): Promise<$ReadOnlyArray<TransformerResult | UncommittedAsset>> {
const logger = new PluginLogger({origin: transformerName});

Expand Down Expand Up @@ -786,7 +822,7 @@ export default class Transformation {
});
let results = await normalizeAssets(this.options, transfomerResult);

// Create generate function that can be called later
// Create generate and postProcess function that can be called later
asset.generate = (): Promise<GenerateOutput> => {
let publicAsset = new Asset(asset);
if (transformer.generate && asset.ast) {
Expand All @@ -805,6 +841,32 @@ export default class Transformation {
);
};

let postProcess = transformer.postProcess;
if (postProcess) {
pipeline.postProcess = async (
assets: Array<UncommittedAsset>,
): Promise<Array<UncommittedAsset> | null> => {
let results = await postProcess.call(transformer, {
assets: assets.map(asset => new MutableAsset(asset)),
config,
options: pipeline.pluginOptions,
resolve,
logger,
});

return Promise.all(
results.map(result =>
asset.createChildAsset(
result,
transformerName,
parcelConfig.filePath,
// configKeyPath,
),
),
);
};
}

return results;
}
}
Expand All @@ -816,6 +878,7 @@ type Pipeline = {|
pluginOptions: PluginOptions,
resolverRunner: ResolverRunner,
workerApi: WorkerApi,
postProcess?: PostProcessFunc,
generate?: GenerateFunc,
|};

Expand Down
56 changes: 54 additions & 2 deletions packages/core/integration-tests/test/hmr.js
Expand Up @@ -10,6 +10,7 @@ import {
overlayFS,
sleep,
run,
request,
} from '@parcel/test-utils';
import WebSocket from 'ws';
import json5 from 'json5';
Expand Down Expand Up @@ -110,6 +111,7 @@ describe('hmr', function () {
return {
outputs: JSON.parse(JSON.stringify(outputs)),
reloaded,
bundleGraph,
};
}

Expand Down Expand Up @@ -157,10 +159,12 @@ describe('hmr', function () {
assert.equal(message.type, 'update');

// Figure out why output doesn't change...
let localAsset = message.assets.find(
asset => asset.output === 'exports.a = 5;\nexports.b = 5;\n',
let localAsset = message.assets.find(asset =>
asset.output.includes('exports.a = 5;\nexports.b = 5;\n'),
);
assert(!!localAsset);
assert(localAsset.output.includes('//# sourceMappingURL'));
assert(localAsset.output.includes('//# sourceURL'));
});

it('should emit an HMR update for all new dependencies along with the changed file', async function () {
Expand Down Expand Up @@ -331,6 +335,31 @@ describe('hmr', function () {

assert.equal(message.type, 'update');
});

it('should respond to requests for assets by id', async function () {
let port = await getPort();
let b = bundler(path.join(__dirname, '/input/index.js'), {
serveOptions: {port},
hmrOptions: {port},
inputFS: overlayFS,
config,
});

subscription = await b.watch();
let event = await getNextBuild(b);

let bundleGraph = nullthrows(event.bundleGraph);
let asset = nullthrows(bundleGraph.getBundles()[0].getMainEntry());
let contents = await request('/__parcel_hmr/' + asset.id, port);
let publicId = nullthrows(bundleGraph).getAssetPublicId(asset);
assert(
contents.startsWith(
`parcelHotUpdate['${publicId}'] = function (require, module, exports) {`,
),
);
assert(contents.includes('//# sourceMappingURL'));
assert(contents.includes('//# sourceURL'));
});
});

// TODO: add test for 4532 (`require` call in modified asset in child bundle where HMR runtime runs in parent bundle)
Expand Down Expand Up @@ -548,6 +577,29 @@ module.hot.dispose((data) => {
assert.notEqual(url.search, search);
});

it('should have correct source locations in errors', async function () {
let {outputs, bundleGraph} = await testHMRClient(
'hmr-accept-self',
() => {
return {
'local.js': 'output(new Error().stack);',
};
},
);

let asset = bundleGraph
.getBundles()[0]
.traverseAssets((asset, _, actions) => {
if (asset.filePath.endsWith('local.js')) {
actions.stop();
return asset;
}
});

let stack = outputs.pop();
assert(stack.includes('/__parcel_hmr/' + nullthrows(asset).id));
});

/*
it.skip('should accept HMR updates in the runtime after an initial error', async function() {
await fs.mkdirp(path.join(__dirname, '/input'));
Expand Down
28 changes: 1 addition & 27 deletions packages/core/integration-tests/test/server.js
Expand Up @@ -10,8 +10,8 @@ import {
outputFS,
overlayFS,
ncp,
request as get,
} from '@parcel/test-utils';
import http from 'http';
import https from 'https';
import getPort from 'get-port';
import type {BuildEvent} from '@parcel/types';
Expand All @@ -22,32 +22,6 @@ const config = path.join(
'./integration/custom-configs/.parcelrc-dev-server',
);

function get(file, port, client = http) {
return new Promise((resolve, reject) => {
// $FlowFixMe
client.get(
{
hostname: 'localhost',
port: port,
path: file,
rejectUnauthorized: false,
},
res => {
res.setEncoding('utf8');
let data = '';
res.on('data', c => (data += c));
res.on('end', () => {
if (res.statusCode !== 200) {
return reject({statusCode: res.statusCode, data});
}

resolve(data);
});
},
);
});
}

describe('server', function () {
let subscription;

Expand Down
34 changes: 34 additions & 0 deletions packages/core/test-utils/src/utils.js
Expand Up @@ -27,6 +27,8 @@ import nullthrows from 'nullthrows';
import {parser as postHtmlParse} from 'posthtml-parser';
import postHtml from 'posthtml';
import EventEmitter from 'events';
import http from 'http';
import https from 'https';

import {makeDeferredWithPromise, normalizeSeparators} from '@parcel/utils';
import _chalk from 'chalk';
Expand Down Expand Up @@ -734,6 +736,8 @@ function prepareBrowserContext(
},
URL,
Worker: createWorkerClass(bundle.filePath),
addEventListener() {},
removeEventListener() {},
},
globals,
);
Expand Down Expand Up @@ -1157,3 +1161,33 @@ export async function assertNoFilePathInCache(
}
}
}

export function request(
file: string,
port: number,
client: typeof http | typeof https = http,
): Promise<string> {
return new Promise((resolve, reject) => {
// $FlowFixMe
client.get(
{
hostname: 'localhost',
port: port,
path: file,
rejectUnauthorized: false,
},
res => {
res.setEncoding('utf8');
let data = '';
res.on('data', c => (data += c));
res.on('end', () => {
if (res.statusCode !== 200) {
return reject({statusCode: res.statusCode, data});
}

resolve(data);
});
},
);
});
}
21 changes: 14 additions & 7 deletions packages/core/types/index.js
Expand Up @@ -186,7 +186,7 @@ export type EnvironmentOptions = {|
*/
export type VersionMap = {
[string]: string,
...,
...
};

export type EnvironmentFeature =
Expand Down Expand Up @@ -398,9 +398,7 @@ export interface AssetSymbols // eslint-disable-next-line no-undef
* This is the default state.
*/
+isCleared: boolean;
get(
exportSymbol: Symbol,
): ?{|
get(exportSymbol: Symbol): ?{|
local: Symbol,
loc: ?SourceLocation,
meta?: ?Meta,
Expand Down Expand Up @@ -443,9 +441,7 @@ export interface MutableDependencySymbols // eslint-disable-next-line no-undef
* This is the default state.
*/
+isCleared: boolean;
get(
exportSymbol: Symbol,
): ?{|
get(exportSymbol: Symbol): ?{|
local: Symbol,
loc: ?SourceLocation,
isWeak: boolean,
Expand Down Expand Up @@ -1045,6 +1041,17 @@ export type Transformer<ConfigType> = {|
options: PluginOptions,
logger: PluginLogger,
|}): Async<Array<TransformerResult | MutableAsset>>,
/**
* Do some processing after the transformation
* @experimental
*/
postProcess?: ({|
assets: Array<MutableAsset>,
config: ConfigType,
resolve: ResolveFn,
options: PluginOptions,
logger: PluginLogger,
|}) => Async<Array<TransformerResult>>,
/** Stringify the AST */
generate?: ({|
asset: Asset,
Expand Down

0 comments on commit 3c9eb60

Please sign in to comment.