Skip to content

Commit 2d4055e

Browse files
author
Amjad Masad
committed
[react-packager] Rewrite dependency graph (support node_modules, speed, fix bugs etc)
Summary: @public Fixes facebook#773, facebook#1055 The resolver was getting a bit unwieldy because a lot has changed since the initial writing (porting node-haste). This also splits up a large complex file into the following: * Makes use of classes: Module, AssetModule, Package, and AssetModule_DEPRECATED (`image!` modules) * DependencyGraph is lazy for everything that isn't haste modules and packages (need to read ahead of time) * Lazy makes it fast, easier to reason about, and easier to add new loaders * Has a centralized filesystem wrapper: fast-fs (ffs) * ffs is async and lazy for any read operation and sync for directory/file lookup which makes it fast * we can easily drop in different adapters for ffs to be able to build up the tree: watchman, git ls-files, etc * use es6 for classes and easier to read promise-based code Follow up diffs will include: * Using new types (Module, AssetModule etc) in the rest of the codebase (currently we convert to plain object which is a bit of a hack) * using watchman to build up the fs * some caching at the object creation level (we are recreating Modules and Packages many times, we can cache them) * A plugin system for loaders (e.g. @tadeuzagallo wants to add a native module loader) Test Plan: * ./runJestTests.sh react-packager * ./runJestTests.sh PackagerIntegration * Export open source and run the e2e test * reset cache * ./fbrnios.sh run and click around
1 parent 5c1ac2a commit 2d4055e

File tree

33 files changed

+4884
-2895
lines changed

33 files changed

+4884
-2895
lines changed

Libraries/JavaScriptAppEngine/Initialization/SourceMap.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
/**
23
* Copyright (c) 2015-present, Facebook, Inc.
34
* All rights reserved.
@@ -8,6 +9,7 @@
89
*
910
* @providesModule SourceMap
1011
* @generated
12+
* @extern
1113
*
1214
* This module was generated from `node_modules/source-map` by running
1315
*

packager/blacklist.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
// Don't forget to everything listed here to `testConfig.json`
1212
// modulePathIgnorePatterns.
1313
var sharedBlacklist = [
14-
__dirname,
1514
'website',
1615
'node_modules/react-tools/src/utils/ImmutableObject.js',
1716
'node_modules/react-tools/src/core/ReactInstanceHandles.js',

packager/react-packager/.babelrc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Keep in sync with packager/transformer.js
2+
{
3+
"retainLines": true,
4+
"compact": true,
5+
"comments": false,
6+
"whitelist": [
7+
"es6.arrowFunctions",
8+
"es6.blockScoping",
9+
// This is the only place where we differ from transformer.js
10+
"es6.constants",
11+
"es6.classes",
12+
"es6.destructuring",
13+
"es6.parameters.rest",
14+
"es6.properties.computed",
15+
"es6.properties.shorthand",
16+
"es6.spread",
17+
"es6.templateLiterals",
18+
"es7.trailingFunctionCommas",
19+
"es7.objectRestSpread",
20+
"flow",
21+
"react"
22+
],
23+
"sourceMaps": false
24+
}

packager/react-packager/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
*/
99
'use strict';
1010

11+
require('babel/register')({
12+
only: /react-packager\/src/
13+
});
14+
1115
useGracefulFs();
1216

1317
var Activity = require('./src/Activity');

packager/react-packager/src/AssetServer/index.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var Promise = require('bluebird');
1515
var fs = require('fs');
1616
var crypto = require('crypto');
1717

18-
var lstat = Promise.promisify(fs.lstat);
18+
var stat = Promise.promisify(fs.stat);
1919
var readDir = Promise.promisify(fs.readdir);
2020
var readFile = Promise.promisify(fs.readFile);
2121

@@ -98,14 +98,14 @@ AssetServer.prototype.getAssetData = function(assetPath) {
9898

9999
return Promise.all(
100100
record.files.map(function(file) {
101-
return lstat(file);
101+
return stat(file);
102102
})
103103
);
104104
}).then(function(stats) {
105105
var hash = crypto.createHash('md5');
106106

107-
stats.forEach(function(stat) {
108-
hash.update(stat.mtime.getTime().toString());
107+
stats.forEach(function(fstat) {
108+
hash.update(fstat.mtime.getTime().toString());
109109
});
110110

111111
data.hash = hash.digest('hex');
@@ -117,18 +117,18 @@ function findRoot(roots, dir) {
117117
return Promise.some(
118118
roots.map(function(root) {
119119
var absPath = path.join(root, dir);
120-
return lstat(absPath).then(function(stat) {
121-
if (!stat.isDirectory()) {
120+
return stat(absPath).then(function(fstat) {
121+
if (!fstat.isDirectory()) {
122122
throw new Error('Looking for dirs');
123123
}
124-
stat._path = absPath;
125-
return stat;
124+
fstat._path = absPath;
125+
return fstat;
126126
});
127127
}),
128128
1
129129
).spread(
130-
function(stat) {
131-
return stat._path;
130+
function(fstat) {
131+
return fstat._path;
132132
}
133133
);
134134
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
const Module = require('./Module');
4+
const Promise = require('bluebird');
5+
const getAssetDataFromName = require('../lib/getAssetDataFromName');
6+
7+
class AssetModule extends Module {
8+
9+
isHaste() {
10+
return Promise.resolve(false);
11+
}
12+
13+
getDependencies() {
14+
return Promise.resolve([]);
15+
}
16+
17+
_read() {
18+
return Promise.resolve({});
19+
}
20+
21+
getName() {
22+
return super.getName().then(id => {
23+
const {name, type} = getAssetDataFromName(this.path);
24+
return id.replace(/\/[^\/]+$/, `/${name}.${type}`);
25+
});
26+
}
27+
28+
getPlainObject() {
29+
return this.getName().then(name => this.addReference({
30+
path: this.path,
31+
isJSON: false,
32+
isAsset: true,
33+
isAsset_DEPRECATED: false,
34+
isPolyfill: false,
35+
resolution: getAssetDataFromName(this.path).resolution,
36+
id: name,
37+
dependencies: [],
38+
}));
39+
}
40+
41+
hash() {
42+
return `AssetModule : ${this.path}`;
43+
}
44+
}
45+
46+
module.exports = AssetModule;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
const Module = require('./Module');
4+
const Promise = require('bluebird');
5+
const getAssetDataFromName = require('../lib/getAssetDataFromName');
6+
7+
class AssetModule_DEPRECATED extends Module {
8+
isHaste() {
9+
return Promise.resolve(false);
10+
}
11+
12+
getName() {
13+
return Promise.resolve(this.name);
14+
}
15+
16+
getDependencies() {
17+
return Promise.resolve([]);
18+
}
19+
20+
getPlainObject() {
21+
const {name, resolution} = getAssetDataFromName(this.path);
22+
23+
return Promise.resolve(this.addReference({
24+
path: this.path,
25+
id: `image!${name}`,
26+
resolution,
27+
isAsset_DEPRECATED: true,
28+
dependencies: [],
29+
isJSON: false,
30+
isPolyfill: false,
31+
isAsset: false,
32+
}));
33+
}
34+
35+
hash() {
36+
return `AssetModule_DEPRECATED : ${this.path}`;
37+
}
38+
}
39+
40+
module.exports = AssetModule_DEPRECATED;

0 commit comments

Comments
 (0)