module-alias not working with esm if called from specific file

2.1k views Asked by At

I want to use module-alias with esm. I have already found an answer here. The problem is that I am using it manually, like this:

import * as path from 'path';
import * as moduleAlias from 'module-alias';
moduleAlias.addAlias('@', path.join(process.cwd(), 'dist', 'server'));

How can I fix it if it is not directly called by module-alias/register but from this code?

1

There are 1 answers

2
EuberDeveloper On BEST ANSWER

I solved the problem. To do it I just stop using module-alias which is at this point an obsolete npm package (+3 year of inactivity as of 19/07/2022) and useful only for the commonjs module resolution.

Citing the right answer from this github error, the solution is creating a file custom-loader.mjs and add it as a loader when calling node

import path from 'node:path';

export default function loadAliases(aliasesToAdd) {
  const getAliases = () => {

    const base = process.cwd();

    const absoluteAliases = Object.keys(aliasesToAdd).reduce((acc, key) =>
      aliasesToAdd[key][0] === '/'
        ? acc
        : { ...acc, [key]: path.join(base, aliasesToAdd[key]) },
      aliasesToAdd)

    return absoluteAliases;

  }

  const isAliasInSpecifier = (path, alias) => {
    return path.indexOf(alias) === 0
      && (path.length === alias.length || path[alias.length] === '/')
  }

  const aliases = getAliases();

  return (specifier, parentModuleURL, defaultResolve) => {

    const alias = Object.keys(aliases).find((key) => isAliasInSpecifier(specifier, key));

    const newSpecifier = alias === undefined
      ? specifier
      : path.join(aliases[alias], specifier.substr(alias.length));

    return defaultResolve(newSpecifier, parentModuleURL);
  }
}

export const resolve = loadAliases({
  "@": "./dist/source",
  "@src": "./dist/source",
  "@test": "./dist/test"
});

Then, when calling the script, add --loader=./custom-loader.mjs

node --no-warnings --loader=./custom-loader.mjs myscript.js

UPDATE: I created this npm module to automatically take care of this.