mirror of https://github.com/status-im/metro.git
Move Cache into DependencyGraph
Reviewed By: martinbigio Differential Revision: D2758776 fb-gh-sync-id: 15fb232e00267698e386d5422cb70e2091dabcdd
This commit is contained in:
parent
3f81ea5844
commit
90d1b6ee62
|
@ -14,7 +14,7 @@ const path = require('path');
|
|||
const Promise = require('promise');
|
||||
const ProgressBar = require('progress');
|
||||
const BundlesLayout = require('../BundlesLayout');
|
||||
const Cache = require('../Cache');
|
||||
const Cache = require('../DependencyResolver/Cache');
|
||||
const Transformer = require('../JSTransformer');
|
||||
const Resolver = require('../Resolver');
|
||||
const Bundle = require('./Bundle');
|
||||
|
@ -23,6 +23,7 @@ const Activity = require('../Activity');
|
|||
const ModuleTransport = require('../lib/ModuleTransport');
|
||||
const declareOpts = require('../lib/declareOpts');
|
||||
const imageSize = require('image-size');
|
||||
const version = require('../../../../package.json').version;
|
||||
|
||||
const sizeOf = Promise.denodeify(imageSize);
|
||||
const readFile = Promise.denodeify(fs.readFile);
|
||||
|
@ -88,11 +89,23 @@ class Bundler {
|
|||
|
||||
opts.projectRoots.forEach(verifyRootExists);
|
||||
|
||||
let mtime;
|
||||
try {
|
||||
({mtime} = fs.statSync(opts.transformModulePath));
|
||||
mtime = String(mtime.getTime());
|
||||
} catch (error) {
|
||||
mtime = '';
|
||||
}
|
||||
|
||||
this._cache = new Cache({
|
||||
resetCache: opts.resetCache,
|
||||
cacheVersion: opts.cacheVersion,
|
||||
projectRoots: opts.projectRoots,
|
||||
transformModulePath: opts.transformModulePath,
|
||||
cacheKey: [
|
||||
'react-packager-cache',
|
||||
version,
|
||||
opts.cacheVersion,
|
||||
opts.projectRoots.join(',').split(path.sep).join('-'),
|
||||
mtime
|
||||
].join('$'),
|
||||
});
|
||||
|
||||
this._resolver = new Resolver({
|
||||
|
@ -365,7 +378,7 @@ class Bundler {
|
|||
generateAssetModule(bundle, module, platform = null) {
|
||||
const relPath = getPathRelativeToRoot(this._projectRoots, module.path);
|
||||
var assetUrlPath = path.join('/assets', path.dirname(relPath));
|
||||
|
||||
|
||||
// On Windows, change backslashes to slashes to get proper URL path from file path.
|
||||
if (path.sep === '\\') {
|
||||
assetUrlPath = assetUrlPath.replace(/\\/g, '/');
|
||||
|
|
|
@ -14,7 +14,7 @@ jest.dontMock('../index')
|
|||
var Promise = require('promise');
|
||||
var BundlesLayout = require('../index');
|
||||
var Resolver = require('../../Resolver');
|
||||
var loadCacheSync = require('../../lib/loadCacheSync');
|
||||
var loadCacheSync = require('../../DependencyResolver/Cache/lib/loadCacheSync');
|
||||
|
||||
describe('BundlesLayout', () => {
|
||||
function newBundlesLayout(options) {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
jest
|
||||
.autoMockOff()
|
||||
.mock('../../Cache')
|
||||
.mock('../../DependencyResolver/Cache')
|
||||
.mock('../../Activity');
|
||||
|
||||
const Promise = require('promise');
|
||||
|
@ -19,7 +19,7 @@ const path = require('path');
|
|||
jest.mock('fs');
|
||||
|
||||
var BundlesLayout = require('../index');
|
||||
var Cache = require('../../Cache');
|
||||
var Cache = require('../../DependencyResolver/Cache');
|
||||
var Resolver = require('../../Resolver');
|
||||
var fs = require('fs');
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@ const Activity = require('../Activity');
|
|||
const _ = require('underscore');
|
||||
const declareOpts = require('../lib/declareOpts');
|
||||
const fs = require('fs');
|
||||
const getCacheFilePath = require('../lib/getCacheFilePath');
|
||||
const loadCacheSync = require('../lib/loadCacheSync');
|
||||
const getCacheFilePath = require('../DependencyResolver/Cache/lib/getCacheFilePath');
|
||||
const loadCacheSync = require('../DependencyResolver/Cache/lib/loadCacheSync');
|
||||
const version = require('../../../../package.json').version;
|
||||
const path = require('path');
|
||||
const tmpdir = require('os').tmpDir();
|
||||
|
||||
const validateOpts = declareOpts({
|
||||
dependencyResolver: {
|
||||
|
@ -189,6 +190,7 @@ class BundlesLayout {
|
|||
|
||||
_getCacheFilePath(options) {
|
||||
return getCacheFilePath(
|
||||
tmpdir,
|
||||
'react-packager-bundles-cache-',
|
||||
version,
|
||||
options.projectRoots.join(',').split(path.sep).join('-'),
|
||||
|
|
|
@ -9,38 +9,35 @@
|
|||
'use strict';
|
||||
|
||||
jest
|
||||
.dontMock('underscore')
|
||||
.dontMock('absolute-path')
|
||||
.dontMock('../')
|
||||
.dontMock('../../lib/loadCacheSync')
|
||||
.dontMock('../../lib/getCacheFilePath');
|
||||
.dontMock('../lib/loadCacheSync')
|
||||
.dontMock('../lib/getCacheFilePath');
|
||||
|
||||
jest
|
||||
.mock('fs')
|
||||
.setMock('os', {
|
||||
tmpDir() { return 'tmpDir'; }
|
||||
tmpDir() { return 'tmpDir'; },
|
||||
});
|
||||
|
||||
var Promise = require('promise');
|
||||
var fs = require('fs');
|
||||
var _ = require('underscore');
|
||||
|
||||
var Cache = require('../');
|
||||
|
||||
describe('JSTransformer Cache', () => {
|
||||
describe('Cache', () => {
|
||||
describe('getting/setting', () => {
|
||||
pit('calls loader callback for uncached file', () => {
|
||||
fs.stat.mockImpl((file, callback) => {
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => {}
|
||||
}
|
||||
getTime: () => {},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var loaderCb = jest.genMockFn().mockImpl(() => Promise.resolve());
|
||||
|
||||
|
@ -55,14 +52,13 @@ describe('JSTransformer Cache', () => {
|
|||
fs.stat.mockImpl((file, callback) => {
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => {}
|
||||
}
|
||||
getTime: () => {},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var index = 0;
|
||||
var loaderCb = jest.genMockFn().mockImpl(() =>
|
||||
|
@ -83,14 +79,13 @@ describe('JSTransformer Cache', () => {
|
|||
fs.stat.mockImpl((file, callback) =>
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => {}
|
||||
}
|
||||
getTime: () => {},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var loaderCb = jest.genMockFn().mockImpl(() =>
|
||||
Promise.resolve('lol')
|
||||
|
@ -105,14 +100,13 @@ describe('JSTransformer Cache', () => {
|
|||
fs.stat.mockImpl((file, callback) => {
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => {}
|
||||
}
|
||||
getTime: () => {},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var loaderCb = jest.genMockFn().mockImpl(() =>
|
||||
Promise.resolve('lol')
|
||||
|
@ -135,14 +129,13 @@ describe('JSTransformer Cache', () => {
|
|||
fs.stat.mockImpl((file, callback) => {
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => mtime++
|
||||
}
|
||||
getTime: () => mtime++,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var loaderCb = jest.genMockFn().mockImpl(() =>
|
||||
Promise.resolve('lol' + mtime)
|
||||
|
@ -167,14 +160,14 @@ describe('JSTransformer Cache', () => {
|
|||
fileStats = {
|
||||
'/rootDir/someFile': {
|
||||
mtime: {
|
||||
getTime: () => 22
|
||||
}
|
||||
getTime: () => 22,
|
||||
},
|
||||
},
|
||||
'/rootDir/foo': {
|
||||
mtime: {
|
||||
getTime: () => 11
|
||||
}
|
||||
}
|
||||
getTime: () => 11,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
fs.existsSync.mockImpl(() => true);
|
||||
|
@ -189,14 +182,13 @@ describe('JSTransformer Cache', () => {
|
|||
'/rootDir/foo': {
|
||||
metadata: {mtime: 11},
|
||||
data: {field: 'lol wat'},
|
||||
}
|
||||
},
|
||||
}));
|
||||
});
|
||||
|
||||
pit('should load cache from disk', () => {
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var loaderCb = jest.genMockFn();
|
||||
|
||||
|
@ -219,16 +211,15 @@ describe('JSTransformer Cache', () => {
|
|||
fs.stat.mockImpl((file, callback) =>
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => {}
|
||||
}
|
||||
getTime: () => {},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
fileStats['/rootDir/foo'].mtime.getTime = () => 123;
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
var loaderCb = jest.genMockFn().mockImpl(() =>
|
||||
Promise.resolve('new value')
|
||||
|
@ -254,26 +245,17 @@ describe('JSTransformer Cache', () => {
|
|||
it('should write cache to disk', () => {
|
||||
var index = 0;
|
||||
var mtimes = [10, 20, 30];
|
||||
var debounceIndex = 0;
|
||||
_.debounce = callback => {
|
||||
return () => {
|
||||
if (++debounceIndex === 3) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
fs.stat.mockImpl((file, callback) =>
|
||||
callback(null, {
|
||||
mtime: {
|
||||
getTime: () => mtimes[index++]
|
||||
}
|
||||
getTime: () => mtimes[index++],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
var cache = new Cache({
|
||||
projectRoots: ['/rootDir'],
|
||||
transformModulePath: 'x.js',
|
||||
cacheKey: 'cache',
|
||||
});
|
||||
|
||||
cache.get('/rootDir/bar', 'field', () =>
|
||||
|
@ -286,7 +268,10 @@ describe('JSTransformer Cache', () => {
|
|||
Promise.resolve('baz value')
|
||||
);
|
||||
|
||||
jest.runAllTicks();
|
||||
// jest has some trouble with promises and timeouts within promises :(
|
||||
jest.runAllTimers();
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(fs.writeFile).toBeCalled();
|
||||
});
|
||||
});
|
|
@ -9,50 +9,37 @@
|
|||
'use strict';
|
||||
|
||||
const Promise = require('promise');
|
||||
const _ = require('underscore');
|
||||
const declareOpts = require('../lib/declareOpts');
|
||||
const fs = require('fs');
|
||||
const getCacheFilePath = require('../lib/getCacheFilePath');
|
||||
const getCacheFilePath = require('./lib/getCacheFilePath');
|
||||
const isAbsolutePath = require('absolute-path');
|
||||
const loadCacheSync = require('../lib/loadCacheSync');
|
||||
const path = require('path');
|
||||
const version = require('../../../../package.json').version;
|
||||
const loadCacheSync = require('./lib/loadCacheSync');
|
||||
const tmpdir = require('os').tmpDir();
|
||||
|
||||
const validateOpts = declareOpts({
|
||||
resetCache: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
cacheVersion: {
|
||||
type: 'string',
|
||||
default: '1.0',
|
||||
},
|
||||
projectRoots: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
},
|
||||
transformModulePath: {
|
||||
type:'string',
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
function getObjectValues(object) {
|
||||
return Object.keys(object).map(key => object[key]);
|
||||
}
|
||||
|
||||
function debounce(fn, delay) {
|
||||
var timeout;
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(fn, delay);
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: move to Packager directory
|
||||
class Cache {
|
||||
constructor(options) {
|
||||
var opts = validateOpts(options);
|
||||
|
||||
this._cacheFilePath = this._getCacheFilePath(opts);
|
||||
|
||||
var data;
|
||||
if (!opts.resetCache) {
|
||||
data = this._loadCacheSync(this._cacheFilePath);
|
||||
constructor({
|
||||
resetCache,
|
||||
cacheKey,
|
||||
}) {
|
||||
this._cacheFilePath = getCacheFilePath(tmpdir, cacheKey);
|
||||
if (!resetCache) {
|
||||
this._data = this._loadCacheSync(this._cacheFilePath);
|
||||
} else {
|
||||
data = Object.create(null);
|
||||
this._data = Object.create(null);
|
||||
}
|
||||
this._data = data;
|
||||
|
||||
this._persistEventually = _.debounce(
|
||||
this._persistEventually = debounce(
|
||||
this._persistCache.bind(this),
|
||||
2000,
|
||||
);
|
||||
|
@ -124,10 +111,10 @@ class Cache {
|
|||
var data = this._data;
|
||||
var cacheFilepath = this._cacheFilePath;
|
||||
|
||||
var allPromises = _.values(data)
|
||||
var allPromises = getObjectValues(data)
|
||||
.map(record => {
|
||||
var fieldNames = Object.keys(record.data);
|
||||
var fieldValues = _.values(record.data);
|
||||
var fieldValues = getObjectValues(record.data);
|
||||
|
||||
return Promise
|
||||
.all(fieldValues)
|
||||
|
@ -187,25 +174,6 @@ class Cache {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
_getCacheFilePath(options) {
|
||||
let mtime;
|
||||
try {
|
||||
({mtime} = fs.statSync(options.transformModulePath));
|
||||
mtime = String(mtime.getTime());
|
||||
} catch (error) {
|
||||
mtime = '';
|
||||
}
|
||||
|
||||
return getCacheFilePath(
|
||||
'react-packager-cache-',
|
||||
version,
|
||||
options.projectRoots.join(',').split(path.sep).join('-'),
|
||||
options.cacheVersion || '0',
|
||||
options.transformModulePath,
|
||||
mtime
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Cache;
|
|
@ -10,16 +10,11 @@
|
|||
|
||||
const crypto = require('crypto');
|
||||
const path = require('path');
|
||||
const tmpdir = require('os').tmpDir();
|
||||
|
||||
function getCacheFilePath(...args) {
|
||||
args = Array.prototype.slice.call(args);
|
||||
const prefix = args.shift();
|
||||
|
||||
let hash = crypto.createHash('md5');
|
||||
function getCacheFilePath(tmpdir, ...args) {
|
||||
const hash = crypto.createHash('md5');
|
||||
args.forEach(arg => hash.update(arg));
|
||||
|
||||
return path.join(tmpdir, prefix + hash.digest('hex'));
|
||||
return path.join(tmpdir, hash.digest('hex'));
|
||||
}
|
||||
|
||||
module.exports = getCacheFilePath;
|
|
@ -14,7 +14,7 @@ jest
|
|||
|
||||
jest.mock('fs');
|
||||
|
||||
var Cache = require('../../Cache');
|
||||
var Cache = require('../../DependencyResolver/Cache');
|
||||
var Transformer = require('../');
|
||||
var fs = require('fs');
|
||||
|
||||
|
|
Loading…
Reference in New Issue