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

Secondary entry point not working consistently in typescript <2.6 #677

Closed
benjamincharity opened this issue Mar 8, 2018 · 12 comments
Closed

Comments

@benjamincharity
Copy link

Type of Issue

[x] Bug Report
[ ] Feature Request

Description

Desire: A single library with multiple entry points:

@terminus/my-lib
@terminus/my-lib/keycodes
@terminus/my-lib/testing
etc..
  1. I have cloned the ng-packaged repo as my starting point and changed a few names and added a secondary entry for keycodes.
  2. I published the library to NPM and installed into a fresh Angular CLI project
  3. When the demo app starts I see an error ERROR in src/app/app.component.ts(9,24): error TS2307: Cannot find module '@terminus/test/keycodes'.

How To Reproduce

My test library (cloned from ng-packaged): https://github.com/GetTerminus/test
A fresh CLI project with the library added: https://github.com/benjamincharity/test-demo

  1. Clone the test-demo project
  2. yarn install && ng serve
  3. See the compile error - notice the app doesn't load in the browser

Expected Behaviour

No errors should exist in the terminal during a build consuming the library.

I know this should be supported so I'm assuming I'm missing something simple? Any direction would be appreciated! 🙏

Version Information

ng-packagr:            2.2.0
@angular/compiler:     5.2.0
@angular/compiler-cli: 5.2.0
rollup:                0.55.3
tsickle:               0.27.1
typescript:            2.7.1
@terminus/test:        1.0.0-alpha.0

Please include all version numbers that might be relevant, e.g. third-party libraries

@benjamincharity
Copy link
Author

Update: Getting some odd behavior... The demo app compilation fails initially, but when any code is changed to cause a recompile, the app works (though the error still exists in the terminal)

Reproduction

  1. Clone the test-demo project
  2. yarn install && ng serve
  3. See the compile error - notice the app doesn't load in the browser
  4. Change & save any demo app file to trigger a recompile
  5. Notice the error still exists in the terminal but the app loads in the browser

Gif of recompile:

demo

Successful log of a keycode coming from the library:
screen shot 2018-03-08 at 9 02 23 am

@georgiee
Copy link
Contributor

georgiee commented Mar 9, 2018

I can 100% confirm this behaviour with the 2.2 ng-packagr
To help you @dherges I also provided a sample project with a small readme outlining what I have observed.

Look here:
https://github.com/georgiee/ng-packagr-entry-points

Boils down to this:

  1. Creating an entry point and compiling with ng-packagr works fine. At least successful and the package looks reasonable.

  2. Using a module from a separate entry point false once you remove the module in question from the main module.

Don't think that this is working as expected. Otherwise all of my peer dependencies spread over different modules will land in the main entry file despite carefully curating my different entry points . A dependency would land in the main entry event when not using the origin module.

I would also love to help you with a more minimal example with ngc if needed.

@dherges
Copy link
Contributor

dherges commented Mar 10, 2018

Hi, @benjamincharity @georgiee thanks for the good issue reports! I am going to look at it.

@dherges
Copy link
Contributor

dherges commented Mar 11, 2018

I checked your repros and looked at the generated dist folders. From manually looking at it, I neither see an error in the package.json nor in the *.js files. But I noticed a similar glitch some time ago.


In PR #685, the feature seems to be working, even with ng serve and reloads.

screen shot 2018-03-11 at 18 54 56


The error is reported in the app's build in ng CLI. Did you check whether there are issues in the CLI or webpack or one of the webpack plugins? I would need to start debugging by the module resolution in webpack and/or the relevant plugin.

@georgiee
Copy link
Contributor

Thanks a lot for your response.

I just compiled the samples and run the consumer part of your test suites. Nothing wrong in there indeed. I also looked into the examples of secondary and primary. The only difference I spot is that the entry point of @sample/secondary is pointing to the primary folder not to a public_api.ts file in the same directory as in our examples.

To be honest, I hurried here too quickly after tinkering with ng-packagr so much. So I will double check the issue trackers of Angular CLI and webpack too ✌️ But before doing so I will try to drop in my example into your sample/consumer environment.

Thanks a lot!

@georgiee
Copy link
Contributor

Hello,
first of all it seems that I can confirm that ng-packagr is working as expected and this is some problem of the remaining pipeline as already suspected by @dherges.

I did the following criss-cross checkings for confirmation.

  1. Rebuild my example in the integration/samples folder and build them
  2. Integrate my examples in the integration/consumers/ng-cli application by importing @sample/secondary-v2 and use the given directives.
  3. Prepare with yarn integration:consumers. This will spit out all build files without errors. That's a good sign ✅
  4. Just to be sure I started the dev server in the consumers ng-cli app with yarn start and changed the files to trigger a new build. Worked too ✅
  5. This was all pretty isolated from my example environment. So let's link my earlier created package (@magic/library)into the consumer and consume it. The module names are different, the directives are the same so I can just swap them in the import (https://github.com/georgiee/ng-packagr/blob/3adaa511c222a80228883676bb40ee76976e5db7/integration/consumers/ng-cli/src/app/secondary-v2/secondary-v2.module.ts#L4-L11). Done this. Rebuild. Works ✅
  6. Let's turn it around. Use the packages build in sample. First my @sample/secondary-v2 one.
    That immediately fails with the pattern outlined at the top 👊
  7. Now I linked the ng-packagr examples and got the same errors for that example in addition 👊
  8. I tried then to change the tsconfg. I spotted a es2017 instead of a es2016. No change.
  9. Finally I just dropped the package.json and rebuild all of my dependencies. Et voila it worked 👊 Reverting node_modules and it faile gain. So it's reproducible.

This is clearly a problem further down in the pipeline. When comparing the two package.json files I noticed some gaps in the versioning.

(mine -> ngpackagr)
"@angular/cli": "~1.7.1" -> "~1.7.0"
"ts-node": "~4.1.0" -> "~5.0.0",
"tslint": "~5.9.1", -> "~5.9.0",
"typescript": "~2.5.3" ->  "~2.6.1"

I tested all of them with a clean yarn install and I found the reason for that problem:

"typescript": "~2.5.3" ->  "~2.6.1"

👇
It is a Typescript problem. Use 2.6.1.
👆

Typescript 2.5.3 is still the default for Angular CLI apps even that Angular 5.2 is already supporting TS 2.6 (see https://github.com/angular/angular-cli/blob/1972bd954300be12efb6c917556fbc3a48d003f9/packages/%40angular/cli/upgrade/version.ts#L174)

Angular Release v6 is imminent but the CLI schematics are still pointing to 2.5.3 (https://github.com/angular/devkit/blob/891f4706c89967b9bbe14da57c02e49f35f13799/packages/schematics/angular/application/files/package.json)

Everything is fine on the ng-packagr side. We maintainers of an Angular library have now to deal with the problem that our users will run into that problem as their friendly Angular CLI is pointing to an outdated version of TS when creating an App. Looks like fun 😑

@dherges
Copy link
Contributor

dherges commented Mar 12, 2018

Summary: to use secondary entry points, you need to use typescript 2.6 (or later) in the app?

@georgiee
Copy link
Contributor

Yes👌

@dherges dherges closed this as completed Mar 12, 2018
@dherges dherges changed the title Secondary entry point doesn't seem to work consistently Secondary entry point not working consistently in typescript <2.6 Mar 12, 2018
@Liowag
Copy link

Liowag commented Mar 23, 2018

For me there is something that even with typescript >2.6 isn't working regarding dependency injection and extended services.

I have a FooModule and a BarModule in a structure like this: foo/bar. In my BarModule I have a SettingsService and use the APP_INITIALIZER inject token to load() my settings from a backend service before the app starts. Now in my app I have a MySettingsService which extends the SettingsService from my library to modify some settings and tell the SettingsService where the backend service is located etc and provide the SettingsService token with useExisting MySettingsService.

If i use both modules via one primary entry point, everything works fine, MySettingsService.load() is executed and everywhere in FooModule and BarModule MySettingsService is used instead of SettingsService. If i use secondary entry points however the SettingsService.load() function is executed and MySettingsService isn't used. Any ideas why this is working differently with secondary entry points?

@georgiee
Copy link
Contributor

You have given a pretty good mental image of what you are doing. But without a working minimal example it's pretty hard to answer if its a mistake on your side, a bug in Angular or something off with the library. I have at least no immediate idea what's wrong.

You should reproduce it in a project and provide it- also test some variants like this when preparing:

  • Inject somewhere else, the APP_INITIALIZER gets your code running at a very special place. Maybe something is interfering.
  • Tinker with the useExisting part. Select a local app class, another class from another submodule, another class from your main entry too inject and note the results.
  • Inject the Injector and debug its content. Maybe you get some insights from there.

@JoostK
Copy link
Member

JoostK commented May 3, 2018

I was facing this issue as well and figured that the problem is likely due to a missing index.d.ts file in the secondary entrypoint root. Adding an index.d.ts file next to public_api.d.ts in the generated distribution will in fact resolve this issue for TS < 2.5.

I noticed that Angular packages themselves do also include an index.ts in the sources, next to public_api.ts. Also, they put this note in there that pretty much explains this issue:

https://github.com/angular/angular/blob/6.0.x/packages/common/http/index.ts:

/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

// This file is not used to build this module. It is only used during editing
// by the TypeScript language service and during build for verification. `ngc`
// replaces this file with production index.ts when it rewrites private symbol
// names.
export * from './public_api';

To get the index.ts to actually end up in the package as ambient file (index.d.ts) you then need to change ng-packagr's entryFile to index.ts as otherwise it wouldn't become part of the Typescript program, as it is not referenced from anywhere.

For more information on why the double indirection seems to exist, see nrwl/nx#155 for a discussion.

@github-actions
Copy link

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

This action has been performed automatically by a bot.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

5 participants