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

Imports from libraries outside @types and typeRoots are inlined #74

Closed
foxable opened this issue Mar 7, 2019 · 12 comments
Closed

Imports from libraries outside @types and typeRoots are inlined #74

foxable opened this issue Mar 7, 2019 · 12 comments
Assignees
Labels
Milestone

Comments

@foxable
Copy link

foxable commented Mar 7, 2019

Bug report

Imports from libraries outside of @types and typeRoots are always inlined, even when explicitly specified as external import.

Input code

foo.ts

import { Bar } from "bar";

export interface Foo extends Bar {}

externals/bar.d.ts

export interface Bar {}

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "bar": ["externals/bar"]
    }
  }
}

Expected output

import { Bar } from "bar";

export interface Foo extends Bar {}

Actual output

export interface Bar {}
export interface Foo extends Bar {
}

Additional context
CLI options:

./node_modules/.bin/dts-bundle-generator foo.ts --out-file bundle.d.ts --external-imports=bar
@timocov
Copy link
Owner

timocov commented Mar 7, 2019

Hi @foxable,

I'm not familiar with paths compiler option yet, but can you please tell me what the difference between using paths and using declare module "bar" {}?

If bar is an external module, should we "add it to the project" via paths or via declare module "bar"? Until now I prefer to use declare module for such cases as soon it is external module and should be declared via declare module, because paths is just shorthand for some folder.

Importing modules from declare module (and without typeRoots) does not work for now and I believe I'll fix at the weekend (related #50 (comment)), but case with paths is interesting 🙂

@foxable
Copy link
Author

foxable commented Mar 7, 2019

Hi @timocov,

you can use the paths compiler option to tell TS where to find the definition of modules that are not under @types or typeRoots. This can be used to divide large projects into independent modules. Imagine the following folder structure:

  • module1
    • index.ts
    • tsconfig.json
  • module2 (depends on module1)
    • index.ts
    • tsconfig.json

Without a paths configuration you would import module1 this way:

import * as module1 from "../module1/index";

With a paths configuration you can import module1 like an external module:

import * as module1 from "module1";

This decouples both modules and allows building them iteratively.

In my case, I reference a bundled module declaration instead of the TS entry point (which is generated using dts-bundle-generator). I want to keep the module declaration within the same folder as the source code. This is why copying all generated declarations into one folder and using typeRoots is not my preferred solution.

A local, empty declare module neither solves my problem, since it would not provide the desired type safety against the actual interface of the external module.

@timocov timocov added the Bug label Mar 8, 2019
@timocov
Copy link
Owner

timocov commented Mar 8, 2019

@foxable thank you for clarification!

I need to play with that, but anyway it looks like a bug and we need to fix it.

(but if you can provide an example of repro where I can debug the issue - it would be awesome)

@timocov timocov added this to the 3.0 milestone Mar 8, 2019
@foxable
Copy link
Author

foxable commented Mar 9, 2019

@timocov thank you for adding this bug to the next milestone.

I think a good approach could be to treat every import without a relative path as an external module w.r.t the libraries bundle options. Then you could check if the module either lies under node_modules, @types or typeRoots, or if it's mapped using paths.

Regarding a repro, do you need more examples or something ready to clone locally? You can use the example above as a minimal repro.

@timocov
Copy link
Owner

timocov commented Mar 9, 2019

something ready to clone locally?

Yeah, something like that - with folders, sources and tsconfigs (then I'll use it that example as test case).

@timocov
Copy link
Owner

timocov commented Mar 9, 2019

At first thought it looks like the issue has the same reason as #54, #59 (comment) and #62.

@foxable
Copy link
Author

foxable commented Mar 9, 2019

You can find the repro here: foxable/dts-bundle-generator-paths-bug

If you have any further questions or need some help feel free to ask.

@foxable
Copy link
Author

foxable commented Mar 14, 2019

I created PR #78 to fix the bug, which also includes a test case.

@timocov
Copy link
Owner

timocov commented Mar 23, 2019

@foxable Wow, that's amazing! Let's continue discussion there.

@foxable
Copy link
Author

foxable commented Apr 12, 2019

The PR was closed, because it became obsolete. The problem can be solved using a package.json with local dependencies defined as local paths. This way, they appear under node_modules to both TypeScript and dts-bundle-generator and can be used like any other library.

@foxable foxable closed this as completed Apr 12, 2019
@WaiSiuKei
Copy link

I am encountering the same problem in my monorepo, and disappointedly to find that Local Paths will limit users from publishing packages to NPM.

@foxable
Copy link
Author

foxable commented May 28, 2019

You are free to publish packages to NPM when using local paths. The only thing you need to ensure is that the package name and the name of the dependency pointing to the local path are identical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants