Repository navigation
Proposal: Async imports #3100
Description
Activity
RequireJS does not bundle everything into a single file. By its nature, it was built to support asynchronous module loading (a.k.a. AMD). It is R.js (an affiliated project) that allows you to combine many modules into a single file. In AMD, the concept of layers, which would be strategically be built to make sure that only the dependencies are loaded are loaded. Asynchronous module loading makes lots of logic client side, but has a potentially limited value server side. TypeScript targets both.
I don't really think this is the domain of TypeScript. TypeScript supports AMD outputting and CommonJS modules and soon what is referred to as UMD and will support ES6 modules. That is the "job" of TypeScript in my opinion and further build optimisation is left to much more focused tooling like UglifyJS, Closure, R.js, etc. etc. So, I don't think it is appropriate for TypeScript, personally.
Loading is not equal to bundling. AFAIK when you run its bundle tool requirejs bundles everything into one file[1]? Though you can specify multiple bundles, though they don't create the sub dependency graph described above.
You could create the loader described above with AMD and CommonJS(in fact I think webpack does it). You would lose all the tooling support in TS(unless you want to write declaration files). So preferably it should be a built-in feature of TS.
AFAIK when you run its bundle tool requirejs bundles everything into one file[1]?
Actually, it can build multiple layers and then loads it asynchronously.
You could create the loader described above with AMD and CommonJS
So are you suggesting that TypeScript get into the module loading business as well? The packaging came in via #2605. In ES6, module loading is going to be handle natively by the host and allows for async loading. I am not sure why TypeScript would want to solve that problem at a semantic language level.
Part of your original problem:
What you might want is to have it bundled into multiple files, i.e. sub graphs of the main dependency graph.
Is exactly what RequireJS does today into building into layers, with dependency management. Other tools do the same thing. Again, better to let them solve that part of the issue, in my opinion, versus building it in semantically into TypeScript. Often times those layers can be very environment specific and I wouldn't want some upstream coder deciding that I needed to load an individual module asnyc. I want to do that whole thing as part of my build chain tooling. I might very well output a set of layers for IE9 and a different set for Chrome, because of what is support/performance/etc. of my code.
Is exactly what RequireJS does today into building into layers, with dependency management.
The build layers in RJS are not the same as the sub dependency graph I mentioned. Even though they represent a "sub dependency graph". You could for instance fetch an unused module in the up-level layers before you fetch one at the bottom. With the proposed solution no over fetching will occur.
If you want to create a sub dependency graph bundle you would need
require.ensurein CJS andrequire()in AMD. And TS doesn't compile into these with their import statements today. However, you could call those functions directly. But then you would lose the tooling support(unless you want to do some tiresome work of defining declaration files and rewire your build for every async import call).This is outside the scope of TypeScript at the current time.
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptOut of ScopeThis idea sits outside of the TypeScript language design constraintsThis idea sits outside of the TypeScript language design constraints
on May 28, 2015 ++
- locked and limited conversation to collaborators
on Jun 19, 2018
Most module bundlers bundles everything into one file e.g.
browserify,requirejsetc. But if you are developing a very large scale application you might not find it suitable to have everything bundled into a single file. What you might want is to have it bundled into multiple files, i.e. sub graphs of the main dependency graph. So if you visit a page, you only want to download the contents of that page instead of contents of others. This is a very good use case for SPA:s, because in today's day and age they need to be bundled into a single file, because they need to handle navigations and actions through all pages.But in order for it to work we need
async imports. To just give you an overview of what impact this feature could have — let's have a look at a general defined router for an SPA:Now, the above
async importstatement could tell a module loader to bundle its' sub-dependency graph. So all files thatUserPageModelandUserPageViewrequires could be bundled into a single file. Now, If you want to navigate to a different page you don't want to download the already downloaded modules. So a smart module bundler will bundles different subtracted modules of a bundle. So if a user navigates all pages in an application he would have download the whole dependency graph without over fetching something.This proposal was inspired by how Facebook does its' closed source module handling. I know that they do something similar. And it also very similar to webpack's code splitting. It would be good if TypeScript support this with all the tooling support.