mirror of https://github.com/status-im/metro.git
packager: add support for relative files with custom extensions
Reviewed By: cpojer Differential Revision: D4994139 fbshipit-source-id: 5e47c5bc6f8b2cd750f1ca0df940c23234c66600
This commit is contained in:
parent
280779f5c0
commit
173b9244a6
|
@ -10,13 +10,15 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
exports.assetExts = [
|
||||
exports.assetExts = [
|
||||
'bmp', 'gif', 'jpg', 'jpeg', 'png', 'psd', 'svg', 'webp', // Image formats
|
||||
'm4v', 'mov', 'mp4', 'mpeg', 'mpg', 'webm', // Video formats
|
||||
'aac', 'aiff', 'caf', 'm4a', 'mp3', 'wav', // Audio formats
|
||||
'html', 'pdf', // Document formats
|
||||
];
|
||||
|
||||
exports.sourceExts = ['js', 'json'];
|
||||
|
||||
exports.moduleSystem = require.resolve('./src/Resolver/polyfills/require.js');
|
||||
|
||||
exports.platforms = ['ios', 'android', 'windows', 'web'];
|
||||
|
|
|
@ -16,8 +16,8 @@ const Logger = require('./src/Logger');
|
|||
const debug = require('debug');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
import type Server from './src/Server';
|
||||
import type {PostProcessModules, PostMinifyProcess} from './src/Bundler';
|
||||
import type Server from './src/Server';
|
||||
import type {GlobalTransformCache} from './src/lib/GlobalTransformCache';
|
||||
import type {Reporter} from './src/lib/reporting';
|
||||
import type {HasteImpl} from './src/node-haste/Module';
|
||||
|
@ -33,6 +33,7 @@ type Options = {
|
|||
postMinifyProcess?: PostMinifyProcess,
|
||||
projectRoots: Array<string>,
|
||||
reporter?: Reporter,
|
||||
+sourceExts: ?Array<string>,
|
||||
watch?: boolean,
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@ module.exports = {
|
|||
return [];
|
||||
},
|
||||
|
||||
getSourceExts() {
|
||||
return [];
|
||||
},
|
||||
|
||||
getBlacklistRE() {
|
||||
return blacklist();
|
||||
},
|
||||
|
|
|
@ -44,6 +44,7 @@ var commonOptions = {
|
|||
extraNodeModules: {},
|
||||
platforms: defaults.platforms,
|
||||
resetCache: false,
|
||||
sourceExts: defaults.sourceExts,
|
||||
watch: false,
|
||||
};
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ type Options = {|
|
|||
+providesModuleNodeModules?: Array<string>,
|
||||
+reporter: Reporter,
|
||||
+resetCache: boolean,
|
||||
+sourceExts: Array<string>,
|
||||
+transformModulePath?: string,
|
||||
+transformTimeoutInterval: ?number,
|
||||
+watch: boolean,
|
||||
|
@ -217,6 +218,7 @@ class Bundler {
|
|||
opts.providesModuleNodeModules || defaults.providesModuleNodeModules,
|
||||
reporter: opts.reporter,
|
||||
resetCache: opts.resetCache,
|
||||
sourceExts: opts.sourceExts,
|
||||
transformCode:
|
||||
(module, code, transformCodeOptions) => this._transformer.transformFile(
|
||||
module.path,
|
||||
|
|
|
@ -34,6 +34,7 @@ const defaults = require('../../../defaults');
|
|||
type ResolveOptions = {|
|
||||
assetExts: Extensions,
|
||||
extraNodeModules: {[id: string]: string},
|
||||
+sourceExts: Extensions,
|
||||
transformedFiles: {[path: Path]: TransformedCodeFile},
|
||||
|};
|
||||
|
||||
|
@ -72,6 +73,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
assetExts,
|
||||
extraNodeModules,
|
||||
transformedFiles,
|
||||
sourceExts,
|
||||
} = options;
|
||||
const files = Object.keys(transformedFiles);
|
||||
function getTransformedFile(path) {
|
||||
|
@ -93,7 +95,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
getTransformedFile,
|
||||
);
|
||||
const hasteMap = new HasteMap({
|
||||
extensions: ['js', 'json'],
|
||||
extensions: sourceExts,
|
||||
files,
|
||||
helpers,
|
||||
moduleCache,
|
||||
|
@ -119,6 +121,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
platform,
|
||||
platforms,
|
||||
preferNativePlatform: true,
|
||||
sourceExts,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ type Options = {|
|
|||
+providesModuleNodeModules: Array<string>,
|
||||
+reporter: Reporter,
|
||||
+resetCache: boolean,
|
||||
+sourceExts: Array<string>,
|
||||
+transformCode: TransformCode,
|
||||
+watch: boolean,
|
||||
|};
|
||||
|
@ -67,7 +68,6 @@ class Resolver {
|
|||
static async load(opts: Options): Promise<Resolver> {
|
||||
const depGraphOpts = Object.assign(Object.create(opts), {
|
||||
assetDependencies: ['react-native/Libraries/Image/AssetRegistry'],
|
||||
extensions: ['js', 'json'],
|
||||
forceNodeFilesystemAPI: false,
|
||||
ignoreFilePath(filepath) {
|
||||
return filepath.indexOf('__tests__') !== -1 ||
|
||||
|
|
|
@ -74,6 +74,7 @@ type Options = {
|
|||
reporter: Reporter,
|
||||
resetCache?: boolean,
|
||||
silent?: boolean,
|
||||
+sourceExts: ?Array<string>,
|
||||
transformModulePath?: string,
|
||||
transformTimeoutInterval?: number,
|
||||
watch?: boolean,
|
||||
|
@ -129,6 +130,7 @@ class Server {
|
|||
reporter: Reporter,
|
||||
resetCache: boolean,
|
||||
silent: boolean,
|
||||
+sourceExts: Array<string>,
|
||||
transformModulePath: void | string,
|
||||
transformTimeoutInterval: ?number,
|
||||
watch: boolean,
|
||||
|
@ -166,6 +168,7 @@ class Server {
|
|||
reporter: options.reporter,
|
||||
resetCache: options.resetCache || false,
|
||||
silent: options.silent || false,
|
||||
sourceExts: options.sourceExts || defaults.sourceExts,
|
||||
transformModulePath: options.transformModulePath,
|
||||
transformTimeoutInterval: options.transformTimeoutInterval,
|
||||
watch: options.watch || false,
|
||||
|
|
|
@ -71,6 +71,7 @@ type Options<TModule, TPackage> = {|
|
|||
+platform: ?string,
|
||||
+platforms: Set<string>,
|
||||
+preferNativePlatform: boolean,
|
||||
+sourceExts: Array<string>,
|
||||
|};
|
||||
|
||||
/**
|
||||
|
@ -528,22 +529,39 @@ class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
|
|||
let file;
|
||||
if (this._options.hasteFS.exists(potentialModulePath)) {
|
||||
file = potentialModulePath;
|
||||
} else if (this._options.platform != null &&
|
||||
this._options.hasteFS.exists(potentialModulePath + '.' + this._options.platform + '.js')) {
|
||||
file = potentialModulePath + '.' + this._options.platform + '.js';
|
||||
} else if (this._preferNativePlatform &&
|
||||
this._options.hasteFS.exists(potentialModulePath + '.native.js')) {
|
||||
file = potentialModulePath + '.native.js';
|
||||
} else if (this._options.hasteFS.exists(potentialModulePath + '.js')) {
|
||||
file = potentialModulePath + '.js';
|
||||
} else if (this._options.hasteFS.exists(potentialModulePath + '.json')) {
|
||||
file = potentialModulePath + '.json';
|
||||
} else {
|
||||
throw new UnableToResolveError(
|
||||
fromModule,
|
||||
toModule,
|
||||
`File ${potentialModulePath} doesn't exist`,
|
||||
);
|
||||
const {platform, preferNativePlatform, hasteFS} = this._options;
|
||||
for (let i = 0; i < this._options.sourceExts.length; i++) {
|
||||
const ext = this._options.sourceExts[i];
|
||||
if (platform != null) {
|
||||
const platformSpecificPath = `${potentialModulePath}.${platform}.${ext}`;
|
||||
if (hasteFS.exists(platformSpecificPath)) {
|
||||
file = platformSpecificPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (preferNativePlatform) {
|
||||
const nativeSpecificPath = `${potentialModulePath}.native.${ext}`;
|
||||
if (hasteFS.exists(nativeSpecificPath)) {
|
||||
file = nativeSpecificPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const genericPath = `${potentialModulePath}.${ext}`;
|
||||
if (hasteFS.exists(genericPath)) {
|
||||
file = genericPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (file == null) {
|
||||
throw new UnableToResolveError(
|
||||
fromModule,
|
||||
toModule,
|
||||
`File ${potentialModulePath} doesn't exist`,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this._options.moduleCache.getModule(file);
|
||||
|
|
|
@ -40,7 +40,7 @@ describe('DependencyGraph', function() {
|
|||
let emptyTransformOptions;
|
||||
|
||||
function getOrderedDependenciesAsJSON(dgraphPromise, entryPath, platform, recursive = true) {
|
||||
return dgraphPromise
|
||||
return Promise.resolve(dgraphPromise)
|
||||
.then(dgraph => dgraph.getDependencies({
|
||||
entryPath,
|
||||
options: emptyTransformOptions,
|
||||
|
@ -72,7 +72,6 @@ describe('DependencyGraph', function() {
|
|||
emptyTransformOptions = {transformer: {transform: {}}};
|
||||
defaults = {
|
||||
assetExts: ['png', 'jpg'],
|
||||
extensions: ['js', 'json'],
|
||||
forceNodeFilesystemAPI: true,
|
||||
providesModuleNodeModules: [
|
||||
'haste-fbjs',
|
||||
|
@ -96,6 +95,7 @@ describe('DependencyGraph', function() {
|
|||
},
|
||||
getTransformCacheKey: () => 'abcdef',
|
||||
reporter: require('../../lib/reporting').nullReporter,
|
||||
sourceExts: ['js', 'json'],
|
||||
watch: true,
|
||||
};
|
||||
});
|
||||
|
@ -5250,7 +5250,7 @@ describe('DependencyGraph', function() {
|
|||
var dgraph = DependencyGraph.load({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
extensions: ['jsx', 'coffee'],
|
||||
sourceExts: ['jsx', 'coffee'],
|
||||
});
|
||||
|
||||
return dgraph
|
||||
|
@ -5284,6 +5284,80 @@ describe('DependencyGraph', function() {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('supports custom file extensions with relative paths', async () => {
|
||||
const root = '/root';
|
||||
setMockFileSystem({
|
||||
'root': {
|
||||
'index.jsx': [
|
||||
'require("./a")',
|
||||
].join('\n'),
|
||||
'a.coffee': [
|
||||
].join('\n'),
|
||||
'X.js': '',
|
||||
},
|
||||
});
|
||||
|
||||
const dgraph = await DependencyGraph.load({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
sourceExts: ['jsx', 'coffee'],
|
||||
});
|
||||
const files = await dgraph.matchFilesByPattern('.*');
|
||||
expect(files).toEqual([
|
||||
'/root/index.jsx', '/root/a.coffee',
|
||||
]);
|
||||
|
||||
const deps = await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx');
|
||||
expect(deps).toEqual([
|
||||
{
|
||||
dependencies: ['./a'],
|
||||
id: '/root/index.jsx',
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
path: '/root/index.jsx',
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
dependencies: [],
|
||||
id: '/root/a.coffee',
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
path: '/root/a.coffee',
|
||||
resolution: undefined,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not include extensions that are not specified explicitely', async () => {
|
||||
const root = '/root';
|
||||
setMockFileSystem({
|
||||
'root': {
|
||||
'index.jsx': [
|
||||
'require("./a")',
|
||||
].join('\n'),
|
||||
'a.coffee': [
|
||||
].join('\n'),
|
||||
'X.js': '',
|
||||
},
|
||||
});
|
||||
|
||||
const dgraph = await DependencyGraph.load({
|
||||
...defaults,
|
||||
roots: [root],
|
||||
});
|
||||
const files = await dgraph.matchFilesByPattern('.*');
|
||||
expect(files).toEqual(['/root/X.js']);
|
||||
|
||||
try {
|
||||
await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx');
|
||||
throw Error('should not reach this line');
|
||||
} catch (error) {
|
||||
expect(error.type).toEqual('UnableToResolveError');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Progress updates', () => {
|
||||
|
|
|
@ -51,7 +51,6 @@ import type {HasteFS} from './types';
|
|||
type Options = {|
|
||||
+assetDependencies: Array<string>,
|
||||
+assetExts: Array<string>,
|
||||
+extensions: Array<string>,
|
||||
+extraNodeModules: ?{},
|
||||
+forceNodeFilesystemAPI: boolean,
|
||||
+getTransformCacheKey: GetTransformCacheKey,
|
||||
|
@ -65,6 +64,7 @@ type Options = {|
|
|||
+reporter: Reporter,
|
||||
+resetCache: boolean,
|
||||
+roots: Array<string>,
|
||||
+sourceExts: Array<string>,
|
||||
+transformCode: TransformCode,
|
||||
+useWatchman: boolean,
|
||||
+watch: boolean,
|
||||
|
@ -103,7 +103,7 @@ class DependencyGraph extends EventEmitter {
|
|||
|
||||
static _createHaste(opts: Options): JestHasteMap {
|
||||
return new JestHasteMap({
|
||||
extensions: opts.extensions.concat(opts.assetExts),
|
||||
extensions: opts.sourceExts.concat(opts.assetExts),
|
||||
forceNodeFilesystemAPI: opts.forceNodeFilesystemAPI,
|
||||
ignorePattern: {test: opts.ignoreFilePath},
|
||||
maxWorkers: opts.maxWorkerCount,
|
||||
|
@ -234,6 +234,7 @@ class DependencyGraph extends EventEmitter {
|
|||
platform,
|
||||
platforms: this._opts.platforms,
|
||||
preferNativePlatform: this._opts.preferNativePlatform,
|
||||
sourceExts: this._opts.sourceExts,
|
||||
});
|
||||
|
||||
const response = new ResolutionResponse(options);
|
||||
|
|
Loading…
Reference in New Issue