mirror of https://github.com/status-im/metro.git
metro-bundler: remove hardcoded AssetRegistry path
Reviewed By: davidaurelio Differential Revision: D5452553 fbshipit-source-id: e0a6f56d3bc03f4ba7f34fbee1ae418495dcc6cd
This commit is contained in:
parent
74e78ee43f
commit
5ba56250b5
|
@ -40,6 +40,7 @@ const {any, objectContaining} = expect;
|
||||||
var commonOptions = {
|
var commonOptions = {
|
||||||
allowBundleUpdates: false,
|
allowBundleUpdates: false,
|
||||||
assetExts: defaults.assetExts,
|
assetExts: defaults.assetExts,
|
||||||
|
assetRegistryPath: '/AssetRegistry.js',
|
||||||
cacheVersion: 'smth',
|
cacheVersion: 'smth',
|
||||||
enableBabelRCLookup: true,
|
enableBabelRCLookup: true,
|
||||||
extraNodeModules: {},
|
extraNodeModules: {},
|
||||||
|
|
|
@ -121,6 +121,7 @@ export type PostProcessBundleSourcemap = ({
|
||||||
type Options = {|
|
type Options = {|
|
||||||
+allowBundleUpdates: boolean,
|
+allowBundleUpdates: boolean,
|
||||||
+assetExts: Array<string>,
|
+assetExts: Array<string>,
|
||||||
|
+assetRegistryPath: string,
|
||||||
+assetServer: AssetServer,
|
+assetServer: AssetServer,
|
||||||
+blacklistRE?: RegExp,
|
+blacklistRE?: RegExp,
|
||||||
+cacheVersion: string,
|
+cacheVersion: string,
|
||||||
|
@ -213,6 +214,7 @@ class Bundler {
|
||||||
|
|
||||||
this._resolverPromise = Resolver.load({
|
this._resolverPromise = Resolver.load({
|
||||||
assetExts: opts.assetExts,
|
assetExts: opts.assetExts,
|
||||||
|
assetRegistryPath: opts.assetRegistryPath,
|
||||||
blacklistRE: opts.blacklistRE,
|
blacklistRE: opts.blacklistRE,
|
||||||
extraNodeModules: opts.extraNodeModules,
|
extraNodeModules: opts.extraNodeModules,
|
||||||
getPolyfills: opts.getPolyfills,
|
getPolyfills: opts.getPolyfills,
|
||||||
|
@ -740,7 +742,8 @@ class Bundler {
|
||||||
|
|
||||||
return this._applyAssetPlugins(assetPlugins, asset);
|
return this._applyAssetPlugins(assetPlugins, asset);
|
||||||
}).then(asset => {
|
}).then(asset => {
|
||||||
const {code, dependencies, dependencyOffsets} = generateAssetTransformResult(asset);
|
const {code, dependencies, dependencyOffsets} =
|
||||||
|
generateAssetTransformResult(this._opts.assetRegistryPath, asset);
|
||||||
return {
|
return {
|
||||||
asset,
|
asset,
|
||||||
code,
|
code,
|
||||||
|
|
|
@ -29,15 +29,16 @@ const assetPropertyBlacklist = new Set([
|
||||||
'path',
|
'path',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ASSET_REGISTRY_PATH = 'react-native/Libraries/Image/AssetRegistry';
|
function generateAssetCodeFileAst(
|
||||||
|
assetRegistryPath: string,
|
||||||
function generateAssetCodeFileAst(assetDescriptor: AssetDescriptor): Object {
|
assetDescriptor: AssetDescriptor,
|
||||||
|
): Object {
|
||||||
const properDescriptor = filterObject(assetDescriptor, assetPropertyBlacklist);
|
const properDescriptor = filterObject(assetDescriptor, assetPropertyBlacklist);
|
||||||
const descriptorAst = babylon.parseExpression(JSON.stringify(properDescriptor));
|
const descriptorAst = babylon.parseExpression(JSON.stringify(properDescriptor));
|
||||||
const t = babel.types;
|
const t = babel.types;
|
||||||
const moduleExports = t.memberExpression(t.identifier('module'), t.identifier('exports'));
|
const moduleExports = t.memberExpression(t.identifier('module'), t.identifier('exports'));
|
||||||
const requireCall =
|
const requireCall =
|
||||||
t.callExpression(t.identifier('require'), [t.stringLiteral(ASSET_REGISTRY_PATH)]);
|
t.callExpression(t.identifier('require'), [t.stringLiteral(assetRegistryPath)]);
|
||||||
const registerAssetFunction = t.memberExpression(requireCall, t.identifier('registerAsset'));
|
const registerAssetFunction = t.memberExpression(requireCall, t.identifier('registerAsset'));
|
||||||
const registerAssetCall = t.callExpression(registerAssetFunction, [descriptorAst]);
|
const registerAssetCall = t.callExpression(registerAssetFunction, [descriptorAst]);
|
||||||
return t.file(t.program([
|
return t.file(t.program([
|
||||||
|
@ -45,17 +46,20 @@ function generateAssetCodeFileAst(assetDescriptor: AssetDescriptor): Object {
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateAssetTransformResult(assetDescriptor: AssetDescriptor): {|
|
function generateAssetTransformResult(
|
||||||
|
assetRegistryPath: string,
|
||||||
|
assetDescriptor: AssetDescriptor,
|
||||||
|
): {|
|
||||||
code: string,
|
code: string,
|
||||||
dependencies: Array<string>,
|
dependencies: Array<string>,
|
||||||
dependencyOffsets: Array<number>,
|
dependencyOffsets: Array<number>,
|
||||||
|} {
|
|} {
|
||||||
const {code} = babelGenerate(
|
const {code} = babelGenerate(
|
||||||
generateAssetCodeFileAst(assetDescriptor),
|
generateAssetCodeFileAst(assetRegistryPath, assetDescriptor),
|
||||||
{comments: false, compact: true},
|
{comments: false, compact: true},
|
||||||
);
|
);
|
||||||
const dependencies = [ASSET_REGISTRY_PATH];
|
const dependencies = [assetRegistryPath];
|
||||||
const dependencyOffsets = [code.indexOf(ASSET_REGISTRY_PATH) - 1];
|
const dependencyOffsets = [code.indexOf(assetRegistryPath) - 1];
|
||||||
return {code, dependencies, dependencyOffsets};
|
return {code, dependencies, dependencyOffsets};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ type ContainsTransformerOptions = {+transformer: JSTransformerOptions}
|
||||||
|
|
||||||
type Options = {|
|
type Options = {|
|
||||||
+assetExts: Array<string>,
|
+assetExts: Array<string>,
|
||||||
|
+assetRegistryPath: string,
|
||||||
+blacklistRE?: RegExp,
|
+blacklistRE?: RegExp,
|
||||||
+extraNodeModules: ?{},
|
+extraNodeModules: ?{},
|
||||||
+getPolyfills: ({platform: ?string}) => $ReadOnlyArray<string>,
|
+getPolyfills: ({platform: ?string}) => $ReadOnlyArray<string>,
|
||||||
|
@ -71,7 +72,7 @@ class Resolver {
|
||||||
|
|
||||||
static async load(opts: Options): Promise<Resolver> {
|
static async load(opts: Options): Promise<Resolver> {
|
||||||
const depGraphOpts = {
|
const depGraphOpts = {
|
||||||
assetDependencies: ['react-native/Libraries/Image/AssetRegistry'],
|
assetDependencies: [opts.assetRegistryPath],
|
||||||
assetExts: opts.assetExts,
|
assetExts: opts.assetExts,
|
||||||
extraNodeModules: opts.extraNodeModules,
|
extraNodeModules: opts.extraNodeModules,
|
||||||
forceNodeFilesystemAPI: false,
|
forceNodeFilesystemAPI: false,
|
||||||
|
|
|
@ -68,6 +68,7 @@ function debounceAndBatch(fn, delay) {
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
assetExts?: Array<string>,
|
assetExts?: Array<string>,
|
||||||
|
+assetRegistryPath: string,
|
||||||
blacklistRE?: RegExp,
|
blacklistRE?: RegExp,
|
||||||
cacheVersion?: string,
|
cacheVersion?: string,
|
||||||
enableBabelRCLookup?: boolean,
|
enableBabelRCLookup?: boolean,
|
||||||
|
@ -176,6 +177,7 @@ class Server {
|
||||||
const maxWorkers = getMaxWorkers(options.maxWorkers);
|
const maxWorkers = getMaxWorkers(options.maxWorkers);
|
||||||
this._opts = {
|
this._opts = {
|
||||||
assetExts: options.assetExts || defaults.assetExts,
|
assetExts: options.assetExts || defaults.assetExts,
|
||||||
|
assetRegistryPath: options.assetRegistryPath,
|
||||||
blacklistRE: options.blacklistRE,
|
blacklistRE: options.blacklistRE,
|
||||||
cacheVersion: options.cacheVersion || '1.0',
|
cacheVersion: options.cacheVersion || '1.0',
|
||||||
enableBabelRCLookup:
|
enableBabelRCLookup:
|
||||||
|
|
|
@ -33,6 +33,7 @@ exports.createServer = createServer;
|
||||||
exports.Logger = Logger;
|
exports.Logger = Logger;
|
||||||
|
|
||||||
type Options = {|
|
type Options = {|
|
||||||
|
+assetRegistryPath: string,
|
||||||
+sourceExts: ?Array<string>,
|
+sourceExts: ?Array<string>,
|
||||||
+transformCache: TransformCache,
|
+transformCache: TransformCache,
|
||||||
+transformModulePath: string,
|
+transformModulePath: string,
|
||||||
|
|
|
@ -258,9 +258,11 @@ var asset = require(7 ); // 7 = ./test.png
|
||||||
|
|
||||||
module.exports = { type: 'foo', asset: asset };
|
module.exports = { type: 'foo', asset: asset };
|
||||||
}, 6);
|
}, 6);
|
||||||
__d(/* /test.png */function(global, require, module, exports) {module.exports=require(8 ).registerAsset({\\"__packager_asset\\":true,\\"httpServerLocation\\":\\"/assets\\",\\"width\\":8,\\"height\\":8,\\"scales\\":[1],\\"hash\\":\\"77d45c1f7fa73c0f6c444a830dc42f67\\",\\"name\\":\\"test\\",\\"type\\":\\"png\\"}); // 8 = react-native/Libraries/Image/AssetRegistry
|
__d(/* /test.png */function(global, require, module, exports) {module.exports=require(8).registerAsset({\\"__packager_asset\\":true,\\"httpServerLocation\\":\\"/assets\\",\\"width\\":8,\\"height\\":8,\\"scales\\":[1],\\"hash\\":\\"77d45c1f7fa73c0f6c444a830dc42f67\\",\\"name\\":\\"test\\",\\"type\\":\\"png\\"}); // 8 = /AssetRegistry
|
||||||
}, 7);
|
}, 7);
|
||||||
__d(/* /node_modules/react-native/Libraries/Image/AssetRegistry.js */function(global, require, module, exports) {'use strict';
|
__d(/* /AssetRegistry.js */function(global, require, module, exports) {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
}, 8);
|
}, 8);
|
||||||
;require(0);"
|
;require(0);"
|
||||||
`;
|
`;
|
||||||
|
@ -523,9 +525,11 @@ var asset = require(7 ); // 7 = ./test.png
|
||||||
|
|
||||||
module.exports = { type: 'foo', asset: asset };
|
module.exports = { type: 'foo', asset: asset };
|
||||||
}, 6);
|
}, 6);
|
||||||
__d(/* /test.png */function(global, require, module, exports) {module.exports=require(8 ).registerAsset({\\"__packager_asset\\":true,\\"httpServerLocation\\":\\"/assets\\",\\"width\\":8,\\"height\\":8,\\"scales\\":[1],\\"hash\\":\\"77d45c1f7fa73c0f6c444a830dc42f67\\",\\"name\\":\\"test\\",\\"type\\":\\"png\\"}); // 8 = react-native/Libraries/Image/AssetRegistry
|
__d(/* /test.png */function(global, require, module, exports) {module.exports=require(8).registerAsset({\\"__packager_asset\\":true,\\"httpServerLocation\\":\\"/assets\\",\\"width\\":8,\\"height\\":8,\\"scales\\":[1],\\"hash\\":\\"77d45c1f7fa73c0f6c444a830dc42f67\\",\\"name\\":\\"test\\",\\"type\\":\\"png\\"}); // 8 = /AssetRegistry
|
||||||
}, 7);
|
}, 7);
|
||||||
__d(/* /node_modules/react-native/Libraries/Image/AssetRegistry.js */function(global, require, module, exports) {'use strict';
|
__d(/* /AssetRegistry.js */function(global, require, module, exports) {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
}, 8);
|
}, 8);
|
||||||
;require(0);"
|
;require(0);"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -20,6 +20,10 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 30 * 1000;
|
||||||
|
|
||||||
const INPUT_PATH = path.resolve(__dirname, '../basic_bundle');
|
const INPUT_PATH = path.resolve(__dirname, '../basic_bundle');
|
||||||
const POLYFILLS_PATH = path.resolve(__dirname, '../../Resolver/polyfills');
|
const POLYFILLS_PATH = path.resolve(__dirname, '../../Resolver/polyfills');
|
||||||
|
const ASSET_REGISTRY_PATH = path.resolve(
|
||||||
|
__dirname,
|
||||||
|
'../basic_bundle/AssetRegistry',
|
||||||
|
);
|
||||||
|
|
||||||
describe('basic_bundle', () => {
|
describe('basic_bundle', () => {
|
||||||
const absPathRe = new RegExp(INPUT_PATH, 'g');
|
const absPathRe = new RegExp(INPUT_PATH, 'g');
|
||||||
|
@ -74,9 +78,24 @@ describe('basic_bundle', () => {
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On different machines and local repos the absolute paths are different so
|
||||||
|
* we relativize them to the root of the test. We also trim the spacing inside
|
||||||
|
* ID-based `require()` calls because the way the bundle appears to do it is
|
||||||
|
* by replacing path strings directly by numbers in the code, not the AST.
|
||||||
|
*/
|
||||||
|
function verifyResultCode(code) {
|
||||||
|
expect(
|
||||||
|
code
|
||||||
|
.replace(absPathRe, '')
|
||||||
|
.replace(/require\(([0-9]*) *\)/g, 'require($1)'),
|
||||||
|
).toMatchSnapshot();
|
||||||
|
}
|
||||||
|
|
||||||
it('bundles package with polyfills as expected', async () => {
|
it('bundles package with polyfills as expected', async () => {
|
||||||
const bundleWithPolyfills = await Packager.buildBundle(
|
const bundleWithPolyfills = await Packager.buildBundle(
|
||||||
{
|
{
|
||||||
|
assetRegistryPath: ASSET_REGISTRY_PATH,
|
||||||
getPolyfills: () => [polyfill1, polyfill2],
|
getPolyfills: () => [polyfill1, polyfill2],
|
||||||
projectRoots: [INPUT_PATH, POLYFILLS_PATH],
|
projectRoots: [INPUT_PATH, POLYFILLS_PATH],
|
||||||
transformCache: Packager.TransformCaching.none(),
|
transformCache: Packager.TransformCaching.none(),
|
||||||
|
@ -89,15 +108,13 @@ describe('basic_bundle', () => {
|
||||||
platform: 'ios',
|
platform: 'ios',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
verifyResultCode(bundleWithPolyfills.getSource());
|
||||||
expect(
|
|
||||||
bundleWithPolyfills.getSource().replace(absPathRe, ''),
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('bundles package without polyfills as expected', async () => {
|
it('bundles package without polyfills as expected', async () => {
|
||||||
const bundleWithoutPolyfills = await Packager.buildBundle(
|
const bundleWithoutPolyfills = await Packager.buildBundle(
|
||||||
{
|
{
|
||||||
|
assetRegistryPath: ASSET_REGISTRY_PATH,
|
||||||
getPolyfills: () => [polyfill1, polyfill2],
|
getPolyfills: () => [polyfill1, polyfill2],
|
||||||
projectRoots: [INPUT_PATH, POLYFILLS_PATH],
|
projectRoots: [INPUT_PATH, POLYFILLS_PATH],
|
||||||
transformCache: Packager.TransformCaching.none(),
|
transformCache: Packager.TransformCaching.none(),
|
||||||
|
@ -110,9 +127,6 @@ describe('basic_bundle', () => {
|
||||||
platform: 'ios',
|
platform: 'ios',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
verifyResultCode(bundleWithoutPolyfills.getSource());
|
||||||
expect(
|
|
||||||
bundleWithoutPolyfills.getSource().replace(absPathRe, ''),
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
|
@ -1 +0,0 @@
|
||||||
'use strict';
|
|
Loading…
Reference in New Issue