An alternative to module-alias, but for esm
The purpose of this project is allowing developers that use esm modules to have a feature similar to the one provided by module alias.
module-alias provides the possibility to alias modules to a different path, taking the same example that is used in its documentation:
require('../../../../some/very/deep/module');
can become:
import module from '@deep/module';
To allow this, one should add some paths to the package.json
, like:
{
"aliases": {
"@deep": "src/some/very/deep"
}
}
The module stopped working after the introduction of the esm in NodeJS. In addition, at the moment in which this README was written, module-alias was last published three years ago.
Taken from this fantastic guide:
- Add
"type": "module"
to your package.json. - Replace
"main": "index.js"
with"exports": "./index.js"
in your package.json. - Update the
"engines"
field in package.json to Node.js 14:"node": ">=14.16"
. (Excluding Node.js 12 as it's no longer supported) - Remove
'use strict';
from all JavaScript files. - Replace all
require()
/module.export
withimport
/export
. - Use only full relative file paths for imports:
import x from '.';
→import x from './index.js';
. - If you have a TypeScript type definition (for example,
index.d.ts
), update it to use ESM imports/exports. - Optional but recommended, use the
node:
protocol for imports.
To use this module:
- Install the module by exeuting
$ npm install esm-module-alias
- Add the property
aliases
to thepackage.json
, the same way you would have done withmodule-alias
, for example:{ "aliases": { "@root" : ".", "@deep" : "src/some/very/deep/directory/or/file", "@my_module" : "lib/some-file.js", "something" : "src/foo" } }
- When you execute your script, add this module as a loader by adding
--loader esm-module-alias/loader
, for example:node --loader esm-module-alias/loader --no-warnings myscript.js # Note that --no-warnings is to disable a warning and is optional
You can also create a custom loader, because the library exports a function that given an object like the aliases
one that one would define in the package.json
, will return a function that will be used as a loader.
To do so:
- Create a custom file named as you want, for instance
my-loader.mjs
:import generateAliasesResolver from 'esm-module-alias'; const aliases = { "@root": ".", "@deep": "src/some/very/deep/directory/or/file", "@my_module": "lib/some-file.js", "something": "src/foo" }; export const resolve = generateAliasesResolver(aliases);
- When you execute your script, add that script as a loader by adding
--loader ./my-loader.mjs
, for example:node --loader=./my-loader.mjs --no-warnings myscript.js # Note that --no-warnings is to disable a warning and is optional
You can also have a custom matcher, a function that customize the behaviour of a path matching an alias.
To do so:
- Create a custom file named as you want, for instance
my-loader.mjs
:import generateAliasesResolver from 'esm-module-alias'; const aliases = { "@root": ".", "@deep": "src/some/very/deep/directory/or/file", "@my_module": "lib/some-file.js", "something": "src/foo" }; const matcher = (path, alias) => { return (path.indexOf(alias) === 0); // Your customized code }; export const resolve = generateAliasesResolver(aliases, { matcher }); // The custom matcher is passed to the options
- When you execute your script, add that script as a loader by adding
--loader ./my-loader.mjs
, for example:node --loader=./my-loader.mjs --no-warnings myscript.js # Note that --no-warnings is to disable a warning and is optional
Tests are run with Jest and work by executing npm test
with shelljs on a bunch of sample projects,
This package took inspiration from a comment of a Github issue