Skip to content

Suggest to inject a module loader helper #12656

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

Closed
yysun opened this issue Dec 4, 2016 · 8 comments
Closed

Suggest to inject a module loader helper #12656

yysun opened this issue Dec 4, 2016 · 8 comments
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

@yysun
Copy link

yysun commented Dec 4, 2016

Nowadays it has become a best practice to develop code using modules and to have all modules bundled into a single file. Currently we rely on webpack to bundle modules or systemjs/requirejs to load the single file bundled by TypeScript, but It is a burden to newcomers.

I hope code in ES2015 modules can be compiled, bundled and included in HTML right away w/o webpack, systemjs and etc. Can some helper functions be injected from tslib for loading modules, just like __await?

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Dec 5, 2016

Firstly, I will say that TypeScript does not to provide a runtime and that this is by design. __awaiter and co. are necessary for syntactic transformations.

However, irrespective of how it might clash with design goals, it is unfortunately not as simple as creating an __awaiter style helper. In fact, I would argue that the variety of function calls that TypeScript already emits when targeting various module formats are basically what I would consider module loader helpers.

However, you bring up a very real issue.
Adopting a module toolchain is indeed hard for newcomers. It also takes significant research, and is in general a complex process that poses challenges even for advanced users who have not previously used modules or have large existing code bases.

TypeScript does not provide a runtime, but if it were to provide a loader runtime, the language's other design goals would necessitate that it do so in a way which was compliant with how ES Modules are specified to behave.

That would mean something like SystemJS which continuously adapts to load modules in a manner conformant with the emerging WHATWG loader specification and the behavior of ES Modules as specified by TC39, while at the same time providing hooks for interop with legacy module formats, transpilers and other tools. In addition, SystemJS provides the excellent System.register format which is designed to map the semantics of ES Modules (Introduced in ES6) onto ES5 constructs via transpilation.
TypeScript can emit in this format, but there is no reason for it to replicate and internally provide, the runtime functionality of SystemJS. TypeScript is designed to integrate into existing and emerging toolchains while at the same time targeting emerging specifications, features, and standards.

At this point it would make sense to conclude that SystemJS is the way to go, and if you are targeting the browser I think it definitely is (Note that I am in a minority on this).

This brings us to two problems.

  1. NodeJS, which has not even decided if they will ever adopt ES Modules at all.
  2. General inertia from those with a preference for the (arguably) easier setup of tools like Webpack and Browserify even though they do not comply with ES Module behavior, and instead target CommonJS which is a different module system with quite different behavior. This is a real problem as so many tools have adopted the ES Module syntax, and ignored the semantics (a pet peeve of mine).

TypeScript aims to support all of these tools. I hope this adds some clarity.

@yysun
Copy link
Author

yysun commented Dec 5, 2016

I understand by design not to have a run time. But if you can help developers out there, ultimately it will help the adoption of TypeScript.

I suggest to have a quick and small module helper function without be constrained by ES standards to be practical. Please take a look the output of webpack which injects a 60 lines module bootstrap helper that subsequent module import and export can leverage. Perhaps TypeScript can do similar by defining a new module format --module=typescript. And put the helper function into tslib.

I trust TypeScript more than webpack and SystemJS and hope TypeScript provides a completed experience out of box.

@RyanCavanaugh RyanCavanaugh added Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript labels Dec 5, 2016
@RyanCavanaugh
Copy link
Member

Inventing another module system, no matter how small, is basically the last thing we want to do. The ecosystem is already too fragmented and everyone should be coalescing around ES6 modules - this will eventually be in browsers and the tooling around it is already quite robust. If we make another module system, we'll be stuck maintaining it and its compatibility forever. Not happening.

@yysun
Copy link
Author

yysun commented Dec 5, 2016

I want to clarify and try one more time. This is not a suggestion to invent another module system. In stead, it asks for a helper function to bootstrap ES modules, so that people can choose to use before browsers support modules.

It's about the user experience and usability. When I introducing TypeScript to developers, the impression today is that without webpack or systemJS, TypeScript is practically difficult to use and is incomplete by itself.

Hope this usability/impression issue sounds it would be worthwhile to invest by TypeScript team.

@RyanCavanaugh
Copy link
Member

What's the meaningful difference between that and just using RequireJS with --target amd ?

@yysun
Copy link
Author

yysun commented Dec 5, 2016

It could make a difference that you can claim "TypeScript compiles ES modules. Compiled code runs by itself" vs "TypeScript compiles ES modules, but compiled code needs a extra tool to run, such as RequireJS or SystemJS or something." The former one makes a complete story re: ES modules.

I love the way async/await in 2.1. It compiles and just works. The suggestion is to make ES module compiles and works. People can start to forget amd, umd and etc, because ES module will just work.

@mhegazy
Copy link
Contributor

mhegazy commented Dec 6, 2016

This issue has been discussed in #4434. When we looked into it, we have found multiple module systems/bundlers that are available in the community today. anything we do here will be yet another format.

One thing to note is that getting a simple loader and loading your modules is not the end of the problem it is just the beginning.

  • Modules usually have dependency on other non-user component, e.g. frameworks, helper libraries, etc.. and these have to be consumed as modules, so whatever we do will have to work with other module systems, amd, sysmtejs, es6, etc..
  • Users usually include other resources than JS, e.g. .css, .json, etc.. module loaders have support for loading non-js resources like requirejs plugins or systemjs plugins.
  • Users usualy want bundelling, and seldom wants to have modules written as thier own files to avoid server trips. then the next request is treeshaking, something like what rollup does today.

That is all fine, but the question is, is it worth creating yet another solution in the community, that will have its own quirks and semantics, and needs to interoperate with other tools.

The position we have taken with TypeScript, is that it is JavaScript. you should be able to use your JS tool-chain and libraries without a barrier. module loaders are no difference. we believe this way you get more value from the community rather than limiting you to the TS-supported-loader.

@yysun
Copy link
Author

yysun commented Dec 7, 2016

Thank you all for spending time explain and educate me.

I agree community tools provide a lot value and TS has made users 'should be able to use' community tools. It looks like users have many options, but the reality is that users 'must use community tools'. No option not to use community tools.

If TS could bundle ES modules into one file that works w/o dependencies as suggested, it could provide an option for simple use cases that don't require community tools. It only needs be done in a simple way and still leave advanced use cases to community tools. But users would have an extra option. I believe it would be good to TS too.

I got your reasons and respect your decisions. If you decide differently in the future, I will be more than happy to know.

Again, thank you all.

@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
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants