You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To add my 2 cents, I agree I would like to see 1, but I know that can be a challenge if for example 2 different files contain the same class or variable name.
I am hoping, that like the CommonJS namespace merging you already do we would simply get a 'multiple declaration' exception.
But either 1 or 2 I would like to see this implemented someway because my application uses requirejs extensively to deliver SPA functionality with durandal.
I'd like to see 1) too since our current desired use case is to use one file per class/interface/enum and one folder per module.
While I think it shouldn't be too hard too implement inside the compiler, the tooling is harder, notably in VS: how do you determine which files compose a module?
Personally, what I would really like to see to solve this problem is a mix between internal and external module syntax at the language level. Something along the lines of:
// A.ts
external module "library" {
class A { }
}
// B.ts
external module "library" {
class B { }
}
Both files would be compiled into one module file library.js. Each file can only declare at most one external module, and cannot have any other top-level declarations if there's an external module declared.
Another benefit of this approach is that it would no longer be magic that a file becomes an external module (with its contents no longer in global scope) as soon as there's an import or export since there's the possibility of explicitly defining that a module is external. That's what most people I've seen working with TS and external modules are struggling with when introduced with the concept. (Still, the old way would still work, for compatibility reasons and implicit single-file external module).
If you compile this with tsc --out library.js library.ts --module commonjs --declaration I would expect there to be line at the end of library.js with module.exports = library which there isn't. Adding this line isn't a huge deal, but it would be nice if it were done automatically.
If you're working in a large org or team and want to develop reusable packages as part of a large system (i.e. any large enterprise app) then you'll hit this problem.
You'd be be using external modules as you'll be relying on an external loader (unlike internal modules that assume it's all loaded already). Each module will defer to the module loader to find the correct script not by an assumption it's already loaded (this just referring to it's module object) .
The separate modules need a single .d.ts so it can be consumed by dependencies at compile time. Currently having (potentially hundreds) of single .d.ts for an external module package is useless.
We've got our system running using dts-bundle which scrapes all the single files into a single .d.ts (same approach as outlined in #17), but there are other teams here stumped by the complexity required to get this running, there off building monolithic internal module applications that can't be split out into separate packages.
Everyone in this thread is voting for 1, so I imagine it's just me being slow to understand how it would work. With option 1 you're changing how things are actually defined if when using external modules aren't you?
If my definition for class A lives in foo/a.ts I would need to import foo/a to get access to the scope that A is defined in. If the d.ts module rewrites it to foo/A wouldn't it break the imports? Additionally, if I made the example a little more silly but still completely valid:
How would the compiler know where the base path was? When you import this project into other projects the module names should be from and inclusive of the project root correct? So in another project the modules would really need to be defined as:
declaremodule'project/foo/b'{classA{};}
I imagine this is going to boil down to the addition of a --include or --library option perhaps? I'm not sure what the solution is, but our biggest stumbling block right now is trying to use typescript modules in other code effectively without shipping the entire raw source. Internal modules work for a while, but if you ever want your project to be isomorphic (node & browser) or traceable using something like browserify external modules are a must.
@xealot Are you suggesting that the folder structure defines modules? I'd rather module definitions be more explicit, that's why I was suggesting having a main library.ts file that contains references to the things you want in your module. The nice thing about having a separate file is that you could potential have multiple version of the library.ts which have different features.
Well currently typescript is using folder structure to import modules, at least for AMD modules it does. @xealot and Julien Lebosquain (@MrJul) makes a good point that merging definitions like 1 would make it hard on tooling (intelisense, etc)
I agree with Julien Lebosquain (@MrJul) 's solution by adding a new 'external module' keyword would make the most sense to me and be nice on tooling.
Mohamed Hegazy (@mhegazy)
Thank your encouragement. I had know this tool and I had afraid bit of configuration - that it could be to complicated.
Thanks your encouragement I the ice has broken up :-) and
I have spend several weeks with webpack and also systemjs.
What I would like to achieve?
But first what I would describe what I need to achieve.
I would like to create my suite of component which would exists in java script file.
E.g.:
lib1.js, lib.d.ts
lib2.js, lib.d.ts
lib3.js, lib.d.ts
this library could be depend on angular, reactjs, kendo and others.
apps
and apps which could consume this libraries and could have own libraries.
app1.js
libapp1.js
libapp2.js
and dependencies: lib1.js with lib1.d.ts, angular etc....
app2.js ... silimar like app1
It would be like: software suite, framework or components.
One library could contain many external modules.
app it is just main js file
My adventure with webpack
I have tested webpack with grunt. I create GruntFile.js which could be use by each project.
This GruntFile.js use project.json which indicate how to process structure of project (solution line in Visual Studio)
Problems
a) I could join js files (after compilation of typescript) but I have problem with generated one
type script date type file d.ts for library
As I wrote I would like to have references between libraries - I need also d.ts
b) I have problem to dynamic loading js to achieve the same as in systemjs.
That mean to have one file in html.
c) And with references. because I had to use external - I don't wont bundle vendors and library to one file.
Summarization
It this moment the biggest problem for me is point "a".
Main requriment
I could compile whole libraries for each app but I need that my library work as plugin.
Thant means for existing application someone else could provide library as plugin
which extend functionality. This library would implement app interfaces to extend functionality.
New version of typescript compilator
I looked on roadmap of typescript compilator and I noticed interesting issues:
2.1 Support for project references
2.0 Improve lib.d.ts modularity
1.8 Concatenate module output with --outFile (only for amd and commonjs)
Conclusion
Maybe in this moment it is difficult to achieve this structure which I was described.
Maybe I am on wrong path because I have habit e.g form .NET or java and I would
like transfer "assembly" to java script world
But maybe no - typescript roadmap looks like small steps in this direction.
Maybe crazy idea for typescript compilator
What do you think to put to to output java script file declaration?
As metadata in comments. It would transparent for java script.
But js could be add as reference to typescript project - similar to assembly or jar file
which has own metadata.
Architecture for enterprise, long term solution
In new year I and my team I will have make some architect decision -
and I ma responsible of consequences.
I really appreciate you for each comments and criticism in this topic.
Typescript architecture for applications and libraries. Thant means how to organize compilation process to achieve these goals.
I think thant others have similar problems with typescript projects - how to organize it
when structure is more complicate, e.g.: #909 , #557
Thank you and sorry that I extended this issue of details
which could be out of scope
ES6 modules provide the ability to build modules from smaller ones using export * from "mod" and export { a as b } from "mod". This allows for having the multiple modules for implementation purposes, but then exposing a single "entry point" module that collates all of the smaller ones into a complete unit. This would be the recommended route for this scenario.
A follow up feature for the TS compiler is #4433, to enable publishing a single .d.ts file that has the "shape" of the "entry point" module, and thus completely hide the internal modules from consumers.
if you are using Node, then there is no need to bundle i would say. the issue with UMD is that it needs to work the same way on node and amd. since the way you can require an internal module is different from amd to node, we can not grantee that the transformation would work.
if you want to have a bundle that works in both amd and node, i would recommend looking at browserify or webpack.
Activity
basarat commentedon Jul 30, 2014
👍
vvakame commentedon Jul 30, 2014
👍
reverofevil commentedon Aug 12, 2014
I'm highly interested in this issue getting closed. I don't like an idea of concatenating
*.tsfiles in mysourcedirectory with a build script.What do you mean by "module boundaries"?
basarat commentedon Aug 13, 2014
Given:
a.ts:b.ts:What will the
.d.tswill be?This
1:or
2My vote :
1reverofevil commentedon Aug 13, 2014
Why should it create a module for each class at all, if we're explicitly making one module file?
My vote goes for the first option.
basarat commentedon Aug 21, 2014
Ryan Cavanaugh (@RyanCavanaugh) can you append the following as well
If you want I can create a separate issue for that.
charlessolar commentedon Sep 8, 2014
To add my 2 cents, I agree I would like to see 1, but I know that can be a challenge if for example 2 different files contain the same class or variable name.
I am hoping, that like the CommonJS namespace merging you already do we would simply get a 'multiple declaration' exception.
But either 1 or 2 I would like to see this implemented someway because my application uses requirejs extensively to deliver SPA functionality with durandal.
MrJul commentedon Oct 14, 2014
I'd like to see 1) too since our current desired use case is to use one file per class/interface/enum and one folder per module.
While I think it shouldn't be too hard too implement inside the compiler, the tooling is harder, notably in VS: how do you determine which files compose a module?
Personally, what I would really like to see to solve this problem is a mix between internal and external module syntax at the language level. Something along the lines of:
Both files would be compiled into one module file library.js. Each file can only declare at most one external module, and cannot have any other top-level declarations if there's an external module declared.
Another benefit of this approach is that it would no longer be magic that a file becomes an external module (with its contents no longer in global scope) as soon as there's an import or export since there's the possibility of explicitly defining that a module is external. That's what most people I've seen working with TS and external modules are struggling with when introduced with the concept. (Still, the old way would still work, for compatibility reasons and implicit single-file external module).
k4b7 commentedon Nov 29, 2014
My vote is for option 1 as well.
In terms of determining which files are part of a module, maybe we could use reference paths... something like this:
If you compile this with
tsc --out library.js library.ts --module commonjs --declarationI would expect there to be line at the end of library.js withmodule.exports = librarywhich there isn't. Adding this line isn't a huge deal, but it would be nice if it were done automatically.KeithWoods commentedon Dec 2, 2014
I say my vote would be for
1too.If you're working in a large org or team and want to develop reusable packages as part of a large system (i.e. any large enterprise app) then you'll hit this problem.
You'd be be using external modules as you'll be relying on an external loader (unlike internal modules that assume it's all loaded already). Each module will defer to the module loader to find the correct script not by an assumption it's already loaded (this just referring to it's module object) .
The separate modules need a single .d.ts so it can be consumed by dependencies at compile time. Currently having (potentially hundreds) of single .d.ts for an external module package is useless.
We've got our system running using dts-bundle which scrapes all the single files into a single .d.ts (same approach as outlined in #17), but there are other teams here stumped by the complexity required to get this running, there off building monolithic internal module applications that can't be split out into separate packages.
related issue #1236
tlong-dev commentedon Dec 2, 2014
Everyone in this thread is voting for
1, so I imagine it's just me being slow to understand how it would work. With option1you're changing how things are actually defined if when using external modules aren't you?If my definition for class
Alives infoo/a.tsI would need to importfoo/ato get access to the scope thatAis defined in. If thed.tsmodule rewrites it tofoo/Awouldn't it break the imports? Additionally, if I made the example a little more silly but still completely valid:a.ts:b.ts:Would the output be:
Additionally, if
2was produced:How would the compiler know where the base path was? When you import this project into other projects the module names should be from and inclusive of the project root correct? So in another project the modules would really need to be defined as:
I imagine this is going to boil down to the addition of a
--includeor--libraryoption perhaps? I'm not sure what the solution is, but our biggest stumbling block right now is trying to use typescript modules in other code effectively without shipping the entire raw source. Internal modules work for a while, but if you ever want your project to be isomorphic (node & browser) or traceable using something like browserify external modules are a must.k4b7 commentedon Dec 2, 2014
@xealot Are you suggesting that the folder structure defines modules? I'd rather module definitions be more explicit, that's why I was suggesting having a main
library.tsfile that contains references to the things you want in your module. The nice thing about having a separate file is that you could potential have multiple version of thelibrary.tswhich have different features.charlessolar commentedon Dec 2, 2014
Well currently typescript is using folder structure to import modules, at least for AMD modules it does. @xealot and Julien Lebosquain (@MrJul) makes a good point that merging definitions like 1 would make it hard on tooling (intelisense, etc)
I agree with Julien Lebosquain (@MrJul) 's solution by adding a new 'external module' keyword would make the most sense to me and be nice on tooling.
33 remaining items
mironx commentedon Dec 14, 2015
Mohamed Hegazy (@mhegazy)
Thank your encouragement. I had know this tool and I had afraid bit of configuration - that it could be to complicated.
Thanks your encouragement I the ice has broken up :-) and
I have spend several weeks with webpack and also systemjs.
What I would like to achieve?
But first what I would describe what I need to achieve.
I would like to create my suite of component which would exists in java script file.
E.g.:
this library could be depend on angular, reactjs, kendo and others.
apps
and apps which could consume this libraries and could have own libraries.
libapp1.js
libapp2.js
and dependencies: lib1.js with lib1.d.ts, angular etc....
It would be like: software suite, framework or components.
My adventure with webpack
I have tested webpack with grunt. I create GruntFile.js which could be use by each project.
This GruntFile.js use project.json which indicate how to process structure of project (solution line in Visual Studio)
Problems
type script date type file d.ts for library
As I wrote I would like to have references between libraries - I need also d.ts
That mean to have one file in html.
Summarization
It this moment the biggest problem for me is point "a".
Main requriment
I could compile whole libraries for each app but I need that my library work as plugin.
Thant means for existing application someone else could provide library as plugin
which extend functionality. This library would implement app interfaces to extend functionality.
New version of typescript compilator
I looked on roadmap of typescript compilator and I noticed interesting issues:
Conclusion
like transfer "assembly" to java script world
But maybe no - typescript roadmap looks like small steps in this direction.
Maybe crazy idea for typescript compilator
What do you think to put to to output java script file declaration?
As metadata in comments. It would transparent for java script.
But js could be add as reference to typescript project - similar to assembly or jar file
which has own metadata.
Architecture for enterprise, long term solution
In new year I and my team I will have make some architect decision -
and I ma responsible of consequences.
I really appreciate you for each comments and criticism in this topic.
Typescript architecture for applications and libraries. Thant means how to organize compilation process to achieve these goals.
I think thant others have similar problems with typescript projects - how to organize it
when structure is more complicate, e.g.: #909 , #557
Thank you and sorry that I extended this issue of details
which could be out of scope
mhegazy commentedon Jan 5, 2016
miron (@mironx), would not #5090 be sufficient for your needs?
mhegazy commentedon Feb 20, 2016
ES6 modules provide the ability to build modules from smaller ones using
export * from "mod"andexport { a as b } from "mod". This allows for having the multiple modules for implementation purposes, but then exposing a single "entry point" module that collates all of the smaller ones into a complete unit. This would be the recommended route for this scenario.A follow up feature for the TS compiler is #4433, to enable publishing a single .d.ts file that has the "shape" of the "entry point" module, and thus completely hide the internal modules from consumers.
Clark159 commentedon Apr 25, 2016
This is my solution uses TypeScript 1.8, The solution build multi-Class in a module.
BSick7 commentedon Jul 18, 2016
Mohamed Hegazy (@mhegazy) can you elaborate on this approach more of using modules for implementation, but smashing into 1 file with 1 entry point?
mhegazy commentedon Jul 19, 2016
there is no "smashing" happening. Each file is emitted as a module, but you have one entry point.
e.g.:
compiling with
--module amdand--outFile.:your users would import
indexand notaorb.BSick7 commentedon Jul 19, 2016
Doesn't this force me to use amd module loading?
Wouldn't UMD be an alternative that allows choice of module loading?
mhegazy commentedon Jul 19, 2016
if you are using Node, then there is no need to bundle i would say. the issue with UMD is that it needs to work the same way on node and amd. since the way you can require an internal module is different from amd to node, we can not grantee that the transformation would work.
if you want to have a bundle that works in both amd and node, i would recommend looking at browserify or webpack.
MortenHoustonLudvigsen commentedon Jul 20, 2016
I think rollup.js looks very promising as well. I haven't tried it yet though.
BSick7 commentedon Jul 20, 2016
Those work well for applications, but I am looking to build a library that works with amd and vanilla js.
Isn't the whole purpose of UMD to be agnostic between commonjs and amd?
I imagine that UMD would work like
module: nonewith the whole thing wrapped with boilerplate umd.