npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

file-replace-loader

v1.4.3

Published

file-replace-loader is webpack loader that allows you replace files in compile time

Downloads

30,315

Readme

file-replace-loader

version npm downloads license

file-replace-loader is a webpack loader that allows you to replace files at compile time based on conditions.

file-replace-loader is free and will always remain free A simple and quick way to support the project is to buy me a coffee. It will take no more than 5 minutes and will allow the project to keep going

Table of contents

Features

  • Compatibility with webpack 3.x, 4.x, 5.x;
  • Supports webpack watch mode;
  • Replace files at compile time without changing source files;
  • Multiple replacement;
  • Sync and async modes;
  • Compatibility with other loaders;
  • Support binary files.

Installation

NPM

npm install --save-dev file-replace-loader

Yarn

yarn add file-replace-loader

Usage

const { resolve } = require('path');

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.config\.js$/,
      loader: 'file-replace-loader',
      options: {
        condition: 'if-replacement-exists',
        replacement: resolve('./config.local.js'),
        async: true,
      }
    }]
  }
}

This rule replaces matching /\.config\.js$/ files with config.local.js, if replacement exists (condition if-replacement-exists).

After the build, the bundle will contain code from config.local.js, while original sources won't be changed.

Multiple replace

To describe replace rules for two or more files you can use function as replacement value.

How does it work?

  1. Webpack runs file-replace-loader according to test rule, include and exclude rule options;
  2. file-replace-loader checks the replacement option. If it is a string, the loader replaces the file. If it is a function, then file-replace-loader checks what it returns. If the function returns a file path, the loader replaces the file; if it returns nothing, the current match is skipped.
  3. If the replacement function returns a path, file-replace-loader checks condition. If condition is always, it replaces every match. If condition is if-replacement-exists, the loader checks whether the file exists, etc;

For example:

const { resolve } = require('path');

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'file-replace-loader',
      options: {
        condition: 'always', // <-- Note that the rule applies for all files!
        replacement(resourcePath) {
          if (resourcePath.endsWith('foo.js')) {
            return resolve('./bar.js');
          }
          if (resourcePath.endsWith('foo-a.js')) {
            return resolve('./bar-a.js');
          }
        },
        async: true,
      }
    }]
  }
}

file-replace-loader passes resourcePath to the replacement function for every matched file. file-replace-loader does not enforce how this path is processed, but if the replacement function returns a new path, file-replace-loader replaces the file. If the replacement function returns nothing, file-replace-loader skips replacement for the current resourcePath.

Example with mapping:

const { resolve } = require('path');

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'file-replace-loader',
      options: {
        condition: 'always', // <-- Note that the rule applies for all files! But you can use other conditions too
        replacement(resourcePath) {
          const mapping = {
            [resolve('./src/foo-a.js')]: resolve('./src/bar-a.js'),
            [resolve('./src/foo-b.js')]: resolve('./src/bar-b.js'),
            [resolve('./src/foo-c.js')]: resolve('./src/bar-c.js'),
          };
          return mapping[resourcePath];
        },
        async: true,
      }
    }]
  }
}

NOTE: Make sure that all replacement files contain the necessary imports and exports that other files are expecting.

Using with binary files

file-replace-loader allows replacing binary files. For example:

//webpack.config.js

const { resolve } = require('path');

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.png$/,
      use: [{
        loader: 'file-loader',
        options: {
          name: '[name].[ext]',
        },
      }, {
        loader: 'file-replace-loader',
        options: {
          condition: 'if-replacement-exists',
          replacement: resolve('./src/replacement.png')
        }
      }]
    }]
  }
}

Using with other loaders

file-replace-loader must execute before other loaders. This means that in a webpack config file the loader must be last in the list. For example:

//webpack.config.js

const { resolve } = require('path');

// Correct

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.config\.js$/,
      use: [{
        loader: 'babel-loader',
      }, {
        loader: 'file-replace-loader',
        options: {
          condition: 'if-replacement-exists',
          replacement: resolve('./config.local.js'),
          async: true,
        }
      }]
    }]
  },
}

The example above is correct. file-replace-loader will be executed before other loaders. Let's see incorrect usage:

//webpack.config.js

const { resolve } = require('path');

// Error, because file-replace-loader will be executed after other loaders

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.config\.js$/,
      use: [{
        loader: 'file-replace-loader',
        options: {
          condition: 'if-replacement-exists',
          replacement: resolve('./config.local.js'),
          async: true,
        }
      }, {
        loader: 'babel-loader',
      }]
    }]
  },
}

In the incorrect example above, file-replace-loader is first in the rule list. This case throws an error because file-replace-loader should be last in the list.

Loader options

| Option | Type | Required | Default | Possible values | ------------ | ------------- | ------------- | ------------- | ------------- | conditionCondition to replace | string|boolean | no | 'if-replacement-exists' | true,false,'always','never','if-replacement-exists','if-source-is-empty' | replacementReplacement file | string|function (resourcePath, options) | yes | — | Full path to file or function returning full path to file | asyncAsynchronous file reading | boolean | no | true | true,false | progressProgress output | boolean | no | IS_DEBUG_MODE == true or IS_PROGRESS_MODE == true | true,false

Contributing

See the contributing guideline.

License

MIT LICENSE