Skip to content

Commit ea980fd

Browse files
gdbortonfacebook-github-bot
authored andcommitted
Adds support for publicPath to enable serving assets from different locations. (#299)
Summary: <!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. The two fields below are mandatory. --> **Summary** <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> This is an updated followup from #280, which we would still need to address the following assumptions about `/assets/`: https://github.com/facebook/metro/blob/e7deea19001d903a47868bb1fe6456bdc4b585e7/packages/metro/src/Server.js#L332 https://github.com/facebook/metro/blob/e7deea19001d903a47868bb1fe6456bdc4b585e7/packages/metro/src/Server.js#L379 https://github.com/facebook/metro/blob/e7deea19001d903a47868bb1fe6456bdc4b585e7/packages/metro/src/Server.js#L385 As pointed out by gdborton, there isn't currently a way to make this a configurable option. I am not certain how to find a proper workaround for `processRequest`. We found a temporary solution to have our express app pick up serving the assets from a publicPath as a middleware. But the change in this PR is still necessary to get it working fully. **Test plan** <!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. --> - Will add tests once we figure out a comprehensive solution Pull Request resolved: #299 Reviewed By: rafeca Differential Revision: D12939229 Pulled By: mjesun fbshipit-source-id: 769c23468c5ac434f8319e5e7caaf46dd6453f2d
1 parent 7b89dcd commit ea980fd

10 files changed

Lines changed: 88 additions & 11 deletions

File tree

packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Object {
109109
"minifierPath": "metro-minify-uglify",
110110
"optimizationSizeLimit": 153600,
111111
"postMinifyProcess": [Function],
112+
"publicPath": "/assets",
112113
"transformVariants": Object {
113114
"default": Object {},
114115
},
@@ -230,6 +231,7 @@ Object {
230231
"minifierPath": "metro-minify-uglify",
231232
"optimizationSizeLimit": 153600,
232233
"postMinifyProcess": [Function],
234+
"publicPath": "/assets",
233235
"transformVariants": Object {
234236
"default": Object {},
235237
},

packages/metro-config/src/configTypes.flow.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ type TransformerConfigT = {|
137137
postMinifyProcess: PostMinifyProcess,
138138
transformVariants: TransformVariants,
139139
workerPath: string,
140+
publicPath: string,
140141
|};
141142

142143
type MetalConfigT = {|

packages/metro-config/src/convertConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ async function convertOldToNew({
146146
? transformVariants()
147147
: defaultConfig.transformer.transformVariants,
148148
workerPath: getWorkerPath(),
149+
publicPath: '/assets',
149150
},
150151

151152
reporter,

packages/metro-config/src/defaults/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const getDefaultValues = (projectRoot: ?string): ConfigT => ({
9999
postMinifyProcess: x => x,
100100
transformVariants: {default: {}},
101101
workerPath: 'metro/src/DeltaBundler/Worker',
102+
publicPath: '/assets',
102103
},
103104
cacheStores: [
104105
new FileStore({

packages/metro/src/Assets.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,9 @@ async function getAssetData(
177177
localPath: string,
178178
assetDataPlugins: $ReadOnlyArray<string>,
179179
platform: ?string = null,
180+
publicPath: string,
180181
): Promise<AssetData> {
181-
let assetUrlPath = path.join('/assets', path.dirname(localPath));
182+
let assetUrlPath = path.join(publicPath, path.dirname(localPath));
182183

183184
// On Windows, change backslashes to slashes to get proper URL path from file path.
184185
if (path.sep === '\\') {

packages/metro/src/DeltaBundler/Serializers/getAssets.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type Options = {|
2323
assetPlugins: $ReadOnlyArray<string>,
2424
platform: ?string,
2525
projectRoot: string,
26+
publicPath: string,
2627
|};
2728

2829
async function getAssets(
@@ -44,6 +45,7 @@ async function getAssets(
4445
path.relative(options.projectRoot, module.path),
4546
options.assetPlugins,
4647
options.platform,
48+
options.publicPath,
4749
),
4850
);
4951
}

packages/metro/src/JSTransformer/worker.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type BabelTransformerOptions = $ReadOnly<{
5151
minify: boolean,
5252
platform: ?string,
5353
projectRoot: string,
54+
publicPath: string,
5455
}>;
5556

5657
export type BabelTransformerArgs = $ReadOnly<{|
@@ -88,6 +89,7 @@ export type JsTransformerConfig = $ReadOnly<{|
8889
minifierConfig: MinifierConfig,
8990
minifierPath: string,
9091
optimizationSizeLimit: number,
92+
publicPath: string,
9193
|}>;
9294

9395
export type CustomTransformOptions = {[string]: mixed, __proto__: null};
@@ -184,6 +186,7 @@ class JsTransformer {
184186
// is used by other tooling, and this would affect it.
185187
inlineRequires: false,
186188
projectRoot: this._projectRoot,
189+
publicPath: this._config.publicPath,
187190
},
188191
plugins: [],
189192
src: sourceCode,

packages/metro/src/Server.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ class Server {
237237
assetPlugins: this._config.transformer.assetPlugins,
238238
platform: transformOptions.platform,
239239
projectRoot: this._config.projectRoot,
240+
publicPath: this._config.transformer.publicPath,
240241
});
241242
}
242243

@@ -802,6 +803,7 @@ class Server {
802803
processModuleFilter: this._config.serializer.processModuleFilter,
803804
assetPlugins: this._config.transformer.assetPlugins,
804805
platform: transformOptions.platform,
806+
publicPath: this._config.transformer.publicPath,
805807
projectRoot: this._config.projectRoot,
806808
});
807809
},

packages/metro/src/__tests__/Assets-test.js

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,13 @@ describe('getAssetData', () => {
125125
'b@4.5x.png': 'b4.5 image',
126126
});
127127

128-
return getAssetData('/root/imgs/b.png', 'imgs/b.png', []).then(data => {
128+
return getAssetData(
129+
'/root/imgs/b.png',
130+
'imgs/b.png',
131+
[],
132+
null,
133+
'/assets',
134+
).then(data => {
129135
expect(data).toEqual(
130136
expect.objectContaining({
131137
__packager_asset: true,
@@ -153,7 +159,13 @@ describe('getAssetData', () => {
153159
'b@4.5x.jpg': 'b4.5 image',
154160
});
155161

156-
const data = await getAssetData('/root/imgs/b.jpg', 'imgs/b.jpg', []);
162+
const data = await getAssetData(
163+
'/root/imgs/b.jpg',
164+
'imgs/b.jpg',
165+
[],
166+
null,
167+
'/assets',
168+
);
157169

158170
expect(data).toEqual(
159171
expect.objectContaining({
@@ -173,6 +185,40 @@ describe('getAssetData', () => {
173185
);
174186
});
175187

188+
it('respects `options.publicPath` for output httpServerLocation', async () => {
189+
writeImages({
190+
'b@1x.jpg': 'b1 image',
191+
'b@2x.jpg': 'b2 image',
192+
'b@4x.jpg': 'b4 image',
193+
'b@4.5x.jpg': 'b4.5 image',
194+
});
195+
196+
const data = await getAssetData(
197+
'/root/imgs/b.jpg',
198+
'imgs/b.jpg',
199+
[],
200+
null,
201+
'/public_paths/foo-boar/',
202+
);
203+
204+
expect(data).toEqual(
205+
expect.objectContaining({
206+
__packager_asset: true,
207+
type: 'jpg',
208+
name: 'b',
209+
scales: [1, 2, 4, 4.5],
210+
fileSystemLocation: '/root/imgs',
211+
httpServerLocation: '/public_paths/foo-boar/imgs',
212+
files: [
213+
'/root/imgs/b@1x.jpg',
214+
'/root/imgs/b@2x.jpg',
215+
'/root/imgs/b@4x.jpg',
216+
'/root/imgs/b@4.5x.jpg',
217+
],
218+
}),
219+
);
220+
});
221+
176222
it('loads and runs asset plugins', async () => {
177223
jest.mock(
178224
'mockPlugin1',
@@ -206,10 +252,13 @@ describe('getAssetData', () => {
206252
'b@3x.png': 'b3 image',
207253
});
208254

209-
const data = await getAssetData('/root/imgs/b.png', 'imgs/b.png', [
210-
'mockPlugin1',
211-
'asyncMockPlugin2',
212-
]);
255+
const data = await getAssetData(
256+
'/root/imgs/b.png',
257+
'imgs/b.png',
258+
['mockPlugin1', 'asyncMockPlugin2'],
259+
null,
260+
'/assets',
261+
);
213262

214263
expect(data).toEqual(
215264
expect.objectContaining({
@@ -247,21 +296,35 @@ describe('getAssetData', () => {
247296
hash.update(fs.readFileSync(path.join('/root/imgs', name), 'utf8'));
248297
}
249298

250-
expect(await getAssetData('/root/imgs/b.jpg', 'imgs/b.jpg', [])).toEqual(
251-
expect.objectContaining({hash: hash.digest('hex')}),
252-
);
299+
expect(
300+
await getAssetData(
301+
'/root/imgs/b.jpg',
302+
'imgs/b.jpg',
303+
[],
304+
null,
305+
'/assets',
306+
),
307+
).toEqual(expect.objectContaining({hash: hash.digest('hex')}));
253308
});
254309

255310
it('changes the hash when the passed-in file watcher emits an `all` event', async () => {
256311
const initialData = await getAssetData(
257312
'/root/imgs/b.jpg',
258313
'imgs/b.jpg',
259314
[],
315+
null,
316+
'/assets',
260317
);
261318

262319
fs.writeFileSync('/root/imgs/b@4x.jpg', 'updated data');
263320

264-
const data = await getAssetData('/root/imgs/b.jpg', 'imgs/b.jpg', []);
321+
const data = await getAssetData(
322+
'/root/imgs/b.jpg',
323+
'imgs/b.jpg',
324+
[],
325+
null,
326+
'/assets',
327+
);
265328
expect(data.hash).not.toEqual(initialData.hash);
266329
});
267330
});

packages/metro/src/assetTransformer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ async function transform(
3636
filename,
3737
assetDataPlugins,
3838
options.platform,
39+
options.publicPath,
3940
);
4041

4142
return {

0 commit comments

Comments
 (0)