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

What is the workflow to distribute a library ? #4545

Closed
aboeglin opened this issue Aug 30, 2015 · 4 comments
Closed

What is the workflow to distribute a library ? #4545

aboeglin opened this issue Aug 30, 2015 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@aboeglin
Copy link

Hi everyone,

I spent two days trying to figure out this module-internal-external-namespace-import-export thing, and I have to say, it's counter intuitive, and not very easy to use.

So, let's pretend that we have a little module that should be consumed by different projects. The module is composed of two classes A and B in the two files A.ts and B.ts. We want to bundle it in a file called library.js along with a type definitions in library.d.ts. I tried two main things so far :

  • internal module library, so that my files would look like this :
//A.ts
module library {
  class A {
  }
}

B.ts
module library {
  class B {
  }
}

Then I would use the --out option, which should be called --outFile but that my compiler as of version 1.5.3 doesn't know of. I end up with a .js file, which doesn't contain a module.exports = library. Which makes it fail to load in node. And the library.d.ts generated doesn't contain export = library, which leads to the compile error TS2306 library.d.ts is not a module. Of course, I played around, tried to create a file library.ts that would import or export things trying to compile it and hope it would generate what was needed.

I also tried to play with external modules, but this can't be the way to go as it seems impossible to generate a single file from it.

So, is there anywhere, a guide or manual that clearly explains how to bundle code ? A sort of step by step process. Looking at references online it seems a lot of people are after that, and a lot of people struggle with it. It can't be that hard can it ? People get confused with internal modules, external modules, namespaces, are internal modules actually gone ?

So what is "the way" of packaging a library that can be consumed by a browser and node ?

@kitsonk
Copy link
Contributor

kitsonk commented Aug 31, 2015

In a lot of cases this depends on your target environment and there are a lot of considerations outside of just compiling to TypeScript. There are several open issues about this as there is not clear and definitive approach. I think the TypeScript team recognise that it has its limits current and there is conversation going on here about proposing to simplify this: #4433 - Proposal: Bundling TS module type definitions (which links to a lot of the other tickets/solutions).

@mhegazy
Copy link
Contributor

mhegazy commented Aug 31, 2015

use namespace (aka internal modules) if you are not using modules/module loaders.
if you are using a module loader (which seems to be the case here), then you can use external modules. bundling external modules into a single output file is not a feature that is supported in TypeScript today. as @kitsonk mentioned, #4433 is tracking adding this feature. for now, you will need to emit each module to its corresponding output file, in node this is fine, i do not think there is an issue with distributing a package with multiple modules, for AMD you will need to use a bundler, like require on your output.

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Aug 31, 2015
@aboeglin
Copy link
Author

aboeglin commented Sep 1, 2015

And in the case of internal module, why do I get library.d.ts is not a module ? The file is full of declare module library {}. Just adding export = library at the end of the file fixes it, but how can I automate it ? What's the correct way of having a usable d.ts out of the box ?

So basically I should drop the module library{} statements and generate one javascript file with its associated d.ts file ? Then the consumer would need to do something like : import {A} from 'library/dist/A'; import {B} from 'library/dist/B'; right ? So it's not the same module anymore. How do people working on big projects with TS do to organize shared libraries ? It seems almost easier for me to distribute TS files at the moment.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 17, 2015

you can either distribute your library as an external module, i.e. your users need a loader to consume it, e.g. require, commonjs, system... or as a standalone script file.

i think both are fairly common practices in the js world. TypeScript compiler is distributed as a file, (e.g. include typescriptservices.js into your html page to get compiler support), and we do use namespaces all over the place.
other code bases, e.g. angular2 is fully written as modules, and you need to use a module loader, e.g. systemjs to get to it.
Personally, i would say modules is the way to go, they have become the standard with ES6, they have a much cleaner scoping rules, and force encapsulation. all nice features for building modular frameworks.

@mhegazy mhegazy closed this as completed Sep 17, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants