Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module alias is not working #154

Closed
abelchun39 opened this issue Nov 16, 2017 · 15 comments
Closed

Module alias is not working #154

abelchun39 opened this issue Nov 16, 2017 · 15 comments
Labels

Comments

@abelchun39
Copy link

I got "Cannot find module" with my @lib on import. Is there way to fix this?

Package.json

{...
"scripts": {
    "dev": "DB_HOST=localhost:27017 nodemon --trace-warnings -w src --exec \"node src/index.js\"",
    "start": "node src/index.js",
    "test": "eslint src"
  },
  "@std/esm": "cjs",
  "_moduleAliases": {
    "@root": "./src",
    "@api": "./src/api",
    "@lib": "./src/lib",
    "@middleware": "./src/middleware",
    "@models": "./src/models"
  }
...}

Index.js

require = require('@std/esm')(module)
module.exports = require('./app.mjs')

app.mjs

require('module-alias/register');
import http from 'http';
...
@jdalton
Copy link
Member

jdalton commented Nov 16, 2017

Hi @ChuntheQhai!

Can you create a simple repro repo for me to look at?

@abelchun39
Copy link
Author

@jdalton

Here's my repo for ESM with module alias:
https://github.com/ChuntheQhai/simple-esm-module-alias

@jdalton
Copy link
Member

jdalton commented Nov 16, 2017

Okay @ChuntheQhai!

Making this work is doable. I'm going to make it work with the option "@std/esm": "cjs". The reason it doesn't work at the moment is because of two things. The first is that module-alias assumes the module system is referencing Module._nodeModulePaths and Module._resolveFilename. The second is that it assumes Module is of require("module"). So for my part when "@std/esm":"cjs" I'll reference Module methods directly instead of cherry-picked imports of them. For the other I'll make a PR to module-alias so that it doesn't use require("module") directly and will get it from the module.constructor. This way it will work with our module system (and others).

@jdalton jdalton added the bug label Nov 16, 2017
@kenotron
Copy link

@ChuntheQhai / @jdalton - did this ever address the issue? I'm trying to make jest work with esm in my setup and it seems having module alias would solve another one of the problems (the last problem would be all those .css / .scss imports)...

@kenotron
Copy link

kenotron commented Mar 28, 2018

Okay, I updated to latest @std/esm and it WORKS. It seems that the latest esm versions has regressed this behavior...

@jdalton
Copy link
Member

jdalton commented Mar 28, 2018

did this ever address the issue

Yes.

It seems that the latest esm versions has regressed this behavior...

Yep. I was just going to post that. It looks like I regressed it when I tried to cache a bit more across loader instances. I'll fix that up tonight 😋

Update:

v3.0.11 is released 🎉

@kenotron
Copy link

Okay I see this is fixed for cjs 👍

However, I'm trying to update that simple repo from @ChuntheQhai with the latest esm, but it wouldn't work since the app.mjs is importing it as esm... wondering how I can get the same behavior as @std/esm's setting for package.json specifying "esm": "cjs" - I tried {mode: 'auto', cjs: true} but didn't work.

@jdalton
Copy link
Member

jdalton commented Mar 28, 2018

.mjs is locked down intentionally. Since it's the Node-way™, and they haven't fully written its support yet, we can't responsibly expand its functionality. You'll not be able to enable it with .mjs. For things to "just work" you'll want to stick with ESM in .js for now.

@kenotron
Copy link

I wanted to follow up on this - I've forked the simple repro and made it work:
https://github.com/kenotron/simple-esm-module-alias

@marxangels

This comment has been minimized.

@marxangels
Copy link

const esmRequire = require('esm')(module, { cjs: { topLevelReturn: true }})

esmRequire('module-alias/register')

require('module-alias').addAliases({
'@': __dirname
})

esmRequire('./logic/demo')

@andersondanilo
Copy link

For me that worked

Added "@std/esm": "cjs" to package.json
nodemon -r @std/esm -r module-alias/register ./app/server.mjs

@yukihirop
Copy link

If you want to use addAliases in module-alias, you can do this.
https://github.com/yukihirop/simple-esm-module-alias

@fancymo
Copy link

fancymo commented Jun 30, 2021

const esmRequire = require('esm')(module, { cjs: { topLevelReturn: true }})

esmRequire('module-alias/register')

require('module-alias').addAliases({
'@': __dirname
})

esmRequire('./logic/demo')

with run esmRequire('module-alias/register')
It's wrong :Cannot find module 'module-alias/register'

@TheDirigible
Copy link

This problem has been plaguing me for years because I want to write good quality code that is shared between node & browser.
I finally found a system that works:

  • Place 'nesm.js' in the root of your project
  • [optional] Place the 'nesm' shell script in your path, make it executable
  • Run scripts with: 'nesm file_to_run.js' or 'node path/to/nesm.js -- file_to_run.js'

'nesm.js'

/*
 * esm and module-alias do not play nicely together.
 * this precise arrangement is the only way I found to make it work.
 * you can run this from anywhere in your project hierarchy.
 * you can use args, and use in npm scripts.
 * encourage the node.js devs to make this work natively.  ux matters.
 * ---- CAVEATS
 * will not work with "type":"module"
 * ---- SETUP
 * place 'nesm.js' in the root of your project
 * [optional] place the 'nesm' shell script in your path, make it executable
 * ---- USAGE
 * > nesm file_to_run.js
 * to run without the nesm shell script:
 * > node path/to/nesm.js -- file_to_run.js
 * to run with nodemon:
 * > nodemon -- path/to/nesm.js -- file_to_run.js
*/
require = require('esm')(module);   // eslint-disable-line no-global-assign
require('module-alias/register');   // must come after esm for some reason

let runNext;
for(const arg of process.argv) {
    if(runNext) {
        let filename = arg;
        if(filename[0]!='.' && filename[0]!='/') filename = './'+filename;
        require(filename);
        break;
    }
    runNext = (arg=='--');
}

'nesm' shell script

#!/bin/bash
if [ -z $1 ]; then
    echo "Node esm runner.  Usage: nesm file_to_run.js"
    exit 1
fi
baseDir=$( pwd )
while [ ! -f "$baseDir/nesm.js" ]; do
    if [ ${#baseDir} -le 1 ]; then
        echo "nesm.js not found in folder ancestry"
        exit 1
    fi
    baseDir="$(dirname "$baseDir")"
done
file1=$(realpath $1);
node $baseDir/nesm.js -- $file1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

8 participants