Skip to content

Commit

Permalink
Parcel 2: Get some JS integration tests passing (#2484)
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett authored Jan 7, 2019
1 parent 574fa44 commit edff682
Show file tree
Hide file tree
Showing 68 changed files with 1,268 additions and 1,109 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ flow-typed

packages/*/*/test/integration/**
packages/*/*/test/mochareporters.json
packages/examples/simple/**

# Generated by the build
lib
Expand Down
26 changes: 13 additions & 13 deletions azure-pipelines-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ jobs:
vmImage: ${{ parameters.vmImage }}
strategy:
matrix:
node_6_x:
node_version: 6.x
node_8_x:
node_version: 8.x
node_10_x:
Expand Down Expand Up @@ -44,14 +42,16 @@ jobs:
displayName: 'Type check with Flow'
- script: yarn lint
displayName: 'Lint'
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFiles: '**/junit-*.xml'
testRunTitle: TestRun ${{ parameters.name }} $(node_version)
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage results'
inputs:
codeCoverageTool: 'cobertura'
summaryFileLocation: '**/coverage/cobertura-coverage.xml'
reportDirectory: '**/parcel-bundler/coverage'
- task: PublishTestResults@2
displayName: 'Publish Test Results'
condition: succeededOrFailed()
inputs:
testResultsFiles: '**/junit-*.xml'
testRunTitle: TestRun ${{ parameters.name }} $(node_version)
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage results'
condition: succeededOrFailed()
inputs:
codeCoverageTool: 'cobertura'
summaryFileLocation: '**/coverage/cobertura-coverage.xml'
reportDirectory: '**/parcel-bundler/coverage'
10 changes: 5 additions & 5 deletions packages/bundlers/default/src/DefaultBundler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow
import type {Dependency, BundleGroup, Bundle} from '@parcel/types';
import {Bundler} from '@parcel/plugin';
import path from 'path';

const ISOLATED_ENVS = new Set(['web-worker', 'service-worker']);
const OPTIONS = {
Expand All @@ -26,6 +25,7 @@ export default new Bundler({
// 6. If two assets are always seen together, put them in the same extracted bundle.

// Step 1: create bundles for each of the explicit code split points.
// $FlowFixMe
assetGraph.traverse((node, context: ?Context) => {
if (node.type === 'dependency') {
let dep: Dependency = node.value;
Expand Down Expand Up @@ -150,10 +150,10 @@ export default new Bundler({
}
}

bundleGraph.dumpGraphViz();
// bundleGraph.dumpGraphViz();

bundleGraph.traverseBundles(bundle => {
bundle.assetGraph.dumpGraphViz();
});
// bundleGraph.traverseBundles(bundle => {
// bundle.assetGraph.dumpGraphViz();
// });
}
});
29 changes: 17 additions & 12 deletions packages/core/cache/src/Cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@ import type {
} from '@parcel/types';

// These keys can affect the output, so if they differ, the cache should not match
const OPTION_KEYS = ['publicURL', 'minify', 'hmr', 'target', 'scopeHoist'];
// const OPTION_KEYS = ['publicURL', 'minify', 'hmr', 'target', 'scopeHoist'];
const OPTION_KEYS = [];

// Default cache directory name
const DEFAULT_CACHE_DIR = '.parcel-cache';

// Cache for whether a cache dir exists
const existsCache = new Set();

export default class Cache {
dir: FilePath;
dirExists: boolean;
invalidated: Set<FilePath>;
optionsHash: string;

constructor(options: CLIOptions) {
this.dir = Path.resolve(options.cacheDir || '.parcel-cache');
this.dirExists = false;
this.dir = Path.resolve(options.cacheDir || DEFAULT_CACHE_DIR);
this.invalidated = new Set();
this.optionsHash = objectHash(
OPTION_KEYS.reduce((p: JSONObject, k) => ((p[k] = options[k]), p), {
Expand All @@ -34,20 +39,19 @@ export default class Cache {
);
}

async ensureDirExists() {
if (this.dirExists) {
static async createCacheDir(dir: FilePath = DEFAULT_CACHE_DIR) {
dir = Path.resolve(dir);
if (existsCache.has(dir)) {
return;
}

await fs.mkdirp(this.dir);

// Create sub-directories for every possible hex value
// This speeds up large caches on many file systems since there are fewer files in a single directory.
for (let i = 0; i < 256; i++) {
await fs.mkdirp(Path.join(this.dir, ('00' + i.toString(16)).slice(-2)));
await fs.mkdirp(Path.join(dir, ('00' + i.toString(16)).slice(-2)));
}

this.dirExists = true;
existsCache.add(dir);
}

getCacheId(appendedData: string, env: Environment) {
Expand Down Expand Up @@ -108,7 +112,6 @@ export default class Cache {

async write(cacheEntry: CacheEntry) {
try {
await this.ensureDirExists();
let cacheId = this.getCacheId(cacheEntry.filePath, cacheEntry.env);
await this.writeBlobs(cacheEntry);
await this.writeBlob('json', cacheId, cacheEntry);
Expand All @@ -134,7 +137,9 @@ export default class Cache {
async readBlobs(asset: Asset) {
await Promise.all(
Object.keys(asset.output).map(async blobKey => {
asset.output[blobKey] = await this.readBlob(asset.output[blobKey]);
if (typeof asset.output[blobKey] === 'string') {
asset.output[blobKey] = await this.readBlob(asset.output[blobKey]);
}
})
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/core/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ let parcel = new Parcel({
cliOpts
});

// eslint-disable-next-line no-console
parcel.run().catch(console.error);
1 change: 0 additions & 1 deletion packages/core/core/src/Asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ export default class Asset implements IAsset {
}

async getPackage(): Promise<PackageJSON | null> {
// $FlowFixMe
return await this.getConfig(['package.json']);
}
}
Expand Down
41 changes: 20 additions & 21 deletions packages/core/core/src/AssetGraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {
GraphTraversalCallback,
DependencyResolution
} from '@parcel/types';
import path from 'path';
import md5 from '@parcel/utils/md5';
import createDependency from './createDependency';

Expand Down Expand Up @@ -93,7 +92,7 @@ export default class AssetGraph extends Graph {
incompleteNodes: Map<NodeId, Node>;
invalidNodes: Map<NodeId, Node>;

constructor(opts) {
constructor(opts: any) {
super(opts);
this.incompleteNodes = new Map();
this.invalidNodes = new Map();
Expand All @@ -107,15 +106,12 @@ export default class AssetGraph extends Graph {
for (let entry of entries) {
for (let target of targets) {
let node = nodeFromDep(
createDependency(
{
moduleSpecifier: entry,
target: target,
env: target.env,
isEntry: true
},
path.resolve(rootDir, 'index')
)
createDependency({
moduleSpecifier: entry,
target: target,
env: target.env,
isEntry: true
})
);

depNodes.push(node);
Expand All @@ -128,7 +124,7 @@ export default class AssetGraph extends Graph {
}
}

removeNode(node: Node) {
removeNode(node: Node): this {
this.incompleteNodes.delete(node.id);
return super.removeNode(node);
}
Expand Down Expand Up @@ -241,6 +237,10 @@ export default class AssetGraph extends Graph {
}

let node = this.getNodesConnectedFrom(depNode)[0];
if (!node) {
return {};
}

if (node.type === 'transformer_request') {
let assetNode = this.getNodesConnectedFrom(node).find(
node => node.type === 'asset' || node.type === 'asset_reference'
Expand Down Expand Up @@ -296,9 +296,12 @@ export default class AssetGraph extends Graph {
}

getEntryAssets(): Array<Asset> {
return this.getNodesConnectedFrom(this.getRootNode()).map(
node => node.value
);
let root = this.getRootNode();
if (!root) {
return [];
}

return this.getNodesConnectedFrom(root).map(node => node.value);
}

removeAsset(asset: Asset) {
Expand Down Expand Up @@ -393,13 +396,9 @@ export default class AssetGraph extends Graph {

function getEnvDescription(env: Environment) {
let description = '';
if (
env.context === 'browser' ||
env.context === 'web-worker' ||
env.context === 'service-worker'
) {
if (env.engines.browsers) {
description = `${env.context}: ${env.engines.browsers.join(', ')}`;
} else if (env.context === 'node') {
} else if (env.engines.node) {
description = `node: ${env.engines.node}`;
}

Expand Down
30 changes: 24 additions & 6 deletions packages/core/core/src/BundlerRunner.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
// @flow
import type {AssetGraph, Namer, Bundle} from '@parcel/types';
import path from 'path';
import type {
AssetGraph,
Namer,
Bundle,
FilePath,
CLIOptions
} from '@parcel/types';
import type Config from './Config';
import BundleGraph from './BundleGraph';

type Opts = {
cliOpts: CLIOptions,
config: Config,
rootDir: FilePath
};

export default class BundlerRunner {
cliOpts: CLIOptions;
config: Config;
rootDir: FilePath;

constructor(opts) {
constructor(opts: Opts) {
this.cliOpts = opts.cliOpts;
this.config = opts.config;
this.rootDir = opts.rootDir;
}

async bundle(graph: AssetGraph /* , opts */) {
async bundle(graph: AssetGraph) {
let bundler = await this.config.getBundler();

let bundleGraph = new BundleGraph();
await bundler.bundle(graph, bundleGraph);
await bundler.bundle(graph, bundleGraph, this.cliOpts);
await this.nameBundles(bundleGraph);

return bundleGraph;
Expand All @@ -33,7 +48,10 @@ export default class BundlerRunner {

async nameBundle(namers: Array<Namer>, bundle: Bundle) {
for (let namer of namers) {
let filePath = await namer.name(bundle);
let filePath = await namer.name(bundle, {
rootDir: this.rootDir
});

if (filePath) {
bundle.filePath = filePath;
return;
Expand Down
25 changes: 19 additions & 6 deletions packages/core/core/src/Graph.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
'use strict';
import type {TraversalContext} from '@parcel/types';
import type {TraversalContext, Graph as IGraph} from '@parcel/types';

export type NodeId = string;

Expand All @@ -20,18 +20,24 @@ type GraphUpdates = {
removed: Graph
};

export default class Graph {
type GraphOpts = {
nodes?: Array<[NodeId, Node]>,
edges?: Array<Edge>,
rootNodeId?: ?NodeId
};

export default class Graph implements IGraph {
nodes: Map<NodeId, Node>;
edges: Set<Edge>;
rootNodeId: ?NodeId;

constructor(opts = {}) {
constructor(opts: GraphOpts = {}) {
this.nodes = new Map(opts.nodes);
this.edges = new Set(opts.edges);
this.rootNodeId = opts.rootNodeId || null;
}

toJSON() {
toJSON(): GraphOpts {
return {
nodes: [...this.nodes],
edges: [...this.edges],
Expand Down Expand Up @@ -78,14 +84,21 @@ export default class Graph {

getNodesConnectedTo(node: Node): Array<Node> {
let edges = Array.from(this.edges).filter(edge => edge.to === node.id);
return edges.map(edge => this.nodes.get(edge.from));
return edges.map(edge => {
// $FlowFixMe
return this.nodes.get(edge.from);
});
}

getNodesConnectedFrom(node: Node): Array<Node> {
let edges = Array.from(this.edges).filter(edge => edge.from === node.id);
return edges.map(edge => this.nodes.get(edge.to));
return edges.map(edge => {
// $FlowFixMe
return this.nodes.get(edge.to);
});
}

// $FlowFixMe - fix interface
merge(graph: Graph) {
for (let [, node] of graph.nodes) {
this.addNode(node);
Expand Down
4 changes: 3 additions & 1 deletion packages/core/core/src/PackagerRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Cache from '@parcel/cache';
import {mkdirp, writeFile} from '@parcel/fs';
import path from 'path';
import type {Bundle, CLIOptions, Blob, FilePath} from '@parcel/types';
import clone from 'clone';
import AssetGraph from './AssetGraph';
import Asset from './Asset';

Expand Down Expand Up @@ -39,6 +38,7 @@ export default class PackagerRunner {
let contents = await this.package(bundle);
contents = await this.optimize(bundle, contents);

// $FlowFixMe - filePath should already be filled in at this point
let dir = path.dirname(bundle.filePath);
if (!this.distExists.has(dir)) {
await mkdirp(dir);
Expand All @@ -49,11 +49,13 @@ export default class PackagerRunner {
}

async package(bundle: Bundle): Promise<Blob> {
// $FlowFixMe - filePath should already be filled in at this point
let packager = await this.config.getPackager(bundle.filePath);
return await packager.package(bundle, this.cliOpts);
}

async optimize(bundle: Bundle, contents: Blob): Promise<Blob> {
// $FlowFixMe - filePath should already be filled in at this point
let optimizers = await this.config.getOptimizers(bundle.filePath);

for (let optimizer of optimizers) {
Expand Down
Loading

0 comments on commit edff682

Please sign in to comment.