title: Any future-proof way to locally override how a file is loaded with common bundlers (Webpack, esbuild, etc)?
body: <p>I like Webpack. Notably the ability to locally override how a certain file is loaded using the <a href="https://webpack.js.org/concepts/loaders/#inline" rel="nofollow noreferrer">inline loader syntax</a>.</p>
  <p>Let's say I have a global configuration for loading images (using a dedicated loader that applies optimization, decides to return either a data url or an URL based on image size, etc.), but locally I want to override it to be sure to just obtain the contents of the image as a Buffer. I could do something like this:</p>
  <pre class="lang-js prettyprint-override"><code>import imageBuffer from '!buffer-loader!./image.png';
  </code></pre>
  <p>It's very nice because the code is able to specify <em>locally, on site</em> what kind of data structure it wants. That does not depend on some global configuration.</p>
  <p>It can even be typed with TypeScript!</p>
  <pre class="lang-js prettyprint-override"><code>
  declare module '!buffer-loader!*.png' {
      const buffer: Buffer;
  
      export default buffer;
  }
  </code></pre>
  <p>The only problem is, it's a very Webpack-specific syntax that has 0 chances from being standardized.</p>
  <p>We're assisting to a rise of concurrent, high performance bundlers like <a href="https://parceljs.org/" rel="nofollow noreferrer">Parcel</a>, <a href="https://esbuild.github.io/" rel="nofollow noreferrer">esbuild</a> and more.</p>
  <p>Chances are I want to migrate away from Webpack some day. No project is eternal.
  Web bundlers will probably be there for a long time though.</p>
  <p>And I wonder, what could be a way to do what I did above, in a way that doesn't screw me the day I'd like to migrate? (So, not using a very Webpack-specific syntax)</p>
  <p>All common bundlers seem to support a notion of mapping <code>extension =&gt; data type or loader</code>. It should be a common denominator.</p>
  <p>So I thought, maybe use some conventions building on that, and therefore use extensions to indicate the bundler how the file should be loaded.</p>
  <pre class="lang-js prettyprint-override"><code>import imageBuffer from './some-image.$buffer.png';
  import imageDataUrl from './another-image.$data-url.png';
  </code></pre>
  <p>Then we should be able to tell any (?) bundler to map the sub-extensions accordingly:</p>
  <pre><code>*.$buffer.* =&gt; buffer loader
  *.$data-url.* =&gt; data url loader
  </code></pre>
  <p>Etc.
  On one hand, I guess it can be ported to any bundler. And it's a relatively simple and solid convention. If a bundler can't do that I will probably not be using it.</p>
  <p>On the other hand, I don't like the fact that I have to specify the target data type as an extension that's not inherent to the file. What if I want to load a same file but in two different formats? (yes, that happened in one of my projects).
  Symlinking could help on that to not physically duplicate the file, but that's not terrible either and it won't work if the bundler follows symlinks (original extension will be read).</p>
  <p>I'm seeking advices from people who are familiar with different builders and what would they do if they had to make the same choice.</p>