Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Commit

Permalink
Improvements for transforms running before dependecy extraction
Browse files Browse the repository at this point in the history
- passes through transform options when getting dependencies
- passes back all properties provided by a custom transform
- `ModuleCache` can create `Polyfill` objects that are completly functional
- `ResolutionRequest` parallelizes dependency extraction instead of running it serially
  • Loading branch information
davidaurelio committed Feb 17, 2016
1 parent 201e32d commit 980f968
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 40 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-haste",
"version": "2.0.0",
"version": "2.1.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/node-haste.git"
Expand Down
44 changes: 26 additions & 18 deletions src/DependencyGraph/ResolutionRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ class ResolutionRequest {
);
}

getOrderedDependencies(response, mocksPattern, recursive = true) {
getOrderedDependencies(
response,
mocksPattern,
transformOptions,
recursive = true,
) {
return this._getAllMocks(mocksPattern).then(allMocks => {
const entry = this._moduleCache.getModule(this._entryPath);
const mocks = Object.create(null);
Expand All @@ -113,7 +118,7 @@ class ResolutionRequest {

response.pushDependency(entry);
const collect = (mod) => {
return mod.getDependencies().then(
return mod.getDependencies(transformOptions).then(
depNames => Promise.all(
depNames.map(name => this.resolveDependency(mod, name))
).then((dependencies) => [depNames, dependencies])
Expand All @@ -137,9 +142,8 @@ class ResolutionRequest {
return [depNames, dependencies];
});
}
return Promise.resolve([depNames, dependencies]);
return [depNames, dependencies];
}).then(([depNames, dependencies]) => {
let p = Promise.resolve();
const filteredPairs = [];

dependencies.forEach((modDep, i) => {
Expand Down Expand Up @@ -167,24 +171,21 @@ class ResolutionRequest {

response.setResolvedDependencyPairs(mod, filteredPairs);

filteredPairs.forEach(([depName, modDep]) => {
p = p.then(() => {
if (!visited[modDep.hash()]) {
return Promise.all(
filteredPairs
.filter(([, modDep]) => !visited[modDep.hash()])
.map(([depName, modDep]) => {
visited[modDep.hash()] = true;
response.pushDependency(modDep);
if (recursive) {
return collect(modDep);
}
}
return null;
});
});

return p;
return Promise.all([modDep, recursive ? collect(modDep) : []]);
})
);
});
};

return collect(entry).then(() => response.setMocks(mocks));
return collect(entry).then(deps => {
recursiveFlatten(deps).forEach(dep => response.pushDependency(dep));
response.setMocks(mocks);
});
});
}

Expand Down Expand Up @@ -443,4 +444,11 @@ function normalizePath(modulePath) {
return modulePath.replace(/\/$/, '');
}

function recursiveFlatten(array) {
return Array.prototype.concat.apply(
Array.prototype,
array.map(item => Array.isArray(item) ? recursiveFlatten(item) : item)
);
}

module.exports = ResolutionRequest;
21 changes: 11 additions & 10 deletions src/Module.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,22 +133,23 @@ class Module {
return Promise.all([
fileContentPromise,
this._readDocBlock(fileContentPromise),
]).then(([code, {id, moduleDocBlock}]) => {
]).then(([source, {id, moduleDocBlock}]) => {
// Ignore requires in JSON files or generated code. An example of this
// is prebuilt files like the SourceMap library.
if (this.isJSON() || 'extern' in moduleDocBlock) {
return {id, code, dependencies: []};
return {id, code: source, source, dependencies: []};
} else {
const transformCode = this._transformCode;
const codePromise = transformCode
? transformCode(this, code, transformOptions)
: Promise.resolve({code});

return codePromise.then(({code, dependencies, map}) => {
if (!dependencies) {
dependencies = this._extractor(code).deps.sync;
}
return {id, code, dependencies, map};
? transformCode(this, source, transformOptions)
: Promise.resolve({code: source});

return codePromise.then(result => {
const {
code,
dependencies = this._extractor(code).deps.sync,
} = result;
return {...result, dependencies, id, source};
});
}
});
Expand Down
12 changes: 12 additions & 0 deletions src/ModuleCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const AssetModule = require('./AssetModule');
const Package = require('./Package');
const Module = require('./Module');
const Polyfill = require('./Polyfill');
const path = require('fast-path');

class ModuleCache {
Expand Down Expand Up @@ -87,6 +88,17 @@ class ModuleCache {
return this.getPackage(packagePath);
}

createPolyfill({file}) {
return new Polyfill({
file,
cache: this._cache,
depGraphHelpers: this._depGraphHelpers,
fastfs: this._fastfs,
moduleCache: this,
transformCode: this._transformCode,
});
}

_processFileChange(type, filePath, root) {
const absPath = path.join(root, filePath);

Expand Down
8 changes: 4 additions & 4 deletions src/Polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ const Promise = require('promise');
const Module = require('./Module');

class Polyfill extends Module {
constructor({ path, id, dependencies }) {
super({ file: path });
this._id = id;
this._dependencies = dependencies;
constructor(options) {
super(options);
this._id = options.id;
this._dependencies = options.dependencies;
}

isHaste() {
Expand Down
8 changes: 4 additions & 4 deletions src/__tests__/DependencyGraph-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const mocksPattern = /(?:[\\/]|^)__mocks__[\\/]([^\/]+)\.js$/;
describe('DependencyGraph', function() {
let defaults;

function getOrderedDependenciesAsJSON(dgraph, entry, platform, recursive = true) {
return dgraph.getDependencies(entry, platform, recursive)
function getOrderedDependenciesAsJSON(dgraph, entryPath, platform, recursive = true) {
return dgraph.getDependencies({entryPath, platform, recursive})
.then(response => response.finalize())
.then(({ dependencies }) => Promise.all(dependencies.map(dep => Promise.all([
dep.getName(),
Expand Down Expand Up @@ -4110,7 +4110,7 @@ describe('DependencyGraph', function() {
roots: [root],
});

return dgraph.getDependencies('/root/index.js')
return dgraph.getDependencies({entryPath: '/root/index.js'})
.then(response => response.finalize())
.then(response => {
expect(response.mocks).toEqual({});
Expand Down Expand Up @@ -4140,7 +4140,7 @@ describe('DependencyGraph', function() {
mocksPattern,
});

return dgraph.getDependencies('/root/b.js')
return dgraph.getDependencies({entryPath: '/root/b.js'})
.then(response => response.finalize())
.then(response => {
expect(response.mocks).toEqual({
Expand Down
22 changes: 22 additions & 0 deletions src/__tests__/Module-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,22 @@ describe('Module', () => {
});
});

pit('forwards all additional properties of the result provided by `transformCode`', () => {
const mockedResult = {
code: exampleCode,
arbitrary: 'arbitrary',
dependencyOffsets: [12, 764],
map: {version: 3},
subObject: {foo: 'bar'},
};
transformCode.mockReturnValue(Promise.resolve(mockedResult));
const module = createModule({transformCode});

return module.read().then((result) => {
expect(result).toEqual(jasmine.objectContaining(mockedResult));
});
});

pit('exposes the transformed code rather than the raw file contents', () => {
transformCode.mockReturnValue(Promise.resolve({code: exampleCode}));
const module = createModule({transformCode});
Expand All @@ -261,6 +277,12 @@ describe('Module', () => {
});
});

pit('exposes the raw file contents as `source` property', () => {
const module = createModule({transformCode});
return module.read()
.then(data => expect(data.source).toBe(fileContents));
});

pit('exposes a source map returned by the transform', () => {
const map = {version: 3};
transformCode.mockReturnValue(Promise.resolve({map, code: exampleCode}));
Expand Down
12 changes: 9 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,10 @@ class DependencyGraph {
* Returns a promise with the direct dependencies the module associated to
* the given entryPath has.
*/
getShallowDependencies(entryPath) {
return this._moduleCache.getModule(entryPath).getDependencies();
getShallowDependencies(entryPath, transformOptions) {
return this._moduleCache
.getModule(entryPath)
.getDependencies(transformOptions);
}

getFS() {
Expand All @@ -184,7 +186,7 @@ class DependencyGraph {
return this.load().then(() => this._moduleCache.getAllModules());
}

getDependencies(entryPath, platform, recursive = true) {
getDependencies({entryPath, platform, transformOptions, recursive = true}) {
return this.load().then(() => {
platform = this._getRequestPlatform(entryPath, platform);
const absPath = this._getAbsolutePath(entryPath);
Expand All @@ -205,6 +207,7 @@ class DependencyGraph {
return req.getOrderedDependencies(
response,
this._opts.mocksPattern,
transformOptions,
recursive,
).then(() => response);
});
Expand Down Expand Up @@ -279,6 +282,9 @@ class DependencyGraph {
});
}

createPolyfill(options) {
return this._moduleCache.createPolyfill(options);
}
}

Object.assign(DependencyGraph, {
Expand Down

0 comments on commit 980f968

Please sign in to comment.