Skip to content

Commit 6253373

Browse files
committed
feat: support bytes for esbuild
1 parent c4d10ed commit 6253373

File tree

4 files changed

+61
-25
lines changed

4 files changed

+61
-25
lines changed

src/index.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@ const unplugin: UnpluginInstance<Options | undefined, false> = createUnplugin(
1919
enforce: options.enforce,
2020

2121
resolveId:
22-
meta.framework === 'rollup'
22+
meta.framework === 'rollup' || meta.framework === 'rolldown'
2323
? async function (this, id, importer, opt) {
24-
if ((opt as any)?.attributes?.type === 'text') {
25-
if (id.includes('?')) {
26-
id += '&raw'
27-
} else {
28-
id += '?raw'
29-
}
24+
const attributeType = (opt as any)?.attributes?.type
25+
if (attributeType === 'text') {
26+
id += `${id.includes('?') ? '&' : '?'}raw`
27+
} else if (attributeType === 'bytes') {
28+
id += `${id.includes('?') ? '&' : '?'}bytes`
3029
}
31-
3230
if (!rawRE.test(id)) return
31+
3332
const file = cleanUrl(id)
3433
const resolved = await (this as PluginContext).resolve(
3534
file,
@@ -43,32 +42,39 @@ const unplugin: UnpluginInstance<Options | undefined, false> = createUnplugin(
4342

4443
load: {
4544
filter: { id: { include: rawRE } },
46-
handler(id) {
45+
async handler(id) {
4746
const file = cleanUrl(id)
4847
const context = this.getNativeBuildContext?.()
4948
const transform =
5049
context?.framework === 'esbuild'
5150
? context.build.esbuild.transform
5251
: undefined
53-
return transformRaw(
52+
const contents = await transformRaw(
5453
file,
5554
transformFilter,
55+
false,
5656
options.transform.options,
5757
transform,
5858
)
59+
return contents as string
5960
},
6061
},
6162
esbuild: {
6263
setup(build) {
6364
build.onLoad({ filter: /.*/ }, async (args) => {
64-
if (args.with.type === 'text') {
65+
const isBytes = args.with.type === 'bytes'
66+
if (args.with.type === 'text' || isBytes) {
6567
const contents = await transformRaw(
6668
args.path,
6769
transformFilter,
70+
isBytes,
6871
options.transform.options,
6972
build.esbuild.transform,
7073
)
71-
return { contents, loader: 'js' }
74+
return {
75+
contents,
76+
loader: typeof contents === 'string' ? 'js' : 'binary',
77+
}
7278
}
7379
})
7480
},
@@ -79,6 +85,7 @@ const unplugin: UnpluginInstance<Options | undefined, false> = createUnplugin(
7985
export default unplugin
8086

8187
const rawRE = /[&?]raw(?:&|$)/
88+
// const bytesRE = /[&?]bytes(?:&|$)/
8289
const postfixRE = /[#?].*$/s
8390
function cleanUrl(url: string) {
8491
return url.replace(postfixRE, '')
@@ -109,16 +116,17 @@ export function guessLoader(id: string): Loader {
109116
async function transformRaw(
110117
file: string,
111118
transformFilter: (id: string | unknown) => boolean,
119+
isBytes: boolean,
112120
options: TransformOptions,
113121
transform?: typeof import('esbuild').transform,
114122
) {
115-
let contents = await readFile(file, 'utf-8')
123+
let contents = await readFile(file, isBytes ? undefined : 'utf8')
116124

117-
if (transformFilter(file)) {
125+
if (!isBytes && transformFilter(file)) {
118126
transform ||= (await import('esbuild')).transform
119127
contents = (
120128
await transform(contents, { loader: guessLoader(file), ...options })
121129
).code
122130
}
123-
return `export default ${JSON.stringify(contents)}`
131+
return isBytes ? contents : `export default ${JSON.stringify(contents)}`
124132
}

tests/__snapshots__/basic.test.ts.snap

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`esbuild 1`] = `
4-
"// tests/fixtures/ts.ts?raw
4+
"var __toBinary = /* @__PURE__ */ (() => {
5+
var table = new Uint8Array(128);
6+
for (var i = 0; i < 64; i++) table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i;
7+
return (base64) => {
8+
var n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == "=") - (base64[n - 2] == "=")) * 3 / 4 | 0);
9+
for (var i2 = 0, j = 0; i2 < n; ) {
10+
var c0 = table[base64.charCodeAt(i2++)], c1 = table[base64.charCodeAt(i2++)];
11+
var c2 = table[base64.charCodeAt(i2++)], c3 = table[base64.charCodeAt(i2++)];
12+
bytes[j++] = c0 << 2 | c1 >> 4;
13+
bytes[j++] = c1 << 4 | c2 >> 2;
14+
bytes[j++] = c2 << 6 | c3;
15+
}
16+
return bytes;
17+
};
18+
})();
19+
20+
// tests/fixtures/ts.ts?raw
521
var ts_default = 'export const msg = "hello ts";\\n';
622
723
// tests/fixtures/js.js?raw
@@ -13,8 +29,11 @@ var jsx_default = 'export const msg = /* @__PURE__ */ React.createElement("div",
1329
// tests/fixtures/with.js
1430
var with_default = 'export const msg = "hello with";\\n';
1531
32+
// tests/fixtures/abc.txt
33+
var abc_default = __toBinary("YWJjCg==");
34+
1635
// <stdin>
17-
console.log(ts_default, js_default, jsx_default, with_default);
36+
console.log(ts_default, js_default, jsx_default, with_default, abc_default);
1837
"
1938
`;
2039

tests/basic.test.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@ import Raw from '../src'
66

77
const resolveDir = path.resolve(__dirname, 'fixtures')
88

9-
const contents = `
10-
import text from "./ts.ts?raw"
11-
import text2 from "./js.js?raw"
12-
import text3 from "./jsx.jsx?raw"
13-
import text4 from "./with.js" with { type: "text" }
14-
console.log(text, text2, text3, text4)
15-
`
16-
179
test('esbuild', async () => {
10+
const contents = `
11+
import text from "./ts.ts?raw"
12+
import text2 from "./js.js?raw"
13+
import text3 from "./jsx.jsx?raw"
14+
import text4 from "./with.js" with { type: "text" }
15+
import bytes1 from "./abc.txt" with { type: "bytes" }
16+
console.log(text, text2, text3, text4, bytes1)
17+
`
18+
1819
const result = await build({
1920
stdin: {
2021
contents,
@@ -29,6 +30,13 @@ test('esbuild', async () => {
2930
})
3031

3132
test('rollup', async () => {
33+
const contents = `
34+
import text from "./ts.ts?raw"
35+
import text2 from "./js.js?raw"
36+
import text3 from "./jsx.jsx?raw"
37+
import text4 from "./with.js" with { type: "text" }
38+
console.log(text, text2, text3, text4)
39+
`
3240
const entryFile = path.resolve(resolveDir, 'main.js')
3341
const bundle = await rollup({
3442
input: [entryFile],

tests/fixtures/abc.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
abc

0 commit comments

Comments
 (0)