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 = {
|
||||
allowBundleUpdates: false,
|
||||
assetExts: defaults.assetExts,
|
||||
assetRegistryPath: '/AssetRegistry.js',
|
||||
cacheVersion: 'smth',
|
||||
enableBabelRCLookup: true,
|
||||
extraNodeModules: {},
|
||||
|
|
|
@ -121,6 +121,7 @@ export type PostProcessBundleSourcemap = ({
|
|||
type Options = {|
|
||||
+allowBundleUpdates: boolean,
|
||||
+assetExts: Array<string>,
|
||||
+assetRegistryPath: string,
|
||||
+assetServer: AssetServer,
|
||||
+blacklistRE?: RegExp,
|
||||
+cacheVersion: string,
|
||||
|
@ -213,6 +214,7 @@ class Bundler {
|
|||
|
||||
this._resolverPromise = Resolver.load({
|
||||
assetExts: opts.assetExts,
|
||||
assetRegistryPath: opts.assetRegistryPath,
|
||||
blacklistRE: opts.blacklistRE,
|
||||
extraNodeModules: opts.extraNodeModules,
|
||||
getPolyfills: opts.getPolyfills,
|
||||
|
@ -740,7 +742,8 @@ class Bundler {
|
|||
|
||||
return this._applyAssetPlugins(assetPlugins, asset);
|
||||
}).then(asset => {
|
||||
const {code, dependencies, dependencyOffsets} = generateAssetTransformResult(asset);
|
||||
const {code, dependencies, dependencyOffsets} =
|
||||
generateAssetTransformResult(this._opts.assetRegistryPath, asset);
|
||||
return {
|
||||
asset,
|
||||
code,
|
||||
|
|
|
@ -29,15 +29,16 @@ const assetPropertyBlacklist = new Set([
|
|||
'path',
|
||||
]);
|
||||
|
||||
const ASSET_REGISTRY_PATH = 'react-native/Libraries/Image/AssetRegistry';
|
||||
|
||||
function generateAssetCodeFileAst(assetDescriptor: AssetDescriptor): Object {
|
||||
function generateAssetCodeFileAst(
|
||||
assetRegistryPath: string,
|
||||
assetDescriptor: AssetDescriptor,
|
||||
): Object {
|
||||
const properDescriptor = filterObject(assetDescriptor, assetPropertyBlacklist);
|
||||
const descriptorAst = babylon.parseExpression(JSON.stringify(properDescriptor));
|
||||
const t = babel.types;
|
||||
const moduleExports = t.memberExpression(t.identifier('module'), t.identifier('exports'));
|
||||
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 registerAssetCall = t.callExpression(registerAssetFunction, [descriptorAst]);
|
||||
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,
|
||||
dependencies: Array<string>,
|
||||
dependencyOffsets: Array<number>,
|
||||
|} {
|
||||
const {code} = babelGenerate(
|
||||
generateAssetCodeFileAst(assetDescriptor),
|
||||
generateAssetCodeFileAst(assetRegistryPath, assetDescriptor),
|
||||
{comments: false, compact: true},
|
||||
);
|
||||
const dependencies = [ASSET_REGISTRY_PATH];
|
||||
const dependencyOffsets = [code.indexOf(ASSET_REGISTRY_PATH) - 1];
|
||||
const dependencies = [assetRegistryPath];
|
||||
const dependencyOffsets = [code.indexOf(assetRegistryPath) - 1];
|
||||
return {code, dependencies, dependencyOffsets};
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ type ContainsTransformerOptions = {+transformer: JSTransformerOptions}
|
|||
|
||||
type Options = {|
|
||||
+assetExts: Array<string>,
|
||||
+assetRegistryPath: string,
|
||||
+blacklistRE?: RegExp,
|
||||
+extraNodeModules: ?{},
|
||||
+getPolyfills: ({platform: ?string}) => $ReadOnlyArray<string>,
|
||||
|
@ -71,7 +72,7 @@ class Resolver {
|
|||
|
||||
static async load(opts: Options): Promise<Resolver> {
|
||||
const depGraphOpts = {
|
||||
assetDependencies: ['react-native/Libraries/Image/AssetRegistry'],
|
||||
assetDependencies: [opts.assetRegistryPath],
|
||||
assetExts: opts.assetExts,
|
||||
extraNodeModules: opts.extraNodeModules,
|
||||
forceNodeFilesystemAPI: false,
|
||||
|
|
|
@ -68,6 +68,7 @@ function debounceAndBatch(fn, delay) {
|
|||
|
||||
type Options = {
|
||||
assetExts?: Array<string>,
|
||||
+assetRegistryPath: string,
|
||||
blacklistRE?: RegExp,
|
||||
cacheVersion?: string,
|
||||
enableBabelRCLookup?: boolean,
|
||||
|
@ -176,6 +177,7 @@ class Server {
|
|||
const maxWorkers = getMaxWorkers(options.maxWorkers);
|
||||
this._opts = {
|
||||
assetExts: options.assetExts || defaults.assetExts,
|
||||
assetRegistryPath: options.assetRegistryPath,
|
||||
blacklistRE: options.blacklistRE,
|
||||
cacheVersion: options.cacheVersion || '1.0',
|
||||
enableBabelRCLookup:
|
||||
|
|
|
@ -33,6 +33,7 @@ exports.createServer = createServer;
|
|||
exports.Logger = Logger;
|
||||
|
||||
type Options = {|
|
||||
+assetRegistryPath: string,
|
||||
+sourceExts: ?Array<string>,
|
||||
+transformCache: TransformCache,
|
||||
+transformModulePath: string,
|
||||
|
|
|
@ -237,8 +237,8 @@ __d(/* /TestBundle.js */function(global, require, module, exports) {
|
|||
|
||||
'use strict';
|
||||
|
||||
var Bar = require(5 ); // 5 = ./Bar
|
||||
var Foo = require(6 ); // 6 = ./Foo
|
||||
var Bar = require(5); // 5 = ./Bar
|
||||
var Foo = require(6); // 6 = ./Foo
|
||||
|
||||
module.exports = { Foo: Foo, Bar: Bar };
|
||||
}, 0);
|
||||
|
@ -246,7 +246,7 @@ __d(/* /Bar.js */function(global, require, module, exports) {
|
|||
|
||||
'use strict';
|
||||
|
||||
var Foo = require(6 ); // 6 = ./Foo
|
||||
var Foo = require(6); // 6 = ./Foo
|
||||
|
||||
module.exports = { type: 'bar', foo: Foo.type };
|
||||
}, 5);
|
||||
|
@ -254,13 +254,15 @@ __d(/* /Foo.js */function(global, require, module, exports) {
|
|||
|
||||
'use strict';
|
||||
|
||||
var asset = require(7 ); // 7 = ./test.png
|
||||
var asset = require(7); // 7 = ./test.png
|
||||
|
||||
module.exports = { type: 'foo', asset: asset };
|
||||
}, 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);
|
||||
__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);
|
||||
;require(0);"
|
||||
`;
|
||||
|
@ -502,8 +504,8 @@ __d(/* /TestBundle.js */function(global, require, module, exports) {
|
|||
|
||||
'use strict';
|
||||
|
||||
var Bar = require(5 ); // 5 = ./Bar
|
||||
var Foo = require(6 ); // 6 = ./Foo
|
||||
var Bar = require(5); // 5 = ./Bar
|
||||
var Foo = require(6); // 6 = ./Foo
|
||||
|
||||
module.exports = { Foo: Foo, Bar: Bar };
|
||||
}, 0);
|
||||
|
@ -511,7 +513,7 @@ __d(/* /Bar.js */function(global, require, module, exports) {
|
|||
|
||||
'use strict';
|
||||
|
||||
var Foo = require(6 ); // 6 = ./Foo
|
||||
var Foo = require(6); // 6 = ./Foo
|
||||
|
||||
module.exports = { type: 'bar', foo: Foo.type };
|
||||
}, 5);
|
||||
|
@ -519,13 +521,15 @@ __d(/* /Foo.js */function(global, require, module, exports) {
|
|||
|
||||
'use strict';
|
||||
|
||||
var asset = require(7 ); // 7 = ./test.png
|
||||
var asset = require(7); // 7 = ./test.png
|
||||
|
||||
module.exports = { type: 'foo', asset: asset };
|
||||
}, 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);
|
||||
__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);
|
||||
;require(0);"
|
||||
`;
|
||||
|
|
|
@ -20,6 +20,10 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 30 * 1000;
|
|||
|
||||
const INPUT_PATH = path.resolve(__dirname, '../basic_bundle');
|
||||
const POLYFILLS_PATH = path.resolve(__dirname, '../../Resolver/polyfills');
|
||||
const ASSET_REGISTRY_PATH = path.resolve(
|
||||
__dirname,
|
||||
'../basic_bundle/AssetRegistry',
|
||||
);
|
||||
|
||||
describe('basic_bundle', () => {
|
||||
const absPathRe = new RegExp(INPUT_PATH, 'g');
|
||||
|
@ -74,9 +78,24 @@ describe('basic_bundle', () => {
|
|||
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 () => {
|
||||
const bundleWithPolyfills = await Packager.buildBundle(
|
||||
{
|
||||
assetRegistryPath: ASSET_REGISTRY_PATH,
|
||||
getPolyfills: () => [polyfill1, polyfill2],
|
||||
projectRoots: [INPUT_PATH, POLYFILLS_PATH],
|
||||
transformCache: Packager.TransformCaching.none(),
|
||||
|
@ -89,15 +108,13 @@ describe('basic_bundle', () => {
|
|||
platform: 'ios',
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
bundleWithPolyfills.getSource().replace(absPathRe, ''),
|
||||
).toMatchSnapshot();
|
||||
verifyResultCode(bundleWithPolyfills.getSource());
|
||||
});
|
||||
|
||||
it('bundles package without polyfills as expected', async () => {
|
||||
const bundleWithoutPolyfills = await Packager.buildBundle(
|
||||
{
|
||||
assetRegistryPath: ASSET_REGISTRY_PATH,
|
||||
getPolyfills: () => [polyfill1, polyfill2],
|
||||
projectRoots: [INPUT_PATH, POLYFILLS_PATH],
|
||||
transformCache: Packager.TransformCaching.none(),
|
||||
|
@ -110,9 +127,6 @@ describe('basic_bundle', () => {
|
|||
platform: 'ios',
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
bundleWithoutPolyfills.getSource().replace(absPathRe, ''),
|
||||
).toMatchSnapshot();
|
||||
verifyResultCode(bundleWithoutPolyfills.getSource());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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