node.jses6-modulesmodule-alias

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


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?


Solution

  • 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.