Skip to content

Adjust asset referenced from css#5452

Draft
ealmloff wants to merge 11 commits intoDioxusLabs:mainfrom
ealmloff:adjust-manganis-references
Draft

Adjust asset referenced from css#5452
ealmloff wants to merge 11 commits intoDioxusLabs:mainfrom
ealmloff:adjust-manganis-references

Conversation

@ealmloff
Copy link
Copy Markdown
Member

@ealmloff ealmloff commented Apr 6, 2026

Adds an asset collector which finds all assets references from inside css and adds those to the bundle. When we optimize the css, we rewrite the urls to match the bundled paths of the assets

Addresses part of #3325

@ealmloff ealmloff added cli Related to the dioxus-cli program manganis Related to the manganis crate labels Apr 6, 2026
@jkelleyrtp
Copy link
Copy Markdown
Member

jkelleyrtp commented Apr 6, 2026

esbuild has some customizable hooks for loaders and entrypoints. I was planning on using that to implement the hot-reload and fan-out build system.

Deno maintains an api for esbuild here https://github.com/denoland/esbuild_client that we could use


when esbuild runs to bundle css, is there a way of viewing which css files it links together using pathing? or control the loader?

Yes, you can control both of these things with esbuild.

Viewing which files esbuild resolves: You can use the metafile option. When enabled, esbuild produces a JSON structure that maps every output file to the input files that contributed to it, including the full dependency graph for CSS @import chains.

const result = await esbuild.build({
  entryPoints: ['src/styles/main.css'],
  bundle: true,
  outdir: 'dist',
  metafile: true,
});

// Print a human-readable summary
console.log(await esbuild.analyzeMetafile(result.metafile));

// Or inspect the raw object
for (const [output, info] of Object.entries(result.metafile.outputs)) {
  console.log(output, '←', Object.keys(info.inputs));
}

This shows you exactly which .css files were pulled in and how they were resolved.

Controlling the loader: You can explicitly tell esbuild how to treat file extensions with the loader option:

await esbuild.build({
  entryPoints: ['src/app.css'],
  bundle: true,
  loader: {
    '.css': 'css',          // default — bundle as CSS
    '.module.css': 'local-css', // CSS modules (scoped class names)
    '.png': 'file',         // copy to outdir, emit URL
    '.svg': 'dataurl',      // inline as data URI
    '.woff2': 'file',
  },
  outdir: 'dist',
});

The key CSS-relevant loaders are css (standard bundling, resolves @import and url()), local-css (CSS modules with scoped names), and empty (ignore the file entirely).

Controlling path resolution: If esbuild isn't finding files where you expect, you can tweak resolution with resolveExtensions, alias, or nodePaths:

await esbuild.build({
  // ...
  alias: {
    '@styles': './src/styles',
  },
  nodePaths: ['./shared-css'],  // extra directories to search
});

You can also write a plugin with an onResolve callback for full control over how any import path maps to a file on disk — useful if you have non-standard path conventions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli Related to the dioxus-cli program manganis Related to the manganis crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants