jakejs / jake

JavaScript build tool, similar to Make or Rake. Built to work with Node.js.
http://jakejs.com
Apache License 2.0
1.96k stars 190 forks source link

Cannot find module 'jake'. WHHAATT!? #394

Closed yilmazdurmaz closed 3 years ago

yilmazdurmaz commented 3 years ago

pre-note for future use: If you have this issue now or in the future, it is possible you missed some points in documentation, or they haven't yet been edited yet after discussions in this issue. then please read discussions here for descriptions of causes and solutions.

when you can't even follow some documentation from one tool's own page, there is something big to fix. the only working thing if jake -h and jake -v to give version number :10.8.2

to reproduce:

install globally $ npm install -g jake

then make a jakefile.js, actually copy/paste the Sample Jakefile from docs.

then try jake, or jake -T, or jake -t, or npx jake. all fails just because of this module error.

jake aborted.
Error: Cannot find module 'jake'
Require stack:
- C:\WorkSpace\Vue\jakefile.js
- C:\Users\durmaz\AppData\Roaming\npm\node_modules\jake\lib\loader.js
- C:\Users\durmaz\AppData\Roaming\npm\node_modules\jake\lib\jake.js
- C:\Users\durmaz\AppData\Roaming\npm\node_modules\jake\bin\cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)      
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (C:\WorkSpace\Vue\jakefile.js:1:22)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)        
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
welearnednothing commented 3 years ago

@yilmazdurmaz I can imagine your frustration here. Likewise, it's frustrating for all of the contributors of Jake to see such a problem, given all of the thankless hard work @mde and many others have put into it - especially when a script that might have once worked reliably is now failing for and discouraging a new user. Let's try to keep the dialog here respectful to @mde, the other contributors, and the Jake community.

Short Answer

Install Jake locally in your project (which is suggested immediately after the global install)

npm install --save-dev jake

Hopefully that solves the problem! If not, let us know and someone can try to help debug.

More Detail

The gist of it is, standards of Node have shifted over time and at one point you would have had your global node_modules searched within your dependency chain when running a global install of Jake (or any lib). That's no longer the case as it can lead to unpredictable results within projects (the age old dictum that global variables are bad applies here). The Node docs dive into this a bit more.

Note that this will still work with the global install for folks that have their global node_modules in their NODE_PATH environment variable - so this won't universally fail for everyone. That said, it's no longer best practice to do so.

You can find a similar issue discussed here.

@mde perhaps it's time to remove the suggestion to install globally and just push everyone in the direction of a local install these days. That's likely more inline with what people are used to in the Node world these days (and for good reason).

mde commented 3 years ago

This is a Windows-only bug. Definitely worth fixing, but Windows CLI tools have always been a maintenance issue with Node-based CLI tools. I'll take a look at this sometime this weekend. And thanks for the request for civility, @welearnednothing. It's really appreciated.

welearnednothing commented 3 years ago

Yeah, of course @mde. I was able to reproduce this on macOS 10.15.7, actually. My NODE_PATH env var was empty and it failed exactly as described. Adding my global node_modules to NODE_PATH worked as expected. This machine has been around the block a few times, so I don't know what happens on a clean Node install - but I suspect it's not to set a NODE_PATH anymore.

mde commented 3 years ago

Ah, that is super helpful. We can easily add that to the docs for 'Nix installs, but I'm not sure what will be needed for Windows. I'll have to dig up a Win VM to test this on.

yilmazdurmaz commented 3 years ago

@welearnednothing that discussion on stackoverflow was started almost 10 years ago. it is amazing to have this kind of a problem even years after.

yilmazdurmaz commented 3 years ago

@mde If it helps I tried the following.

with my already globally installed version, I used npm install --save-dev jake in an empty folder and just created a single jakefile with sample code in it (no project needed).

invoking jake command directly now works fine, and uses newly created node_modules folder inside working directory.

I did not set a path to bin folder in this local module folder, and also renamed "bin" folder to be sure jake is not started from within this folder, so safe to say the globally installed jake is running.

and the result is apparent that even a global installation of jake looks for this local "save-dev" folder right now.

yilmazdurmaz commented 3 years ago

I have found this weirdness:

I uninstalled both global and local, and reinstalled only global.

if I remove let { task, desc } = require('jake'); from jakefile (again sample file), then jake will run without a problem.

so a question arises here: jake cli already requires jake library when called then do we really need to require jake inside jakefile again?

(require does still give the error if I use it in a script file or in node cli for globally installed jake)

mde commented 3 years ago

I am having to refresh my memory, because it's been a while, but basically Jake is of course a CLI tool, and originated with the assumption of either a global install, or install in a known location that has been added to the user's PATH. This is generally how CLI tools are used — transpilers, linters, test runners, etc. The assumption was that you would install Jake somewhere in your PATH, and run it like a binary, jake.

However, there are some advantages to versioning even these CLI tools, and the Node community has historically been militantly anti-global-install, and militantly anti-global-anything, so there is a strong preference for pedantically doing an in-file require of even things that could (theoretically at least) be obviously global, like parts of the Jake API such as task or desc, in a Jakefile.

At some point I did a bunch of rework to allow Jake to function either way. I would have to go back and look at the code, but IIRC there is a preference for a locally installed Jake, but it will fall back to a global one if it can.

So it make sense that the fallback-to-global works for me, even in the case of a require, because my global Jake is in my PATH, and the Node process can find it.

Seems like what we have here is a failure in docs. We should update the docs to prefer local install of Jake, and then explain the fallback to global, which exists mostly for backward compatibility, but also for the few people who don't feel the need to do a mindless require of this stuff in every Jakefile.

yilmazdurmaz commented 3 years ago

I was confused about this module path thing. now I begin to understand the possibilities here.

besides things you mentioned, it is possibly worth mentioning about module path somewhere in between lines.

you may include an explanation, for example, or redirect to a discussion like this one I have found similar/same: Nodejs cannot find installed module on Windows (this one being about "jade" is incidental :) )

as we now have a discussed issue at hand with useful suggested solutions in it, you can mark this issue as solved and close anytime you see fit.