diff --git a/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap b/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap index be90805d18..724d128c20 100644 --- a/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap +++ b/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap @@ -108,6 +108,7 @@ Object { "minifierPath": "metro-minify-uglify", "optimizationSizeLimit": 153600, "postMinifyProcess": [Function], + "publicPath": "/assets", "transformVariants": Object { "default": Object {}, }, @@ -228,6 +229,7 @@ Object { "minifierPath": "metro-minify-uglify", "optimizationSizeLimit": 153600, "postMinifyProcess": [Function], + "publicPath": "/assets", "transformVariants": Object { "default": Object {}, }, diff --git a/packages/metro-config/src/configTypes.flow.js b/packages/metro-config/src/configTypes.flow.js index eca73d99ce..b46c17aa69 100644 --- a/packages/metro-config/src/configTypes.flow.js +++ b/packages/metro-config/src/configTypes.flow.js @@ -130,6 +130,7 @@ type TransformerConfigT = {| postMinifyProcess: PostMinifyProcess, transformVariants: TransformVariants, workerPath: string, + publicPath: string, |}; type MetalConfigT = {| diff --git a/packages/metro-config/src/convertConfig.js b/packages/metro-config/src/convertConfig.js index d854e15951..a1c7c6f8a6 100644 --- a/packages/metro-config/src/convertConfig.js +++ b/packages/metro-config/src/convertConfig.js @@ -145,6 +145,7 @@ async function convertOldToNew({ ? transformVariants() : defaultConfig.transformer.transformVariants, workerPath: getWorkerPath(), + publicPath: '/assets', }, reporter, diff --git a/packages/metro-config/src/defaults/index.js b/packages/metro-config/src/defaults/index.js index d820fc8fa9..1f68c9b301 100644 --- a/packages/metro-config/src/defaults/index.js +++ b/packages/metro-config/src/defaults/index.js @@ -98,6 +98,7 @@ const getDefaultValues = (projectRoot: ?string): ConfigT => ({ postMinifyProcess: x => x, transformVariants: {default: {}}, workerPath: 'metro/src/DeltaBundler/Worker', + publicPath: '/assets', }, cacheStores: [ new FileStore({ diff --git a/packages/metro/src/Assets.js b/packages/metro/src/Assets.js index 5ab85a91cf..db3999392b 100644 --- a/packages/metro/src/Assets.js +++ b/packages/metro/src/Assets.js @@ -177,8 +177,9 @@ async function getAssetData( localPath: string, assetDataPlugins: $ReadOnlyArray, platform: ?string = null, + publicPath: string, ): Promise { - let assetUrlPath = path.join('/assets', path.dirname(localPath)); + let assetUrlPath = path.join(publicPath, path.dirname(localPath)); // On Windows, change backslashes to slashes to get proper URL path from file path. if (path.sep === '\\') { diff --git a/packages/metro/src/DeltaBundler/Serializers/getAssets.js b/packages/metro/src/DeltaBundler/Serializers/getAssets.js index a34437dce9..682bd86f43 100644 --- a/packages/metro/src/DeltaBundler/Serializers/getAssets.js +++ b/packages/metro/src/DeltaBundler/Serializers/getAssets.js @@ -23,6 +23,7 @@ type Options = {| assetPlugins: $ReadOnlyArray, platform: ?string, projectRoot: string, + publicPath: string, |}; async function getAssets( @@ -44,6 +45,7 @@ async function getAssets( path.relative(options.projectRoot, module.path), options.assetPlugins, options.platform, + options.publicPath, ), ); } diff --git a/packages/metro/src/JSTransformer/worker.js b/packages/metro/src/JSTransformer/worker.js index 9b95be602d..8b82eb0edc 100644 --- a/packages/metro/src/JSTransformer/worker.js +++ b/packages/metro/src/JSTransformer/worker.js @@ -51,6 +51,7 @@ type BabelTransformerOptions = $ReadOnly<{ minify: boolean, platform: ?string, projectRoot: string, + publicPath: string, }>; export type BabelTransformerArgs = $ReadOnly<{| @@ -88,6 +89,7 @@ export type JsTransformerConfig = $ReadOnly<{| minifierConfig: MinifierConfig, minifierPath: string, optimizationSizeLimit: number, + publicPath: string, |}>; export type CustomTransformOptions = {[string]: mixed, __proto__: null}; @@ -184,6 +186,7 @@ class JsTransformer { // is used by other tooling, and this would affect it. inlineRequires: false, projectRoot: this._projectRoot, + publicPath: this._config.publicPath, }, plugins: [], src: sourceCode, diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 750b080259..714444595f 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -237,6 +237,7 @@ class Server { assetPlugins: this._config.transformer.assetPlugins, platform: transformOptions.platform, projectRoot: this._config.projectRoot, + publicPath: this._config.transformer.publicPath, }); } @@ -798,6 +799,7 @@ class Server { processModuleFilter: this._config.serializer.processModuleFilter, assetPlugins: this._config.transformer.assetPlugins, platform: transformOptions.platform, + publicPath: this._config.transformer.publicPath, projectRoot: this._config.projectRoot, }); }, diff --git a/packages/metro/src/__tests__/Assets-test.js b/packages/metro/src/__tests__/Assets-test.js index b53e01c326..8a1eb09afb 100644 --- a/packages/metro/src/__tests__/Assets-test.js +++ b/packages/metro/src/__tests__/Assets-test.js @@ -125,7 +125,13 @@ describe('getAssetData', () => { 'b@4.5x.png': 'b4.5 image', }); - return getAssetData('/root/imgs/b.png', 'imgs/b.png', []).then(data => { + return getAssetData( + '/root/imgs/b.png', + 'imgs/b.png', + [], + null, + '/assets', + ).then(data => { expect(data).toEqual( expect.objectContaining({ __packager_asset: true, @@ -153,7 +159,13 @@ describe('getAssetData', () => { 'b@4.5x.jpg': 'b4.5 image', }); - const data = await getAssetData('/root/imgs/b.jpg', 'imgs/b.jpg', []); + const data = await getAssetData( + '/root/imgs/b.jpg', + 'imgs/b.jpg', + [], + null, + '/assets', + ); expect(data).toEqual( expect.objectContaining({ @@ -173,6 +185,40 @@ describe('getAssetData', () => { ); }); + it('respects `options.publicPath` for output httpServerLocation', async () => { + writeImages({ + 'b@1x.jpg': 'b1 image', + 'b@2x.jpg': 'b2 image', + 'b@4x.jpg': 'b4 image', + 'b@4.5x.jpg': 'b4.5 image', + }); + + const data = await getAssetData( + '/root/imgs/b.jpg', + 'imgs/b.jpg', + [], + null, + '/public_paths/foo-boar/', + ); + + expect(data).toEqual( + expect.objectContaining({ + __packager_asset: true, + type: 'jpg', + name: 'b', + scales: [1, 2, 4, 4.5], + fileSystemLocation: '/root/imgs', + httpServerLocation: '/public_paths/foo-boar/imgs', + files: [ + '/root/imgs/b@1x.jpg', + '/root/imgs/b@2x.jpg', + '/root/imgs/b@4x.jpg', + '/root/imgs/b@4.5x.jpg', + ], + }), + ); + }); + it('loads and runs asset plugins', async () => { jest.mock( 'mockPlugin1', @@ -206,10 +252,13 @@ describe('getAssetData', () => { 'b@3x.png': 'b3 image', }); - const data = await getAssetData('/root/imgs/b.png', 'imgs/b.png', [ - 'mockPlugin1', - 'asyncMockPlugin2', - ]); + const data = await getAssetData( + '/root/imgs/b.png', + 'imgs/b.png', + ['mockPlugin1', 'asyncMockPlugin2'], + null, + '/assets', + ); expect(data).toEqual( expect.objectContaining({ @@ -247,9 +296,15 @@ describe('getAssetData', () => { hash.update(fs.readFileSync(path.join('/root/imgs', name), 'utf8')); } - expect(await getAssetData('/root/imgs/b.jpg', 'imgs/b.jpg', [])).toEqual( - expect.objectContaining({hash: hash.digest('hex')}), - ); + expect( + await getAssetData( + '/root/imgs/b.jpg', + 'imgs/b.jpg', + [], + null, + '/assets', + ), + ).toEqual(expect.objectContaining({hash: hash.digest('hex')})); }); it('changes the hash when the passed-in file watcher emits an `all` event', async () => { @@ -257,11 +312,19 @@ describe('getAssetData', () => { '/root/imgs/b.jpg', 'imgs/b.jpg', [], + null, + '/assets', ); fs.writeFileSync('/root/imgs/b@4x.jpg', 'updated data'); - const data = await getAssetData('/root/imgs/b.jpg', 'imgs/b.jpg', []); + const data = await getAssetData( + '/root/imgs/b.jpg', + 'imgs/b.jpg', + [], + null, + '/assets', + ); expect(data.hash).not.toEqual(initialData.hash); }); }); diff --git a/packages/metro/src/assetTransformer.js b/packages/metro/src/assetTransformer.js index 6892670ce3..bf5fd15f2a 100644 --- a/packages/metro/src/assetTransformer.js +++ b/packages/metro/src/assetTransformer.js @@ -36,6 +36,7 @@ async function transform( filename, assetDataPlugins, options.platform, + options.publicPath, ); return {