rechoir: Node Environment File Loader Preparer
rechoir is a utility designed to prepare the Node.js `require` environment for dynamically loading files with various non-native extensions. It operates by registering module loaders into `require.extensions`, leveraging `interpret`-like configuration objects to map file extensions to their respective transpiler or loader modules. Currently stable at version 0.8.0, releases are typically feature-driven and occur on an irregular cadence, often in conjunction with updates within the broader Gulp.js ecosystem where it serves as a dependency for tools like `liftoff`. A key differentiator is its ability to integrate with third-party transpilers (e.g., CoffeeScript, TypeScript, Babel) without bundling them, instead requiring developers to install these transpiler modules as local project dependencies. This design makes rechoir a flexible tool for command-line interfaces and build systems that need to process files written in languages other than standard JavaScript directly via Node's module resolution system.
Common errors
-
Error: Cannot find module 'coffee-script'
cause The required transpiler for the file extension (e.g., CoffeeScript) is not installed in the project.fixInstall the missing transpiler package: `npm install coffee-script` (or the equivalent for other languages like `ts-node`, `@babel/register`, `toml`). -
TypeError: rechoir.prepare is not a function
cause The `rechoir` module was incorrectly imported or required, or an older version was installed that does not expose the `prepare` function (e.g., pre-0.5.0).fixEnsure you are using `const rechoir = require('rechoir');` for CommonJS. If on an old version, update `rechoir` to >=0.5.0. -
Error: The module 'interpret' was not found
cause `interpret` is a direct dependency for rechoir's configuration, but it is not installed.fixInstall the `interpret` package: `npm install interpret`. -
Error: No module loader found for '.scss' files.
cause rechoir was asked to prepare an extension (e.g., `.scss`) for which no corresponding module loader is defined in the `interpret` configuration or installed.fixEnsure `interpret` has a mapping for the desired extension, and that the specified loader module (e.g., `node-sass`) is installed. You might need to extend `interpret.extensions` or use a custom configuration object.
Warnings
- breaking Version 0.8.0 dropped support for Node.js versions older than 10.13.0. Projects using older Node.js runtimes will need to remain on rechoir v0.7.1 or update their Node.js version.
- breaking Version 0.5.0 introduced a complete API rewrite. Code written for rechoir versions prior to 0.5.0 is incompatible and will need to be updated to the new `prepare` API.
- breaking Version 0.4.0 switched internal transpilation logic from `6to5` to `babel`, specifically targeting the `.babel.js` extension. Projects relying on `6to5` might experience issues or require configuration changes.
- deprecated The `load` method was removed in version 0.3.0. Attempting to call `rechoir.load()` will result in an error.
- gotcha rechoir does NOT bundle transpilers (e.g., `coffee-script`, `@babel/register`, `ts-node`, `toml`). You must install the necessary transpiler or loader packages locally in your project as dependencies for rechoir to successfully register and use them.
- gotcha Modifying `require.extensions` (which rechoir does) is a global and synchronous operation. While powerful, it can lead to conflicts if multiple libraries attempt to modify the same extension or if the order of registration matters for specific transpilers.
Install
-
npm install rechoir -
yarn add rechoir -
pnpm add rechoir
Imports
- rechoir
import rechoir from 'rechoir';
const rechoir = require('rechoir'); - prepare
import { prepare } from 'rechoir';const rechoir = require('rechoir'); rechoir.prepare(config, filepath); - interpret.extensions
const config = require('interpret').extensions;
Quickstart
const fs = require('fs');
const path = require('path');
const config = require('interpret').extensions;
const rechoir = require('rechoir');
// Create dummy files for demonstration
const fixtureDir = path.join(__dirname, 'fixtures');
fs.mkdirSync(fixtureDir, { recursive: true });
fs.writeFileSync(path.join(fixtureDir, 'test.coffee'), 'console.log("Hello from CoffeeScript!");');
fs.writeFileSync(path.join(fixtureDir, 'test.toml'), '[section]\nkey = "value"');
fs.writeFileSync(path.join(fixtureDir, 'test.js'), 'module.exports = { js: true };');
// NOTE: For .coffee and .toml, you would typically need to install
// `coffee-script` and `toml` packages in your project.
// For this example to run without errors, ensure they are installed or comment out those lines.
try {
rechoir.prepare(config, path.join(fixtureDir, 'test.coffee'));
console.log('CoffeeScript file loaded via prepare, attempting require...');
require(path.join(fixtureDir, 'test.coffee')); // This will execute the CoffeeScript
} catch (e) {
console.error(`Error preparing/requiring CoffeeScript: ${e.message}. Did you install 'coffee-script'?`);
}
try {
rechoir.prepare(config, path.join(fixtureDir, 'test.toml'));
console.log('TOML file loaded via prepare, attempting require...');
const tomlConfig = require(path.join(fixtureDir, 'test.toml'));
console.log('TOML content:', tomlConfig); // This will show the parsed TOML
} catch (e) {
console.error(`Error preparing/requiring TOML: ${e.message}. Did you install 'toml'?`);
}
// Standard JS files don't need prepare
const jsConfig = require(path.join(fixtureDir, 'test.js'));
console.log('JavaScript content:', jsConfig);
// Cleanup (optional)
// fs.unlinkSync(path.join(fixtureDir, 'test.coffee'));
// fs.unlinkSync(path.join(fixtureDir, 'test.toml'));
// fs.unlinkSync(path.join(fixtureDir, 'test.js'));
// fs.rmdirSync(fixtureDir);