Skip to content

Commit

Permalink
Fix binary asset support in keepAssets
Browse files Browse the repository at this point in the history
The changes in #2156 broke formatting of binary kept assets, because rollup's default load hook will corrupt them.

This provides our own load hook again. But it's still OK to put this plugin after another plugin with a custom load hook, in which case we will take over starting at the `transform` stage instead. In that case, it's up to the other plugin's load hook to produce valid UTF8.
  • Loading branch information
ef4 committed Jan 22, 2025
1 parent d346bd1 commit ce177e4
Show file tree
Hide file tree
Showing 3 changed files with 13,062 additions and 9,453 deletions.
34 changes: 31 additions & 3 deletions packages/addon-dev/src/rollup-keep-assets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Plugin } from 'rollup';
import minimatch from 'minimatch';
import { dirname, relative } from 'path';
import { readFileSync } from 'fs';

// randomly chosen, we're just looking to have high-entropy identifiers that
// won't collide with anyting else in the source
Expand All @@ -15,17 +16,44 @@ export default function keepAssets({
include: string[];
exports?: undefined | 'default' | '*';
}): Plugin {
const marker = `__copy_asset_marker_${counter++}__`;
const marker = `__keep_assets_marker_${counter++}__`;

return {
name: 'copy-assets',
name: 'keep-assets',

// we implement a load hook for the assets we're keeping so that we can
// capture their true binary representations. If we fell through to the
// default rollup load hook we would get utf8 interpretations of them.
//
// Our plugin should be placed after any other plugins that have their own
// load hooks, in which case this will not run but our transform hook will
// still over from there.
load(id: string) {
if (include.some((pattern) => minimatch(id, pattern))) {
return {
code: readFileSync(id).toString('binary'),
meta: {
'keep-assets': {
binaryLoaded: true,
},
},
};
}
},

transform(code: string, id: string) {
let output: Buffer | string = code;
let ourMeta = this.getModuleInfo(id)?.meta?.['keep-assets'];
if (ourMeta?.binaryLoaded) {
// when the code was produced by our own load hook it is binary-encoded
// string and we can emit the true bytes.
output = Buffer.from(code, 'binary');
}
if (include.some((pattern) => minimatch(id, pattern))) {
let ref = this.emitFile({
type: 'asset',
fileName: relative(from, id),
source: code,
source: output,
});
if (exports === '*') {
return `export * from ${marker}("${ref}")`;
Expand Down
Loading

0 comments on commit ce177e4

Please sign in to comment.