angular / angular-cli

CLI tool for Angular
https://cli.angular.io
MIT License
26.73k stars 11.98k forks source link

angular-cli doesn't work when node_modules is located in a parent directory #3864

Closed euangoddard closed 7 years ago

euangoddard commented 7 years ago

Please provide us with the following information:

OS?

Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?) Alpine linux (inside Docker container)

Versions.

Please run ng --version. If there's nothing outputted, please run in a Terminal: node --version and paste the result here: 1.0.0-beta.24

but running ng --version gives:

Cannot find module '/opt/app/ngapp/node_modules/@angular/common/package.json'
Error: Cannot find module '/opt/app/ngapp/node_modules/@angular/common/package.json'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Class.getVersion (/opt/app/node_modules/angular-cli/commands/version.js:67:25)
    at /opt/app/node_modules/angular-cli/commands/version.js:63:67
    at Array.forEach (native)
    at Class.getDependencyVersions (/opt/app/node_modules/angular-cli/commands/version.js:63:14)
    at /opt/app/node_modules/angular-cli/commands/version.js:41:58
    at Array.forEach (native)
    at Class.run (/opt/app/node_modules/angular-cli/commands/version.js:40:19)
    at Class.<anonymous> (/opt/app/node_modules/angular-cli/ember-cli/lib/models/command.js:152:17)
    at process._tickCallback (internal/process/next_tick.js:103:7)

Repro steps.

Was this an app that wasn't created using the CLI? What change did you do on your code? etc.

  1. ng new ngapp
  2. cd ngapp
  3. mv node_modules ..
  4. ng build

The log given by the failure.

Normally this include a stack trace and some more information.

You seem to not be dependending on "@angular/core". This is an error.

Mention any other details that might be useful.

I want to use angular CLI inside a docker container using docker-compose. I cannot have the node_modules folder inside the source code and a common pattern to solve this issue is to move the node_modules folder to the parent directory. Node will correctly recognise dependencies, but for some reason angular CLI is failing to find the @angular/core package.

If I run node and then do require('@angular/core') the package is correctly loaded.

batcoder1 commented 7 years ago

You have to put the node_module directory in the angular directory. ( then config angular-cli.json:

`{ "project": { "version": "1.0.0-beta.24", "name": "prueba" }, "apps": [ { "root": "src", "outDir": "dist", "assets": [ "assets", "favicon.ico" ], "index": "index.html", "main": "main.ts", "test": "test.ts", "tsconfig": "tsconfig.json", "prefix": "app", "mobile": false, "styles": [

    "../node_modules/font-awesome/css/font-awesome.css",
    "../node_modules/primeng/resources/themes/cupertino/theme.css",
    "../node_modules/primeng/resources/primeng.min.css"
  ],
  "scripts": [],
  "environments": {
    "source": "environments/environment.ts",
    "dev": "environments/environment.ts",
    "prod": "environments/environment.prod.ts"
  }
}

], "addons": [ "node_modules/font-awesome/fonts/*.+(otf|eot|svg|ttf|woff|woff2)" ], "packages": [], "e2e": { "protractor": { "config": "config/protractor.conf.js" } }, "test": { "karma": { "config": "config/karma.conf.js" } }, "defaults": { "styleExt": "css", "prefixInterfaces": false, "inline": { "style": false, "template": false }, "spec": { "class": false, "component": true, "directive": true, "module": false, "pipe": true, "service": true } } }` here my project structure captura

i hope this help you.

euangoddard commented 7 years ago

@wooltar, I appreciate your extensive response, but as I said in the my post I cannot put the node_modules in the source directory as Docker compose will sync that with my host system. Other than the permissions issues that Docker will copy the node_modules with into the host, it means that I can't run, e.g. Jamine in the host as any binaries will be compiled for the version of Alpine in the container and not Ubuntu which I use for development.

eight-molecules commented 7 years ago

You could try exporting your node instance's node_modules PATH variable as ../node_modules. The command for this will vary depending on your host operating system.

euangoddard commented 7 years ago

@gelliott181 node can find the node_modules itself, it;s something in angular-cli that explicitly tries to look in node_modules relative to the current directory (i.e. not using node's mechanism)

filipesilva commented 7 years ago

This is the source of that message: https://github.com/angular/angular-cli/blob/master/packages/angular-cli/upgrade/version.ts#L100

Maybe it could be done in a better way that supports your usecase.

wcainboundary commented 7 years ago

I have a slightly different use case for this same feature, not specific to Docker, and I encounter the same error for the same reason. I have an Angular 2 app living inside an outer npm-based app (the outer app having the package.json). I would like to be able to use the outer node_modules for both apps, without copying anything. Running ng build from the Angular 2 app directory yields the same error:

You seem to not be dependending on "@angular/core". This is an error.

In my case I can work around this with a symlink, but that adds complexity and introduces portability concerns.

kylecordes commented 7 years ago

I've hit this same problem, the "You seem to not be depending".

This issue might be more than a "nice to have" - the current behavior breaks the Node module resolution rules:

https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders

If the module identifier passed to require() is not a core module, and does not begin with '/', '../', or './', then Node.js starts at the parent directory of the current module, and adds /node_modules, and attempts to load the module from that location. Node will not append node_modules to a path already ending in node_modules.

If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached.

I think it can be worked around with some bash hackery to add symlinks - but that's ugly, and the current behavior violates the Node module resolution "spec".

filipesilva commented 7 years ago

Fixed by https://github.com/angular/angular-cli/pull/6276.

kylecordes commented 7 years ago

This problem appears to still be present in 1.0.4:

Kyles-MBP:agent kcordes$ ng build
You seem to not be depending on "@angular/core". This is an error.

Kyles-MBP:agent kcordes$ ng --version
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/
@angular/cli: 1.0.4
node: 7.10.0
os: darwin x64
@angular/common: error
@angular/compiler: error
@angular/core: error
@angular/forms: error
@angular/http: error
@angular/platform-browser: error
@angular/platform-browser-dynamic: error
@angular/router: error
@angular/cli: error
@angular/compiler-cli: error

Kyles-MBP:agent kcordes$ ls ../../node_modules/\@angular/core/
@angular        core.d.ts       public_api.d.ts     testing.d.ts
README.md       core.metadata.json  src         testing.metadata.json
bundles         package.json        testing

In the transcript above, I have these files up a couple of levels in node_modules; node module resolution should find them.

Should this issue be reopened? Should I enter a new one instead?

filipesilva commented 7 years ago

@kylecordes I think I see what's happening, we added full node resolution to webpack but still check direct dependencies when running ng commands. Thanks for testing this, I'll reopen.

kylecordes commented 7 years ago

@filipesilva How about a test case (or N of them) proving the whole thing works with empty local node_modules, and all the deps scattered among 1, 2, 3 levels "up"? Is there an "E2E" part of the test suite where such a thing could fit?

kylecordes commented 7 years ago

(Part of such a test could also replace some of the node_module/ZZZ directories with symlinks, to further tease out symlink issues and demonstrate the tooling tolerates symlinks.)

ajayprasad1982 commented 7 years ago

is there any way to access node_modules outside of angular project,I mean ,instead of accessing relative path can we access absolute path for my development activity.

about-code commented 7 years ago

Related to #7097

daviddiefenderfer commented 7 years ago

I'm working inside a Electron-Angular4.x project and to resolve this what I did was move the angular-cli.json in the same dir as node_modules and just changed the root path in the angular-cli.json

This fixed the errors I was getting related to everything angular-cli

screen shot 2017-08-31 at 6 31 53 pm
coffeymatt commented 7 years ago

@daviddiefenderfer Your solution worked for me (in a .net project), but I do get a side effect on ng build:

WARNING in ./ClientApp/node_modules/@angular/compiler/@angular/compiler.es5.js (Emitted value instead of an instance of Error) Cannot find source file 'compiler.es5.ts': Error: Can't resolve './compiler.es5.ts'

Don't suppose you've any idea's on working around that?

draconisNoctis commented 6 years ago

I have the same issue as @coffeymatt

node_modules in a parent directory and symlinked into the ng project.

The warning comes from a sourcemap file which refer to a missing ts file.

Didn't found a workaround yet.

kylecordes commented 6 years ago

@coffeymatt @draconisNoctis Since this issue is already closed with some code merged, it might be better to start a fresh new issue for the remaining problem, and include an example repository which shows a simple case where there is still a problem.

maxime1992 commented 6 years ago

Any news about that?

My use case is the following:

I'm building an app with backend and frontend both merged into a monorepo.

I do have the following structure:

| package.json
| node_modules/
| backend/
| frontend/
  | .angular-cli.json

I'd love to hear from you if you've managed to solved that in a clean way :) (avoiding symlinks or moving .angular-cli.json to top folder)

Thanks

LoveDuckie commented 6 years ago

Funnily enough, the problem that @maxime1992 is the same one that I have and I also have an identical project structure.

Both frontend and backend dependencies being defined in the same package.json file, but as angular-cli belongs in the frontend, it's placed in that sub-directory.

nickdnk commented 6 years ago

Same problem as @maxime1992 - any solution yet?

maxime1992 commented 6 years ago

@nickdnk couldn't find anything yet on my side.

@filipesilva could you reopen? (should I open a new issue? It really seems to be on this one but wondering...)

ErazerBrecht commented 6 years ago

I'm having the same problem aswell. Monorepo with a NodeJS and 3 different Angular applications. One of the Angular applications is SSR. As a result I'd like to have one packages.json in the root.

nimaen commented 6 years ago

You can take a look at nrwl/nx. It should provide an example of what you all need. At Elium, we are running a stack of 2 frontend apps, 2 backend apps and 4 libraries at the moment in a monorepo. We're using Yarn workspaces so each app / lib can have its own package.json. The .angular-cli.json config file is located in the root, and it makes sense to us since it declares apps and libs.

ghost commented 6 years ago

In my case adding WORKDIR /usr/src line solved the problem. Here's my Dockerfile:

FROM node:10.5.0-alpine
WORKDIR /usr/src
COPY package*.json ./
RUN npm install
RUN npm audit fix
COPY . .
EXPOSE 4200
CMD ["npm", "start"]
BrunnerLivio commented 6 years ago

I'm using lerna and yarn workspaces in my project. I've used quite a hacky workaround, but it works. Do not recommend this way, but if you do not care;

packages/web/bin/install-and-build.sh


#!/bin/bash

PREVIOUS_PWD=$PWD
DIR="$( cd "$(dirname "$0")" ; pwd -P )"

cd "${DIR}/.."

npm i --ignore-scripts
npm run build

cd $PREVIOUS_PWD

packages/web/package.json

{
  "scripts": {
    ...
    "prepare": "./bin/install-and-build.sh"
  }
  ...
}

package.json


{
  "scripts": {
    ...
    // Executes prepare on each package
    "prepare": "lerna run prepare"
  }
  ...
}

when running yarn in the terminal, ./bin/install.sh gets executed.

-> Does probably not work on Windows, but should be easy to rewrite

CyberBotX commented 6 years ago

I recently updated @angular/cli in my project to 6.1.0 and now I am getting the error:

You seem to not be depending on "@angular/core" and/or "rxjs". This is an error.

My node_modules is not in the root of my CLI project, but one folder up and symlinked, so node_modules in the CLI project's root points at ../node_modules.

Prior to 6.1.0, this worked fine. But 6.1.0 now seems to check if the node_modules directory is inside the CLI project root and this fails on my setup.

Gillardo commented 6 years ago

I am getting the same error after upgrading my project to 6.1.0 as @CyberBotX

Any news on this please?

ryedin commented 6 years ago

Why would this not just use node's resolution? These checks seem quite artificial. Also... 6.1.0 breaks our setup (same symlinked/docker thing)

htowaileb commented 6 years ago

Getting the same error as well after upgrading to 6.1.0. You seem to not be depending on "@angular/core" and/or "rxjs". This is an error.

I got my frontend and backend folders, and node_modules is setting in a parent folder.

kristy-mj commented 6 years ago

+1 ^ Looks like this issue has regressed, please reopen

htowaileb commented 6 years ago

For the record, if you would like to continue using 6.1.0 rather than reverting back, as a temporary solution, just copy your package.json to your frontend and backend folders, you'll have 2 copies of node_module but that should keep it running fine until this is solved.

The issue is happening only because somehow it's not applying the node module resolution to search in the parent folder if the node_modules isn't found in the current folder, but if it finds the node_modules in the current folder, everything should be running fine.

ryedin commented 6 years ago

@NightwareSystems that won't work in our case (which is the docker-compose mounted volume problem where we use a symlink inside the image to point node_modules to a folder one level up in the image to prevent them from being shared with the host). I have no idea what features we're missing out on, but we've locked our version of this package to 6.0.8 until the issue is resolved.

I go back to my initial question, though, which is why is this not just using node's resolution all the way through? I'm sure there is some reason the devs decided they needed to do explicit checks when running ng commands but I cannot for the life me see what those reasons might be... hoping we can get an explanation on that point because it's a little confusing (node's resolution should suffice in all cases... if you don't have things installed they don't work, if you do... they do)

ryedin commented 6 years ago

@filipesilva ^^^ (at-mentioning you just in case the closed status of this issue has prevented you from seeing the recent comments). This issue has regressed.

filipesilva commented 6 years ago

@ryedin can you open a new issue with a reproduction that we can follow to see this problem please?

ryedin commented 6 years ago

@filipesilva Yeah I think I can do that, although will not be able to right away (deadlines and such). Basically though, if you have your node_modules folder sitting in a parent dir and symlinked in, this fails. Hopefully will be able to make a clear repro setup for you later tonight/tomorrow.

clydin commented 6 years ago

These two PRs should help to mitigate the issue: #11691 (already merged) & #11725

ryedin commented 6 years ago

@filipesilva @clydin do you still need a repro setup for this issue? (asking because of @clydin 's response above indicating potential incoming fixes)

johneast commented 5 years ago

I have a similar issue where I have backend code and an Ionic 4/Angular 6 app in a mono repo with some shared code outside of the angular project

| backend
| shared
| apps/
    | my app/
        | node_modules
        | src
            | tsconfig.app.json

I have node_modules for my angular app in the app itself. If I install all my external deps and build everything is ok. But if I then change my tsconfig.app.json file so it adds a path reference to my shared code, then I get errors resolving 'fs' in aws-sdk (which is pulled in through aws-amplify which I am using) in node_modules.

My tsconfig.app.json looks like this

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "es2015",
    "types" : ["node"],
    "paths": {
      "@mylibs/*":[
        "../../shared/*"
      ],
      "*": [
        "../node_modules/*"
      ]
    }
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

If I remove the paths section and bring my local dependencies from my repo into the angular project then everything works fine. It's strange that adding the paths would have this knock on effect of causing the aws-sdk to cause a compilation error.

bb1 commented 5 years ago

Why isn't this reopen? This problem persists and as @kylecordes pointed out the current behavior violates the module resolution rules of node.js and breaks every sane MonoRepo structure (like plenty of people here are using). I would like to have my Backend and Frontend dependencies separated and only a small root-node_module.

Neither yarn workspaces nor relative PATH inside the package.json is working because suddenly rxjs Objects are not the same anymore (Observable is not assignable to Observable) and angular can't build anymore.

WalterSheng commented 5 years ago

@bb1 It's fixed by #12325. Just upgrade CLI to v7.0.

angular-automatic-lock-bot[bot] commented 5 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.