Skip to content

Commit

Permalink
Merge branch 'v2' of github.com:parcel-bundler/parcel into add-multi-…
Browse files Browse the repository at this point in the history
…module-compilation-for-elm
  • Loading branch information
ChristophP committed May 20, 2022
2 parents 004a394 + 97a7864 commit e6d0c08
Show file tree
Hide file tree
Showing 86 changed files with 1,661 additions and 1,004 deletions.
411 changes: 199 additions & 212 deletions Cargo.lock

Large diffs are not rendered by default.

363 changes: 116 additions & 247 deletions packages/bundlers/experimental/src/ExperimentalBundler.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/core/cache/package.json
Expand Up @@ -27,7 +27,7 @@
"@parcel/fs": "2.5.0",
"@parcel/logger": "2.5.0",
"@parcel/utils": "2.5.0",
"lmdb": "2.3.7"
"lmdb": "2.3.10"
},
"peerDependencies": {
"@parcel/core": "^2.5.0"
Expand Down
3 changes: 3 additions & 0 deletions packages/core/core/src/ParcelConfig.schema.js
Expand Up @@ -93,6 +93,9 @@ const mapStringSchema = (pluginType: string, key: string): SchemaEntity => {
export default {
type: 'object',
properties: {
$schema: {
type: 'string',
},
extends: {
oneOf: [
{
Expand Down
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
6 changes: 3 additions & 3 deletions packages/core/integration-tests/test/cache.js
Expand Up @@ -4901,17 +4901,17 @@ describe('cache', function () {
},
async update(b) {
let res = await run(b.bundleGraph);
assert(res.includes("let a = 'a'"));
assert(res.includes(`let a = "a"`));

await overlayFS.writeFile(
path.join(inputDir, 'src/entries/a.js'),
"export let a = 'b';",
`export let a = "b";`,
);
},
});

let res = await run(b.bundleGraph);
assert(res.includes("let a = 'b'"));
assert(res.includes(`let a = "b"`));
});

it('should invalidate when switching to a different packager for an inline bundle', async function () {
Expand Down
52 changes: 52 additions & 0 deletions packages/core/integration-tests/test/elm.js
Expand Up @@ -81,4 +81,56 @@ describe('elm', function () {
assert(js.includes('Elm'));
assert(js.includes('init'));
});

it('should produce correct formatting and indentation when compilation fails', async function () {
const normalizedPath = path.normalize(
'test/integration/elm-compile-error/src/Main.elm',
);
await assert.rejects(
() =>
bundle(path.join(__dirname, 'integration/elm-compile-error/index.js'), {
mode: 'production',
}),

{
name: 'BuildError',
diagnostics: [
{
message:
'\n' +
`-- TYPE MISMATCH --------------- ${normalizedPath}\n` +
'\n' +
'The 1st argument to `text` is not what I expect:\n' +
'\n' +
'7| Html.text 5 "Hello, world!"\n' +
' **^**\n' +
'This argument is a number of type:\n' +
'\n' +
' **number**\n' +
'\n' +
'But `text` needs the 1st argument to be:\n' +
'\n' +
' **String**\n' +
'\n' +
'__Hint__: Try using **String.fromInt** to convert it to a string?',
origin: '@parcel/elm-transformer',
stack: '',
},
{
message:
'\n' +
`-- TOO MANY ARGS --------------- ${normalizedPath}\n` +
'\n' +
'The `text` function expects 1 argument, but it got 2 instead.\n' +
'\n' +
'7| Html.text 5 "Hello, world!"\n' +
' **^^^^^^^^^**\n' +
'Are there any missing commas? Or missing parentheses?',
origin: '@parcel/elm-transformer',
stack: '',
},
],
},
);
});
});
2 changes: 1 addition & 1 deletion packages/core/integration-tests/test/fs.js
Expand Up @@ -198,7 +198,7 @@ describe('fs', function () {
path.join(distDir, 'index.js'),
'utf8',
);
assert(contents.includes("require('fs')"));
assert(contents.includes(`require("fs")`));
assert(contents.includes('readFileSync'));

await outputFS.writeFile(
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
34 changes: 32 additions & 2 deletions packages/core/integration-tests/test/html.js
Expand Up @@ -2549,7 +2549,7 @@ describe('html', function () {
await getNextBuild(b);

let html = await outputFS.readFile('/dist/index.html', 'utf8');
assert(html.includes("console.log('test')"));
assert(html.includes(`console.log("test")`));

await overlayFS.writeFile(
path.join(__dirname, '/html-inline-js-require/test.js'),
Expand All @@ -2558,7 +2558,7 @@ describe('html', function () {
await getNextBuild(b);

html = await outputFS.readFile(path.join(distDir, '/index.html'), 'utf8');
assert(html.includes("console.log('foo')"));
assert(html.includes(`console.log("foo")`));
});

it('should invalidate parent bundle when nested inline bundles change', async function () {
Expand Down Expand Up @@ -2841,4 +2841,34 @@ describe('html', function () {
},
);
});

it('extracts shared bundles that load referenced bundle roots across entries', async () => {
let b = await bundle(
['index1.html', 'index2.html'].map(entry =>
path.join(__dirname, 'integration/html-shared-referenced', entry),
),
{
mode: 'production',
defaultTargetOptions: {
shouldOptimize: false,
},
},
);

await run(b);
});

it('should not skip bundleRoots if an asset is both async required and static required', async function () {
let b = await bundle(
path.join(__dirname, 'integration/html-sync-async-asset/index.html'),
{
mode: 'production',
defaultTargetOptions: {
shouldOptimize: false,
},
},
);

await run(b, {output: null}, {require: false});
});
});
@@ -0,0 +1,24 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.1",
"elm/core": "1.0.2",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

0 comments on commit e6d0c08

Please sign in to comment.