mirror of https://github.com/status-im/metro.git
Sync new haste features from upstream
Reviewed By: amasad Differential Revision: D2644383 fb-gh-sync-id: 5225e6afb8e5b835865473b2880a77235e6bd6eb
This commit is contained in:
parent
ccea74fc87
commit
a8ded758d0
|
@ -15,7 +15,8 @@ const Promise = require('promise');
|
|||
const GENERIC_PLATFORM = 'generic';
|
||||
|
||||
class HasteMap {
|
||||
constructor({ fastfs, moduleCache, helpers }) {
|
||||
constructor({ extensions, fastfs, moduleCache, helpers }) {
|
||||
this._extensions = extensions;
|
||||
this._fastfs = fastfs;
|
||||
this._moduleCache = moduleCache;
|
||||
this._helpers = helpers;
|
||||
|
@ -24,7 +25,7 @@ class HasteMap {
|
|||
build() {
|
||||
this._map = Object.create(null);
|
||||
|
||||
let promises = this._fastfs.findFilesByExt('js', {
|
||||
let promises = this._fastfs.findFilesByExts(this._extensions, {
|
||||
ignore: (file) => this._helpers.isNodeModulesDir(file),
|
||||
}).map(file => this._processHasteModule(file));
|
||||
|
||||
|
@ -57,8 +58,7 @@ class HasteMap {
|
|||
}
|
||||
}
|
||||
|
||||
if (this._helpers.extname(absPath) === 'js' ||
|
||||
this._helpers.extname(absPath) === 'json') {
|
||||
if (this._extensions.indexOf(this._helpers.extname(absPath)) !== -1) {
|
||||
if (path.basename(absPath) === 'package.json') {
|
||||
return this._processHastePackage(absPath);
|
||||
} else {
|
||||
|
|
|
@ -97,8 +97,10 @@ class ResolutionRequest {
|
|||
);
|
||||
}
|
||||
|
||||
getOrderedDependencies(response) {
|
||||
return Promise.resolve().then(() => {
|
||||
getOrderedDependencies(response, mocksPattern) {
|
||||
return this._getAllMocks(mocksPattern).then(mocks => {
|
||||
response.setMocks(mocks);
|
||||
|
||||
const entry = this._moduleCache.getModule(this._entryPath);
|
||||
const visited = Object.create(null);
|
||||
visited[entry.hash()] = true;
|
||||
|
@ -110,8 +112,20 @@ class ResolutionRequest {
|
|||
depNames.map(name => this.resolveDependency(mod, name))
|
||||
).then((dependencies) => [depNames, dependencies])
|
||||
).then(([depNames, dependencies]) => {
|
||||
if (mocks) {
|
||||
return mod.getName().then(name => {
|
||||
if (mocks[name]) {
|
||||
const mockModule =
|
||||
this._moduleCache.getModule(mocks[name]);
|
||||
depNames.push(name);
|
||||
dependencies.push(mockModule);
|
||||
}
|
||||
return [depNames, dependencies];
|
||||
});
|
||||
}
|
||||
return Promise.resolve([depNames, dependencies]);
|
||||
}).then(([depNames, dependencies]) => {
|
||||
let p = Promise.resolve();
|
||||
|
||||
const filteredPairs = [];
|
||||
|
||||
dependencies.forEach((modDep, i) => {
|
||||
|
@ -163,6 +177,20 @@ class ResolutionRequest {
|
|||
));
|
||||
}
|
||||
|
||||
_getAllMocks(pattern) {
|
||||
// Take all mocks in all the roots into account. This is necessary
|
||||
// because currently mocks are global: any module can be mocked by
|
||||
// any mock in the system.
|
||||
let mocks = null;
|
||||
if (pattern) {
|
||||
mocks = Object.create(null);
|
||||
this._fastfs.matchFilesByPattern(pattern).forEach(file =>
|
||||
mocks[path.basename(file, path.extname(file))] = file
|
||||
);
|
||||
}
|
||||
return Promise.resolve(mocks);
|
||||
}
|
||||
|
||||
_resolveHasteDependency(fromModule, toModuleName) {
|
||||
toModuleName = normalizePath(toModuleName);
|
||||
|
||||
|
@ -349,6 +377,7 @@ class ResolutionRequest {
|
|||
_resetResolutionCache() {
|
||||
this._immediateResolutionCache = Object.create(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ class ResolutionResponse {
|
|||
this.dependencies = [];
|
||||
this.asyncDependencies = [];
|
||||
this.mainModuleId = null;
|
||||
this.mocks = null;
|
||||
this._mappings = Object.create(null);
|
||||
this._finalized = false;
|
||||
}
|
||||
|
@ -64,6 +65,10 @@ class ResolutionResponse {
|
|||
}
|
||||
}
|
||||
|
||||
setMocks(mocks) {
|
||||
this.mocks = mocks;
|
||||
}
|
||||
|
||||
getResolvedDependencyPairs(module) {
|
||||
this._assertFinalized();
|
||||
return this._mappings[module.hash()];
|
||||
|
|
|
@ -3676,4 +3676,184 @@ describe('DependencyGraph', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Extensions', () => {
|
||||
pit('supports custom file extensions', () => {
|
||||
var root = '/root';
|
||||
fs.__setMockFilesystem({
|
||||
'root': {
|
||||
'index.jsx': [
|
||||
'/**',
|
||||
' * @providesModule index',
|
||||
' */',
|
||||
'require("a")',
|
||||
].join('\n'),
|
||||
'a.coffee': [
|
||||
'/**',
|
||||
' * @providesModule a',
|
||||
' */',
|
||||
].join('\n'),
|
||||
'X.js': '',
|
||||
},
|
||||
});
|
||||
|
||||
var dgraph = new DependencyGraph({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
extensions: ['jsx', 'coffee'],
|
||||
});
|
||||
|
||||
return dgraph.matchFilesByPattern('.*')
|
||||
.then(files => {
|
||||
expect(files).toEqual([
|
||||
'/root/index.jsx', '/root/a.coffee',
|
||||
]);
|
||||
})
|
||||
.then(() => getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx'))
|
||||
.then(deps => {
|
||||
expect(deps).toEqual([
|
||||
{
|
||||
dependencies: ['a'],
|
||||
id: 'index',
|
||||
isAsset: false,
|
||||
isAsset_DEPRECATED: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
path: '/root/index.jsx',
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
dependencies: [],
|
||||
id: 'a',
|
||||
isAsset: false,
|
||||
isAsset_DEPRECATED: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
path: '/root/a.coffee',
|
||||
resolution: undefined,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Mocks', () => {
|
||||
pit('resolves to null if mocksPattern is not specified', () => {
|
||||
var root = '/root';
|
||||
fs.__setMockFilesystem({
|
||||
'root': {
|
||||
'__mocks': {
|
||||
'A.js': '',
|
||||
},
|
||||
'index.js': '',
|
||||
},
|
||||
});
|
||||
var dgraph = new DependencyGraph({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
});
|
||||
|
||||
return dgraph.getDependencies('/root/index.js')
|
||||
.then(response => response.finalize())
|
||||
.then(response => {
|
||||
expect(response.mocks).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
pit('retrieves a list of all mocks in the system', () => {
|
||||
var root = '/root';
|
||||
fs.__setMockFilesystem({
|
||||
'root': {
|
||||
'__mocks__': {
|
||||
'A.js': '',
|
||||
'b.js': '',
|
||||
},
|
||||
'b.js': [
|
||||
'/**',
|
||||
' * @providesModule b',
|
||||
' */',
|
||||
].join('\n'),
|
||||
},
|
||||
});
|
||||
|
||||
var dgraph = new DependencyGraph({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
mocksPattern: /(?:[\\/]|^)__mocks__[\\/]([^\/]+)\.js$/,
|
||||
});
|
||||
|
||||
return dgraph.getDependencies('/root/b.js')
|
||||
.then(response => response.finalize())
|
||||
.then(response => {
|
||||
expect(response.mocks).toEqual({
|
||||
A: '/root/__mocks__/A.js',
|
||||
b: '/root/__mocks__/b.js',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
pit('adds mocks as a dependency of their actual module', () => {
|
||||
var root = '/root';
|
||||
fs.__setMockFilesystem({
|
||||
'root': {
|
||||
'__mocks__': {
|
||||
'A.js': [
|
||||
'require("b");',
|
||||
].join('\n'),
|
||||
'b.js': '',
|
||||
},
|
||||
'A.js': [
|
||||
'/**',
|
||||
' * @providesModule A',
|
||||
' */',
|
||||
'require("foo");',
|
||||
].join('\n'),
|
||||
'foo.js': [
|
||||
'/**',
|
||||
' * @providesModule foo',
|
||||
' */',
|
||||
].join('\n'),
|
||||
},
|
||||
});
|
||||
|
||||
var dgraph = new DependencyGraph({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
mocksPattern: /(?:[\\/]|^)__mocks__[\\/]([^\/]+)\.js$/,
|
||||
});
|
||||
|
||||
return getOrderedDependenciesAsJSON(dgraph, '/root/A.js')
|
||||
.then(deps => {
|
||||
expect(deps).toEqual([
|
||||
{
|
||||
path: '/root/A.js',
|
||||
isJSON: false,
|
||||
isAsset: false,
|
||||
isAsset_DEPRECATED: false,
|
||||
isPolyfill: false,
|
||||
id: 'A',
|
||||
dependencies: ['foo', 'A'],
|
||||
},
|
||||
{
|
||||
path: '/root/foo.js',
|
||||
isJSON: false,
|
||||
isAsset: false,
|
||||
isAsset_DEPRECATED: false,
|
||||
isPolyfill: false,
|
||||
id: 'foo',
|
||||
dependencies: [],
|
||||
},
|
||||
{
|
||||
path: '/root/__mocks__/A.js',
|
||||
isJSON: false,
|
||||
isAsset: false,
|
||||
isAsset_DEPRECATED: false,
|
||||
isPolyfill: false,
|
||||
id: '/root/__mocks__/A.js',
|
||||
dependencies: ['b'],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -38,6 +38,9 @@ class DependencyGraph {
|
|||
providesModuleNodeModules,
|
||||
platforms,
|
||||
cache,
|
||||
extensions,
|
||||
mocksPattern,
|
||||
extractRequires,
|
||||
}) {
|
||||
this._opts = {
|
||||
activity: activity || defaultActivity,
|
||||
|
@ -49,6 +52,9 @@ class DependencyGraph {
|
|||
providesModuleNodeModules,
|
||||
platforms: platforms || [],
|
||||
cache,
|
||||
extensions: extensions || ['js', 'json'],
|
||||
mocksPattern,
|
||||
extractRequires,
|
||||
};
|
||||
this._cache = this._opts.cache;
|
||||
this._helpers = new Helpers(this._opts);
|
||||
|
@ -70,7 +76,7 @@ class DependencyGraph {
|
|||
const allRoots = this._opts.roots.concat(this._opts.assetRoots_DEPRECATED);
|
||||
this._crawling = crawl(allRoots, {
|
||||
ignore: this._opts.ignoreFilePath,
|
||||
exts: ['js', 'json'].concat(this._opts.assetExts),
|
||||
exts: this._opts.extensions.concat(this._opts.assetExts),
|
||||
fileWatcher: this._opts.fileWatcher,
|
||||
});
|
||||
this._crawling.then((files) => activity.endEvent(crawlActivity));
|
||||
|
@ -88,10 +94,15 @@ class DependencyGraph {
|
|||
|
||||
this._fastfs.on('change', this._processFileChange.bind(this));
|
||||
|
||||
this._moduleCache = new ModuleCache(this._fastfs, this._cache);
|
||||
this._moduleCache = new ModuleCache(
|
||||
this._fastfs,
|
||||
this._cache,
|
||||
this._opts.extractRequires
|
||||
);
|
||||
|
||||
this._hasteMap = new HasteMap({
|
||||
fastfs: this._fastfs,
|
||||
extensions: this._opts.extensions,
|
||||
moduleCache: this._moduleCache,
|
||||
assetExts: this._opts.exts,
|
||||
helpers: this._helpers,
|
||||
|
@ -138,12 +149,16 @@ class DependencyGraph {
|
|||
const response = new ResolutionResponse();
|
||||
|
||||
return Promise.all([
|
||||
req.getOrderedDependencies(response),
|
||||
req.getOrderedDependencies(response, this._opts.mocksPattern),
|
||||
req.getAsyncDependencies(response),
|
||||
]).then(() => response);
|
||||
});
|
||||
}
|
||||
|
||||
matchFilesByPattern(pattern) {
|
||||
return this.load().then(() => this._fastfs.matchFilesByPattern(pattern));
|
||||
}
|
||||
|
||||
_getRequestPlatform(entryPath, platform) {
|
||||
if (platform == null) {
|
||||
platform = getPlatformExtension(entryPath);
|
||||
|
@ -208,6 +223,7 @@ class DependencyGraph {
|
|||
return this._loading;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function NotFoundError() {
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
const docblock = require('./DependencyGraph/docblock');
|
||||
const isAbsolutePath = require('absolute-path');
|
||||
const path = require('path');
|
||||
const replacePatterns = require('./replacePatterns');
|
||||
const extractRequires = require('./lib/extractRequires');
|
||||
|
||||
class Module {
|
||||
|
||||
constructor(file, fastfs, moduleCache, cache) {
|
||||
constructor(file, fastfs, moduleCache, cache, extractor) {
|
||||
if (!isAbsolutePath(file)) {
|
||||
throw new Error('Expected file to be absolute path but got ' + file);
|
||||
}
|
||||
|
@ -26,12 +26,11 @@ class Module {
|
|||
this._fastfs = fastfs;
|
||||
this._moduleCache = moduleCache;
|
||||
this._cache = cache;
|
||||
this._extractor = extractor;
|
||||
}
|
||||
|
||||
isHaste() {
|
||||
return this._cache.get(this.path, 'haste', () =>
|
||||
this._read().then(data => !!data.id)
|
||||
);
|
||||
return this._read().then(data => !!data.id);
|
||||
}
|
||||
|
||||
getName() {
|
||||
|
@ -67,19 +66,17 @@ class Module {
|
|||
}
|
||||
|
||||
getDependencies() {
|
||||
return this._cache.get(this.path, 'dependencies', () =>
|
||||
this._read().then(data => data.dependencies)
|
||||
);
|
||||
}
|
||||
|
||||
invalidate() {
|
||||
this._cache.invalidate(this.path);
|
||||
return this._read().then(data => data.dependencies);
|
||||
}
|
||||
|
||||
getAsyncDependencies() {
|
||||
return this._read().then(data => data.asyncDependencies);
|
||||
}
|
||||
|
||||
invalidate() {
|
||||
this._cache.invalidate(this.path);
|
||||
}
|
||||
|
||||
_read() {
|
||||
if (!this._reading) {
|
||||
this._reading = this._fastfs.readFile(this.path).then(content => {
|
||||
|
@ -96,7 +93,7 @@ class Module {
|
|||
if ('extern' in moduleDocBlock) {
|
||||
data.dependencies = [];
|
||||
} else {
|
||||
var dependencies = extractRequires(content);
|
||||
var dependencies = (this._extractor || extractRequires)(content).deps;
|
||||
data.dependencies = dependencies.sync;
|
||||
data.asyncDependencies = dependencies.async;
|
||||
}
|
||||
|
@ -140,48 +137,4 @@ class Module {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all required modules from a `code` string.
|
||||
*/
|
||||
const blockCommentRe = /\/\*(.|\n)*?\*\//g;
|
||||
const lineCommentRe = /\/\/.+(\n|$)/g;
|
||||
function extractRequires(code) {
|
||||
var deps = {
|
||||
sync: [],
|
||||
async: [],
|
||||
};
|
||||
|
||||
code
|
||||
.replace(blockCommentRe, '')
|
||||
.replace(lineCommentRe, '')
|
||||
// Parse sync dependencies. See comment below for further detils.
|
||||
.replace(replacePatterns.IMPORT_RE, (match, pre, quot, dep, post) => {
|
||||
deps.sync.push(dep);
|
||||
return match;
|
||||
})
|
||||
.replace(replacePatterns.EXPORT_RE, (match, pre, quot, dep, post) => {
|
||||
deps.sync.push(dep);
|
||||
return match;
|
||||
})
|
||||
// Parse the sync dependencies this module has. When the module is
|
||||
// required, all it's sync dependencies will be loaded into memory.
|
||||
// Sync dependencies can be defined either using `require` or the ES6
|
||||
// `import` or `export` syntaxes:
|
||||
// var dep1 = require('dep1');
|
||||
.replace(replacePatterns.REQUIRE_RE, (match, pre, quot, dep, post) => {
|
||||
deps.sync.push(dep);
|
||||
})
|
||||
// Parse async dependencies this module has. As opposed to what happens
|
||||
// with sync dependencies, when the module is required, it's async
|
||||
// dependencies won't be loaded into memory. This is deferred till the
|
||||
// code path gets to the import statement:
|
||||
// System.import('dep1')
|
||||
.replace(replacePatterns.SYSTEM_IMPORT_RE, (match, pre, quot, dep, post) => {
|
||||
deps.async.push([dep]);
|
||||
return match;
|
||||
});
|
||||
|
||||
return deps;
|
||||
}
|
||||
|
||||
module.exports = Module;
|
||||
|
|
|
@ -7,11 +7,12 @@ const path = require('path');
|
|||
|
||||
class ModuleCache {
|
||||
|
||||
constructor(fastfs, cache) {
|
||||
constructor(fastfs, cache, extractRequires) {
|
||||
this._moduleCache = Object.create(null);
|
||||
this._packageCache = Object.create(null);
|
||||
this._fastfs = fastfs;
|
||||
this._cache = cache;
|
||||
this._extractRequires = extractRequires;
|
||||
fastfs.on('change', this._processFileChange.bind(this));
|
||||
}
|
||||
|
||||
|
@ -23,6 +24,7 @@ class ModuleCache {
|
|||
this._fastfs,
|
||||
this,
|
||||
this._cache,
|
||||
this._extractRequires
|
||||
);
|
||||
}
|
||||
return this._moduleCache[filePath];
|
||||
|
|
|
@ -11,18 +11,19 @@
|
|||
jest
|
||||
.dontMock('absolute-path')
|
||||
.dontMock('../fastfs')
|
||||
.dontMock('../replacePatterns')
|
||||
.dontMock('../lib/extractRequires')
|
||||
.dontMock('../lib/replacePatterns')
|
||||
.dontMock('../DependencyGraph/docblock')
|
||||
.dontMock('../Module');
|
||||
|
||||
jest
|
||||
.mock('fs');
|
||||
|
||||
var Fastfs = require('../fastfs');
|
||||
var Module = require('../Module');
|
||||
var ModuleCache = require('../ModuleCache');
|
||||
var Promise = require('promise');
|
||||
var fs = require('fs');
|
||||
const Fastfs = require('../fastfs');
|
||||
const Module = require('../Module');
|
||||
const ModuleCache = require('../ModuleCache');
|
||||
const Promise = require('promise');
|
||||
const fs = require('fs');
|
||||
|
||||
describe('Module', () => {
|
||||
const fileWatcher = {
|
||||
|
@ -30,17 +31,31 @@ describe('Module', () => {
|
|||
isWatchman: () => Promise.resolve(false),
|
||||
};
|
||||
|
||||
const Cache = jest.genMockFn();
|
||||
Cache.prototype.get = jest.genMockFn().mockImplementation(
|
||||
(filepath, field, cb) => cb(filepath)
|
||||
);
|
||||
Cache.prototype.invalidate = jest.genMockFn();
|
||||
Cache.prototype.end = jest.genMockFn();
|
||||
|
||||
|
||||
describe('Async Dependencies', () => {
|
||||
function expectAsyncDependenciesToEqual(expected) {
|
||||
var fastfs = new Fastfs(
|
||||
const fastfs = new Fastfs(
|
||||
'test',
|
||||
['/root'],
|
||||
fileWatcher,
|
||||
{crawling: Promise.resolve(['/root/index.js']), ignore: []},
|
||||
);
|
||||
const cache = new Cache();
|
||||
|
||||
return fastfs.build().then(() => {
|
||||
var module = new Module('/root/index.js', fastfs, new ModuleCache(fastfs));
|
||||
const module = new Module(
|
||||
'/root/index.js',
|
||||
fastfs,
|
||||
new ModuleCache(fastfs, cache),
|
||||
cache
|
||||
);
|
||||
|
||||
return module.getAsyncDependencies().then(actual =>
|
||||
expect(actual).toEqual(expected)
|
||||
|
@ -94,4 +109,43 @@ describe('Module', () => {
|
|||
return expectAsyncDependenciesToEqual([['dep1']]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Extrators', () => {
|
||||
|
||||
function createModuleWithExtractor(extractor) {
|
||||
const fastfs = new Fastfs(
|
||||
'test',
|
||||
['/root'],
|
||||
fileWatcher,
|
||||
{crawling: Promise.resolve(['/root/index.js']), ignore: []},
|
||||
);
|
||||
const cache = new Cache();
|
||||
|
||||
return fastfs.build().then(() => {
|
||||
return new Module(
|
||||
'/root/index.js',
|
||||
fastfs,
|
||||
new ModuleCache(fastfs, cache),
|
||||
cache,
|
||||
extractor
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
pit('uses custom require extractors if specified', () => {
|
||||
fs.__setMockFilesystem({
|
||||
'root': {
|
||||
'index.js': '',
|
||||
},
|
||||
});
|
||||
|
||||
return createModuleWithExtractor(
|
||||
code => ({deps: {sync: ['foo', 'bar']}})
|
||||
).then(module =>
|
||||
module.getDependencies().then(actual =>
|
||||
expect(actual).toEqual(['foo', 'bar'])
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -79,21 +79,19 @@ class Fastfs extends EventEmitter {
|
|||
return [].concat(...this._roots.map(root => root.getFiles()));
|
||||
}
|
||||
|
||||
findFilesByExt(ext, { ignore }) {
|
||||
findFilesByExt(ext, { ignore } = {}) {
|
||||
return this.findFilesByExts([ext], {ignore});
|
||||
}
|
||||
|
||||
findFilesByExts(exts, { ignore } = {}) {
|
||||
return this.getAllFiles()
|
||||
.filter(
|
||||
file => file.ext() === ext && (!ignore || !ignore(file.path))
|
||||
)
|
||||
.filter(file => (
|
||||
exts.indexOf(file.ext()) !== -1 && (!ignore || !ignore(file.path))
|
||||
))
|
||||
.map(file => file.path);
|
||||
}
|
||||
|
||||
findFilesByExts(exts) {
|
||||
return this.getAllFiles()
|
||||
.filter(file => exts.indexOf(file.ext()) !== -1)
|
||||
.map(file => file.path);
|
||||
}
|
||||
|
||||
findFilesByName(name, { ignore }) {
|
||||
findFilesByName(name, { ignore } = {}) {
|
||||
return this.getAllFiles()
|
||||
.filter(
|
||||
file => path.basename(file.path) === name &&
|
||||
|
@ -102,6 +100,12 @@ class Fastfs extends EventEmitter {
|
|||
.map(file => file.path);
|
||||
}
|
||||
|
||||
matchFilesByPattern(pattern) {
|
||||
return this.getAllFiles()
|
||||
.filter(file => file.path.match(pattern))
|
||||
.map(file => file.path);
|
||||
}
|
||||
|
||||
readFile(filePath) {
|
||||
const file = this._getFile(filePath);
|
||||
if (!file) {
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const replacePatterns = require('./replacePatterns');
|
||||
|
||||
/**
|
||||
* Extract all required modules from a `code` string.
|
||||
*/
|
||||
const blockCommentRe = /\/\*(.|\n)*?\*\//g;
|
||||
const lineCommentRe = /\/\/.+(\n|$)/g;
|
||||
function extractRequires(code) {
|
||||
var deps = {
|
||||
sync: [],
|
||||
async: [],
|
||||
};
|
||||
|
||||
code = code
|
||||
.replace(blockCommentRe, '')
|
||||
.replace(lineCommentRe, '')
|
||||
// Parse the sync dependencies this module has. When the module is
|
||||
// required, all it's sync dependencies will be loaded into memory.
|
||||
// Sync dependencies can be defined either using `require` or the ES6
|
||||
// `import` or `export` syntaxes:
|
||||
// var dep1 = require('dep1');
|
||||
.replace(replacePatterns.IMPORT_RE, (match, pre, quot, dep, post) => {
|
||||
deps.sync.push(dep);
|
||||
return match;
|
||||
})
|
||||
.replace(replacePatterns.EXPORT_RE, (match, pre, quot, dep, post) => {
|
||||
deps.sync.push(dep);
|
||||
return match;
|
||||
})
|
||||
.replace(replacePatterns.REQUIRE_RE, (match, pre, quot, dep, post) => {
|
||||
deps.sync.push(dep);
|
||||
return match;
|
||||
})
|
||||
// Parse async dependencies this module has. As opposed to what happens
|
||||
// with sync dependencies, when the module is required, it's async
|
||||
// dependencies won't be loaded into memory. This is deferred till the
|
||||
// code path gets to the import statement:
|
||||
// System.import('dep1')
|
||||
.replace(replacePatterns.SYSTEM_IMPORT_RE, (match, pre, quot, dep, post) => {
|
||||
deps.async.push([dep]);
|
||||
return match;
|
||||
});
|
||||
|
||||
return {code, deps};
|
||||
}
|
||||
|
||||
module.exports = extractRequires;
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.IMPORT_RE = /(\bimport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g;
|
||||
exports.EXPORT_RE = /(\bexport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g;
|
||||
exports.REQUIRE_RE = /(\brequire\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;
|
||||
exports.SYSTEM_IMPORT_RE = /(\bSystem\.import\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
jest.dontMock('../')
|
||||
.dontMock('underscore')
|
||||
.dontMock('../../DependencyResolver/replacePatterns');
|
||||
.dontMock('../../DependencyResolver/lib/extractRequires')
|
||||
.dontMock('../../DependencyResolver/lib/replacePatterns');
|
||||
|
||||
jest.mock('path');
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
const path = require('path');
|
||||
const Activity = require('../Activity');
|
||||
const DependencyGraph = require('../DependencyResolver/DependencyGraph');
|
||||
const replacePatterns = require('../DependencyResolver/replacePatterns');
|
||||
const replacePatterns = require('../DependencyResolver/lib/replacePatterns');
|
||||
const Polyfill = require('../DependencyResolver/Polyfill');
|
||||
const declareOpts = require('../lib/declareOpts');
|
||||
const Promise = require('promise');
|
||||
|
|
Loading…
Reference in New Issue