angular 9 library publish error "Trying to publish a package that has been compiled by Ivy"
Asked Answered
U

11

48

I migrated my angular 8.x.x project to angular 9.x.x and when I try to publish my library, it fails with below error

npm ERR! @candiman/[email protected] prepublishOnly: node --eval "console.error('ERROR: Trying to publish a package that has been compiled by Ivy. This is not allowed.\nPlease delete and rebuild the package, without compiling with Ivy, before attempting to publish.\n')" && exit 1

is there anything changed in the angular 9

Uttermost answered 14/2, 2020 at 21:57 Comment(2)
Does this answer your question? How to compile a library without Ivy?Erinerina
this issue is related to angular 9 migration @R.Richards. the other one is related to normal and most of the people will fall into this issue as it will pop up during migration.Uttermost
U
74

UPDATE ANGULAR 12

using the --configuration production option while building the library fixed my issue

ng build --configuration production

Original answer:

using --prod option while building the library fixed my issue

ng build yourLibraryName --prod
Uttermost answered 14/2, 2020 at 22:1 Comment(7)
And what is your --prod configuration?Oao
actually --prod is a flag passed to angular cli configuration to say its a prod build so dont do a aot/ivy buildUttermost
Yes - but it still has to be set up as production configuration for your library in angular.json file - otherwise you will get an error saying there is no production configuration when you try to run in.Oao
@codeepic, hann, good point. I actuality did not tried that. thanks for adding that as a noteUttermost
adding --prod worked and no, you should not write production. The environment config and the flag --prod are 2 different thingsKurd
@AniruddhaDas also be sure to do ng build yourLibraryName --prod after ng test --watch=false. Ng test will also compile your library getting then the error: ERROR: Trying to publish a package that has been compiled by NGCC. This is not allowed.Defection
Wouldn't it be great if this was included in the output message!??!!!!Mayers
C
24

Fix for Angular 12+ missing component style issue

On Angular 12, while using:

ng build --configuration production

indeed solved the original issue for me, it also introduced a new one: the styles of my library component where completely missing.

I've solved this other problem by replacing:

  "angularCompilerOptions": {
    "enableIvy": false
  }

with:

  "angularCompilerOptions": {
    "compilationMode": "partial"
  }

in projects/my-library/tsconfig.lib.prod.json

Source: https://angular.io/guide/creating-libraries#building-libraries-with-ivy

Casteel answered 30/6, 2021 at 15:42 Comment(0)
O
23

According to official Angular docs https://angular.io/guide/ivy#opting-out-of-ivy-in-version-9

it is better to opt out from Ivy compiler to use the older View Engine when building and publishing your library by adding this line:

enableIvy: false

to angularCompilerOptions in tsconfig.json file at the root of your library as can be seen below;

enter image description here

I've tried it after updating my Angular library to Angular version 9 and this one small change worked like a charm.

Oao answered 30/4, 2020 at 15:51 Comment(0)
L
8

In my case none of the solutions above worked. I noticed however that in the package.json of my library in the dist folder there is an newly added script (probably added because of this):


  "scripts": {
    "prepublishOnly": "node --eval \"console.error('ERROR: Trying to publish a package that has been compiled by NGCC. This is not allowed.\\nPlease delete and rebuild the package, without compiling with NGCC, before attempting to publish.\\nNote that NGCC may have been run by importing this package into another project that is being built with Ivy enabled.\\n')\" && exit 1"
  }

SO here either remove/replace the prepublishOnly script or publish using npm publish --ignore-scripts

Laflam answered 15/10, 2020 at 23:35 Comment(1)
Is it because you're trying to publish a package that starts from 'ng-'?Hooper
A
6

While building my libraries with ng build --prod and enableIvy = false in tsconfig.lib.json I was getting the same "prepublishOnly" script added to my workspace package.json as Melchia had.

The reason why seems to be related to using a private repository via publishConfig/registry in each library's package.json, as stated in https://github.com/angular/angular/issues/37973#issuecomment-656136865

When building Angular libraries for publishing, use ng build --prod, enableIvy = false in library's tsconfig.json and, if working with a private repository, npm publish --ignore-scripts

Antigone answered 26/2, 2021 at 10:15 Comment(0)
R
3

In addition to adding the --prod flag, if you're running on a really old version, you'll also need the following update to angular.json:

    "myproject": {
      ...
      "architect": {
        "build": {
          ...
          "configurations": {
            "production": {
              "tsConfig": "projects/mypath/tsconfig.lib.prod.json"
            }
          }
        },

with the content of that file being:

{
  "extends": "./tsconfig.lib.json",
  "angularCompilerOptions": {
    "enableIvy": false
  }
}

You can check if you're on such an old version if you still have the following lines in angular.json:

            "production": {
              "project": "projects/tsmean/spinner/ng-package.prod.json"
            }
Resendez answered 20/4, 2021 at 10:36 Comment(0)
T
3

Solved this by simply adding the following to tsconfig.lib.prod.json

"angularCompilerOptions": {
    "compilationMode": "partial",
}
Theretofore answered 14/3, 2023 at 8:56 Comment(2)
Thanks!!, really not good not finding this in angular Doc, at least not so easyAlodee
I had to run production command with flag --configuration production that forced to pick .prod.json configsAnschauung
G
2

In your angular.json file, you have a build object in your library tree. Inside build, you have a configurations object, that contains a production object and probably a development object too.

Inside build object define a new property called defaultConfiguration, and set the value: production that match with the name of the production property inside configurations object.

Your angular.json file should look like this:

"architect": {
  build": {
    "builder": "@angular-devkit/build-ng-packagr:build",
    "options": {
      "tsConfig": "projects/ngx-custom-tooltip/tsconfig.lib.json",
      "project": "projects/ngx-custom-tooltip/ng-package.json"
    },
    "configurations": {
      "production": {
        "tsConfig": "projects/ngx-custom-tooltip/tsconfig.lib.prod.json"
      },
      "development": {
        "tsConfig": "projects/ngx-custom-tooltip/tsconfig.lib.json"
      }
    },
    "defaultConfiguration": "production"
  },
  ...
}

Your tsconfig.lib.prod.json should contains this object:

"angularCompilerOptions": {
  "enableIvy": false
}

Finally, yo can execute ng build your-library-name

Goodrum answered 22/8, 2021 at 3:15 Comment(0)
T
1

Adding

"compilationMode": "partial"

to

"angularCompilerOptions": {

}

Solved my problem

Toritorie answered 5/8, 2021 at 9:54 Comment(2)
This has already been mentioned in Francesco's anser.Unceremonious
Actually this is the exact solution, no long modification needed as discussed in answer you are referencingToritorie
H
0

As per the latest (Version 12+) guidelines by Angular is that don't use full compilation mode for publishing your library to npm.

The Solution is to set your configuration Accordingly in tsconfig.lib.json or tsconfig.lib.prod.json

If using an Angular version less than 12 you can go with ivy false.

"angularCompilerOptions": {
   "enableIvy": false
 }

From Angular version 12 Ivy will consider true by default. We can't control it directly as Angular will complain.

So the correct suggested option to publish your library is:

"angularCompilerOptions": {
"compilationMode": "partial",
}
Hanna answered 26/10, 2023 at 7:58 Comment(0)
B
-1

Angular team doesn't allow to publish library in full Ivy mode to NPM as it is highly probable that applications that will consume it, will be built using partial Ivy mode. This will cause compatibility problems.

So, to get out of this situation, you may use the following hack:

Assumption: You will ensure that your consumer application & library are built using full Ivy mode. And any application built using partial Ivy mode will not consume your library. Moreover, both application and library are built using exact same version of Angular.

Hack: Just before publishing your library, you can remove the script from dist/.../package.json, that prevents the library from publishing.

More information: This has been discussed at length with Angular team here. To summarize you may start reading the thread from here.

Basanite answered 15/2, 2022 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.