Skip to content

Commit

Permalink
feat: add assetPath to remote assets config (#651)
Browse files Browse the repository at this point in the history
* add assetPath to remote assets config

* pr fixes, revert assetsDirname in remote assets path

* improve typing in assetsLoader.test.ts

* add changeset

---------

Co-authored-by: Adam Mruk <[email protected]>
  • Loading branch information
adammruk and Adam Mruk authored Jul 4, 2024
1 parent e31f6cc commit a385b2b
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/yellow-deers-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@callstack/repack": minor
---

added 'assetPath' field to remote assets config, enabling granular control over the generated URL and server location to the asset
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ async function compileBundle(
inline?: boolean,
remote?: {
enabled: boolean;
assetPath?: (args: {
resourcePath: string;
resourceFilename: string;
resourceDirname: string;
resourceExtensionType: string;
}) => string;
publicPath: string;
}
) {
Expand Down Expand Up @@ -395,5 +401,78 @@ describe('assetLoader', () => {
scale: 1,
});
});

describe('with specified assetPath', () => {
it('without scales', async () => {
const { code } = await compileBundle(
'ios', // platform doesn't matter for remote-assets
{
'./index.js': "export { default } from './__fixtures__/logo.png';",
},
false,
{
enabled: true,
assetPath: ({
resourceFilename,
resourceDirname,
resourceExtensionType,
}) => {
return `${resourceDirname}/nested-folder/${resourceFilename}-fake-hash.${resourceExtensionType}`;
},
publicPath: 'http://localhost:9999/remote-assets',
}
);

const context: { Export?: { default: Record<string, any> } } = {};
vm.runInNewContext(code, context);

expect(context.Export?.default).toEqual({
__packager_asset: true,
uri: `http://localhost:9999/remote-assets/assets/__fixtures__/nested-folder/logo-fake-hash.png`,
height: 393,
width: 2292,
scale: 1,
});
});

it.each([
{ prefferedScale: 1 },
{ prefferedScale: 2 },
{ prefferedScale: 3 },
])('with scales $prefferedScale', async ({ prefferedScale }) => {
const { code } = await compileBundle(
'ios', // platform doesn't matter for remote-assets
{
'node_modules/react-native/Libraries/Utilities/PixelRatio.js': `module.exports = { get: () => ${prefferedScale} };`,
'./index.js': "export { default } from './__fixtures__/star.png';",
},
false,
{
enabled: true,
assetPath: ({
resourceFilename,
resourceDirname,
resourceExtensionType,
}) => {
return `${resourceDirname}/nested-folder/${resourceFilename}-fake-hash.${resourceExtensionType}`;
},
publicPath: 'http://localhost:9999',
}
);

const context: { Export?: { default: Record<string, any> } } = {};
vm.runInNewContext(code, context);

expect(context.Export?.default).toEqual({
__packager_asset: true,
uri: `http://localhost:9999/assets/__fixtures__/nested-folder/star-fake-hash${
prefferedScale === 1 ? '' : '@x' + prefferedScale
}.png`,
height: 272,
width: 286,
scale: prefferedScale,
});
});
});
});
});
43 changes: 34 additions & 9 deletions packages/repack/src/webpack/loaders/assetsLoader/assetsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ export default async function repackAssetsLoader(this: LoaderContext<Options>) {
this.addDependency(filenameWithScale);
}

const remoteAssetPathOption =
options.remote?.enabled && options.remote?.assetPath
? options.remote?.assetPath({
resourcePath,
resourceFilename,
resourceDirname,
resourceExtensionType,
})
: null;

const remoteAssetResource = remoteAssetPathOption
? {
filename: path.basename(
remoteAssetPathOption,
`.${resourceExtensionType}`
),
path: path.dirname(remoteAssetPathOption),
}
: null;

const assets = await Promise.all<Asset>(
scaleKeys.map(async (scaleKey) => {
const filenameWithScale = path.join(
Expand Down Expand Up @@ -148,15 +168,20 @@ export default async function repackAssetsLoader(this: LoaderContext<Options>) {

destination = path.join(destination, resourceNormalizedFilename);
} else {
const name = `${resourceFilename}${
const name = `${remoteAssetResource?.filename ?? resourceFilename}${
scaleKey === '@1x' ? '' : scaleKey
}.${resourceExtensionType}`;
destination = path.join(
options.remote?.enabled ? remoteAssetsDirname : '',
assetsDirname,
resourceDirname,
name
);

if (options.remote?.enabled) {
destination = path.join(
remoteAssetsDirname,
assetsDirname,
remoteAssetResource?.path ?? resourceDirname,
name
);
} else {
destination = path.join(assetsDirname, resourceDirname, name);
}
}

return {
Expand Down Expand Up @@ -205,9 +230,9 @@ export default async function repackAssetsLoader(this: LoaderContext<Options>) {
assets,
assetsDirname,
remotePublicPath: options.remote.publicPath,
resourceDirname,
resourceDirname: remoteAssetResource?.path ?? resourceDirname,
resourceExtensionType,
resourceFilename,
resourceFilename: remoteAssetResource?.filename ?? resourceFilename,
resourcePath,
suffixPattern,
pathSeparatorRegexp,
Expand Down
7 changes: 7 additions & 0 deletions packages/repack/src/webpack/loaders/assetsLoader/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export interface Options {
publicPath?: string;
remote?: {
enabled: boolean;
assetPath?: (args: {
resourcePath: string;
resourceFilename: string;
resourceDirname: string;
resourceExtensionType: string;
}) => string;
publicPath: string;
};
}
Expand All @@ -32,6 +38,7 @@ export const optionsSchema: Schema = {
required: ['enabled', 'publicPath'],
properties: {
enabled: { type: 'boolean' },
assetPath: { instanceOf: 'Function' },
publicPath: { type: 'string', pattern: '^https?://' },
},
},
Expand Down

0 comments on commit a385b2b

Please sign in to comment.