Currently, parcel generates bundle names here: https://github.com/parcel-bundler/parcel/blob/8a95f70ff04da6cc32c92278155b112cb37105f0/src/Asset.js#L188
with the generateBundleName function, which is provided by the Asset base class. 
However, one pattern of structuring web application can be like this:
| Resource | Bundle Path |
| --- | --- |
| images (jpg, png, gif, ico, etc.) | /img/{resource-id}.{ext} |
| svg | /svg/{resource-id}.{ext} |
| fonts (woff, eot, ttf, etc)  | /fonts/{resource-id}.{ext} |
| js | /js/{resource-id}.{ext} |
| styles | /css/{resource-id}.{ext} | 
Is there a way to accomplish this with Parcel now? If not, I think it would be great if the generateBundleName can be easily overridden to support use cases like these. It should then be fairly easy to do this in one place as a form of user plugin/config, etc.
Not sure what you mean?
Currently it's not possible to overwrite it.
The current behaviour is: {content-hash}.{name}.{ext}
In case of specific assets that are used for SEO (basically non-js/non-css) it just maintains the same name as input
@DeMoorJasper,
I'm taking about accomplishing something similar to this webpack config. Especially, in the relevant directory path - don't care so much about the basenames of the files really.
// fragments from my .neutrinorc.js (webpack-chain): 
          image: {
            img: { name: "img/[name].[hash].[ext]" },
            ico: { name: "img/ico/[name].[hash].[ext]" },
            svg: { name: "svg/[name].[hash].[ext]" }
          },
          font: {
            woff: { name: "fonts/[name].[hash].[ext]" },
            ttf: { name: "fonts/[name].[hash].[ext]" },
            eot: { name: "fonts/[name].[hash].[ext]" }
          },
...
      config.output
        .filename("js/[name].[hash].js")
        .chunkFilename("js/chunks/[name].[chunkhash].js")
        .sourceMapFilename("js/[file].[hash].map");
Infact, here's my actual config for reference: https://github.com/prasannavl/prasannavl.com/blob/ccaa05b986358184a7c2cbe06bd50aacbdf01d2f/.neutrinorc.js
Currently, with parcel, the tree below still produces a flat output, no matter what. An option to retain the tree would be one way.
src/
βββ index.html
βββ js
βΒ Β  βββ index.js
βββ styles
    βββ index.scss
2 directories, 3 files
Current output:
dist/
βββ index.html
βββ js.d033b3f6.js
βββ js.d033b3f6.map
βββ styles.672b63bd.css
What could be useful:
dist/
βββ index.html
βββ js
βΒ Β  βββ js.d033b3f6.js
βΒ Β  βββ js.d033b3f6.map
βββ styles
    βββ styles.672b63bd.css
Quite possibly, even the file names can be retained.
@DeMoorJasper - Is there any way at all to customise this at it's current state or get close to one of the above configurations (webpack one, or a similar tree)?
@prasannavl the hash will never be removed I think as itβs used for cache invalidating and never having 2 files with the same name. However it might be configurable in the future although Iβm not sure.
Sent with GitHawk
@DeMoorJasper - Of course, the hash is useful. As previously stated, I'm mostly concerned about the path of the files rather than the names. This is a blocker for me to move to parcel, as having every asset of every kind just dumped into the root isn't acceptable.
same problem
Same problem... Option for custom name would be great
Same here, voting this up!
Parcel is great, with this, even greater!
Iβm mostly just trying to understand and learn so bear with me: what is the reason for controlling the output directory structure? What are the benefits? Iβve never had to do this so Iβm hoping to learn something new
@luishasmail - Would you be happy if everything in your filesystem can only just be dumped in the root? Or perhaps a shared static file server to have everything dumped under one place?
The use cases here are very subjective and I consider this to be rather fundamental. Complex projects could have any number of requirements that need their controlled project structure - build systems, debugging, automation, project conventions, or even simply just for cognitive clarity etc.
To be honest I donβt have a ton of experience deploying apps so I donβt really know. I usually think of the dist folder as a black box, but I see your point now. Thanks for the quick response!
Custom naming strategies will be possible with Parcel 2 (the default will however still be the same afaik)
I'm not sure why people care about the output filenames of static assets so much. They are really just implementation details. Are there actual use cases for this level of control?
That said, in parcel 2, you will be able to override file naming with plugins.
It would be great if we can pass a function to generate hash.
For example I trying to migrate from react-scripts to parcel.
Everything works fine, but on my SSR part I have something like:
import "reflect-metadata";
const crypto = require("crypto");
const path = require("path");
// CSS styles will be imported on load and that complicates matters... ignore those bad boys!
import * as ignoreStyles from "ignore-styles";
// We also want to ignore all image requests
// When running locally these will load from a standard import
// When running on the server, we want to load via their hashed version in the build folder
const extensions = [".gif", ".jpeg", ".jpg", ".png", ".svg"];
// Override the default style ignorer, also modifying all image requests
ignoreStyles.default(ignoreStyles.DEFAULT_EXTENSIONS, (mod, filename) => {
  if (!extensions.find((f) => filename.endsWith(f))) {
    // If we find a style
    return ignoreStyles.noOp();
  } else {
    console.log(filename);
    // If we find an image
    // @IMPORTANT: this should be the same as Parcel hash generator
    // otherwise different filenames are being generated which results 404 =(
    const hash = crypto.createHash("md5").update(path.basename(filename)).digest("hex").slice(0, 8);
    const bn = path.basename(filename).replace(/(\.\w{3})$/, `.${hash}$1`);
    mod.exports = `/static/${bn}`;
  }
});
// Set up babel to do its thing... env for the latest toys, react-app for CRA
// Notice three plugins: the first two allow us to use import rather than require, the third is for code splitting
// Polyfill is required for Babel 7, polyfill includes a custom regenerator runtime and core-js
require("@babel/polyfill");
require("@babel/register")({
  cwd: path.resolve(process.cwd(), "../client"),
  cache: true,
  extensions: [".ts", ".js", ".tsx", ".jsx"],
  ignore: [/\/(dist|node_modules)\//],
  plugins: [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-syntax-dynamic-import",
    ["babel-plugin-root-import", { rootPathSuffix: "src" }],
    ["@babel/plugin-transform-runtime", { corejs: 2 }],
    "dynamic-import-node",
    "react-loadable/babel",
  ],
  presets: [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript",
  ],
});
// Now that the nonsense is over... load up the server entry point
require("./server");
This is the index.ts file on server side where I configure babel and other things.
So I should generate the same hash here:
const hash = crypto.createHash("md5").update(path.basename(filename)).digest("hex").slice(0, 8);
to have the same filename for my assets. And it would be great if we could pass some function to do this, not duplicating code from Parcel which can be changed. Or if I doing something rong point me please.
Most helpful comment
@DeMoorJasper - Of course, the hash is useful. As previously stated, I'm mostly concerned about the path of the files rather than the names. This is a blocker for me to move to parcel, as having every asset of every kind just dumped into the root isn't acceptable.