evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
37.91k stars 1.13k forks source link

Destination path for the file loader for specific extensions #361

Closed dalcib closed 2 years ago

dalcib commented 4 years ago

The file loader works well, but all files are placed in the same folder of the bundled js or outdir. With it, css, images, fonts, etc are put all together. It gets complicated in large projects with lots of files. It would be nice if there was an option, like filepath, where would be possible to set a destination path for an extension used by the file loader. For example:

esbuild --bundle ./src/index.js --outfile=./public/js/bundle.js loader:.ttf=file  filepath:.ttf=./public/fonts 
evanw commented 4 years ago

This seems like a special-enough case that some form of plugin or custom logic is probably more appropriate. I will think about how to handle this as a plugin. People probably have all kinds of custom requirements for output directory structures that don't necessarily map to file extensions.

joelmoss commented 3 years ago

I don't think this is just something that is a nice to have. It's actually a problem when a file of the same name exists, but in a different directory...

- /app/images/avatar.png
- /app/images/user/avatar.png

The above two image share the same file name, but reside in different directories.

When built, they end up being given the same name (eg. avatar.JGBRM5DO.png) and placed in the same directory. Resulting in only one file. Yet they are different files and should both be available.

Ideally, the directory structure should be maintained, just like JS and CSS files are.

Is there a reason why the file loader doesn't respect the outbase and outdir options? Can a plugin determine where a file is written to?

joelmoss commented 3 years ago

Ah sorry, just realised that you add a hash based on the file contents - I was testing this with an identical file, but in different directories.

So this is less of an issue. However, it would be great if the file loader did maintain the input directory structure.

dalcib commented 3 years ago

I think this case can now be handled with a plugin.

norman784 commented 3 years ago

I checked the documentation and didn't find any clue where to specify the output directory for the file according to the extension, is this really possible at the moment?

dalcib commented 3 years ago

I tried to implement it with a plugin. But with the current API, it is not possible. I am reopening the issue.

evanw commented 3 years ago

No worries. I plan to extend the plugin API to implement this. I already have it working in one of my branches that contains a rewrite of the linker.

BrunoViera commented 2 years ago

Hello! any news on this? Thanks in advance

evanw commented 2 years ago

In case it’s helpful: you can do something like this using --asset-names= and [ext]: https://esbuild.github.io/api/#asset-names

anselmbradford commented 3 months ago

@dalcib How did you solve this? If I'm understanding correctly, --asset-names would be for the file loader, which wouldn't include CSS. I'm importing a css (actually scss) file into a js file and esbuild outputs both the .js and .css files into the same directory (which is /js/). In my outdir, I'd like to output the .js file into a /js/ directory, and the .css file into a /css/ directory.

EDIT: I tried setting both loader: {'.scss': 'file'} and loader: {'.css': 'file'}, and the .css file still ends up in the same directory as the .js file. I'm using the esbuild-sass-plugin to parse the scss, if that affects this..