Created
June 23, 2025 22:28
-
-
Save adamziel/624cc21a5e8575c1dce14c760c97ee31 to your computer and use it in GitHub Desktop.
esbuild support for ?url
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // build.mjs | |
| import esbuild from 'esbuild' | |
| import importUrlPlugin from './import-url-plugin.ts'; // the plugin shown earlier | |
| await esbuild.build({ | |
| entryPoints: ['src/index.ts'], | |
| bundle: true, | |
| outdir: 'build', | |
| format: 'esm', | |
| platform: 'browser', // change to 'node' if you bundle for Node | |
| publicPath: '/assets/', // base path your server uses to serve static files | |
| plugins: [importUrlPlugin()] | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| this is a file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| this is a file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import fs from 'fs'; | |
| import path from 'path'; | |
| import { createHash } from 'crypto'; | |
| import type { Plugin } from 'esbuild'; | |
| function importUrlPlugin(): Plugin { | |
| return { | |
| name: 'import-url', | |
| setup(build) { | |
| const root = build.initialOptions.absWorkingDir ?? process.cwd(); | |
| build.onResolve({ filter: /\?url$/ }, async args => { | |
| const spec = args.path.replace(/\?url$/, ''); | |
| const resolved = await build.resolve(spec, { | |
| resolveDir: args.resolveDir, | |
| kind: args.kind, | |
| importer: args.importer | |
| }); | |
| if (resolved.errors.length) return { errors: resolved.errors }; | |
| const abs = resolved.path; | |
| const rel = path | |
| .relative(root, abs) | |
| .split(path.sep) | |
| .join('/'); // posix-style for consistency | |
| return { | |
| namespace: 'url-import', | |
| path: rel, // what shows up after “url-import:” | |
| pluginData: { abs } // keep real location for onLoad | |
| }; | |
| }); | |
| build.onLoad({ filter: /.*/, namespace: 'url-import' }, async args => { | |
| const absPath: string = | |
| (args.pluginData as { abs: string }).abs ?? path.join(root, args.path); | |
| const buf = await fs.promises.readFile(absPath); | |
| const hash = createHash('sha1').update(buf).digest('hex').slice(0, 8); | |
| const ext = path.extname(absPath); | |
| const base = path.basename(absPath, ext); | |
| const fileName = `${base}-${hash}${ext}`; | |
| const outDir = | |
| build.initialOptions.outdir ?? | |
| path.dirname(build.initialOptions.outfile ?? 'dist'); | |
| await fs.promises.mkdir(outDir, { recursive: true }); | |
| await fs.promises.writeFile(path.join(outDir, fileName), buf); | |
| return { | |
| contents: `export default new URL(${JSON.stringify( | |
| fileName | |
| )}, import.meta.url).href;`, | |
| loader: 'js' | |
| }; | |
| }); | |
| } | |
| }; | |
| } | |
| export default importUrlPlugin; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var __defProp = Object.defineProperty; | |
| var __getOwnPropNames = Object.getOwnPropertyNames; | |
| var __esm = (fn, res) => function __init() { | |
| return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; | |
| }; | |
| var __export = (target, all) => { | |
| for (var name in all) | |
| __defProp(target, name, { get: all[name], enumerable: true }); | |
| }; | |
| // url-import:src/icudata.dat | |
| var icudata_exports = {}; | |
| __export(icudata_exports, { | |
| default: () => icudata_default | |
| }); | |
| var icudata_default; | |
| var init_icudata = __esm({ | |
| "url-import:src/icudata.dat"() { | |
| icudata_default = new URL("icudata-1c8c6df5.dat", import.meta.url).href; | |
| } | |
| }); | |
| // src/index.ts | |
| var imageUrl = (await Promise.resolve().then(() => (init_icudata(), icudata_exports))).default; | |
| export { | |
| imageUrl | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // @ts-ignore | |
| const imageUrl = (await import('./icudata.dat?url')).default; | |
| export { imageUrl }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "tmp", | |
| "version": "1.0.0", | |
| "description": "", | |
| "main": "index.js", | |
| "scripts": { | |
| "build": "node build.mjs" | |
| }, | |
| "keywords": [], | |
| "author": "", | |
| "license": "ISC", | |
| "type": "module" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment