Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot redeclare block-scoped variable 'ngDevMode'

My app in on Angular 5. Here is how the package.json looks like

{
  "name": "myapp",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",
    "@types/file-saver": "0.0.1",
    "angular-2-dropdown-multiselect": "^1.6.0",
    "angular2-csv": "^0.2.5",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "file-saver": "^1.3.3",
    "ngx-bootstrap": "^1.9.3",
    "ngx-clipboard": "^8.1.0",
    "ngx-loading": "^1.0.14",
    "ngx-pagination": "^3.0.0",
    "ngx-toastr": "^6.4.0",
    "rxjs": "^5.5.6",
    "zone.js": "^0.8.19"
  },
  "devDependencies": {
    "@angular/cli": "~1.7.0",
    "@angular/compiler-cli": "^5.2.0",
    "@angular/language-service": "^5.2.0",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": "~2.5.3"
  }
}

Everything is fine so far. Now I need to use a datepicker in my app. So I installed angular-io-datepicker

npm install angular-io-datepicker --save

Now, when I do a ng serve (after including the OverlayModule and DatePickerModule in app.module.ts ), it gives me the below error

ERROR in node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
node_modules/angular-io-overlay/node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.

Any suggestions on what could be wrong and how to fix it? I was earlier using this module successfully with Angular 4. Then I upgraded to Angular 5 and it broke. Now even if I rollback to angular 4, this module still gives me the same problem.

like image 982
kayasa Avatar asked Feb 22 '18 11:02

kayasa


6 Answers

I ran into the same error, although I think it was caused by a reference to a Typescript file located in a different project. I was able to resolve the problem by following the advice here: github issues 24165. Specifically, I added the following to the compilerOptions in the tsconfig.json file in the root of my project:

"paths": {
  "@angular/*": ["node_modules/@angular/*"]
}

Note: it may be necessary to use ../node_modules if your base path is not empty.

like image 75
Andy King Avatar answered Nov 20 '22 17:11

Andy King


For angular 6 in tsConfig

if the baseUrl is src then setting the path as follows works.

"paths": {
            "@angular/*": [
                "../node_modules/@angular/*"
            ]`enter code here`
        },

if the baseUrl is empty then setting the path without root worked for me

"paths": {
            "@angular/*": [
                "node_modules/@angular/*"
            ]
        },
like image 20
user1288411 Avatar answered Nov 20 '22 19:11

user1288411


TL:DR (See bottom for workaround)

Likely Cause

Before TypeScript, NPM packages could use all the global variables they wanted since NPM manages each package's scope to prevent conflicts. Now, with TypeScript/Webpack, imports are grouped together and the potential for conflicts arises.

Basically, TypeScript/Webpack is letting you know that the same declaration is being made within the same scope more than once, which could be a problem. However, what TypeScript appears to not realize is that NPM is managing the scope, which allows us to make multiple declarations of the same object, in different packages/scopes and even using different versions of the same package in dependents.

Correct Solution

The correct solution is for the imported packages to not declare globals or move each dependency to "peerDependencies". The latter of which isn't very feasible since it would require the consuming applications to know which dependencies each dependency needs... a management nightmare and the whole problem NPM addresses to begin with.

Workaround

Since we don't always have control over third-party packages and how they declare/export objects, you can simply add the following property to the tsconfig.json file:

{
  "compilerOptions": {
    ...
    "skipLibCheck": true,
    ...
  }
}

This tells TypeScript to ignore the duplicate declarations.

like image 44
A-Diddy Avatar answered Nov 20 '22 17:11

A-Diddy


i can see correct answer is already given ,But i think better explanation is needed whats happening with the answer.

in tsconfig.json

 "paths": {

 "@angular/*": ["node_modules/@angular/*"]
}

this tells the compiler to choose "node_modules/@angular", the angular version of main application's for all the occurrences including libraries

like image 44
Heshan Avatar answered Nov 20 '22 18:11

Heshan


The library angular-io-datepicker is still using angular ^4.0.0. This version mismatch with the angular version you're project is using causes the error. The library should have defined peerDependencies instead of directly depending on angular. This would have caused your npm to throw peerDependency mismatch warnings.

The angular team apparently moved a variable within files and the version mismatch now causes the ngDevMode variable to be declared multiple times.

So you could either continue using angular v4 or use another datepicker library.

like image 4
Capricorn Avatar answered Nov 20 '22 19:11

Capricorn


This happened for me too. Here is what I did to solve it:

  • I had a private package which was built using @angular/core version 7.0.4
  • I installed it into my project which was using @angular/core version 7.1.0

In this scenario we have two @angular/core with different versions!

I just updated my private package to use @angular/core version 7.1.0, and the problem resolved!

Adding:

"paths": {
"@angular/": ["node_modules/@angular/"]
}

does not needed in my scenario.

Full discussion here

like image 2
Vahid Farahmandian Avatar answered Nov 20 '22 17:11

Vahid Farahmandian