I have been working with C# for years and am mostly used to the single-file-per-type way of doing things. I am also fond of putting files into subfolders (corresponding to namespaces in C#).
But now I'm building a mobile web application using TypeScript, and find myself structuring my code in much the same way. However, this doesn't work too well:
The first point should be fixable by writing a small tool to strip out unnecessary module wrappers from the bundled output. And I'm thinking that I need to avoid using sub-modules and just stick everything into a single module, regardless of file system location.
Is there a better way to go about structuring TypeScript code than what I am currently doing/planning or would something like the above be recommend practice? What alternatives exist that are worth considering for someone who likes the single-responsibility principle?
PS: I hope this falls within the guidelines of SO, despite possibly being a bit subjective and open-ended.
Project references are a new feature in TypeScript 3.0 that allow you to structure your TypeScript programs into smaller pieces. By doing this, you can greatly improve build times, enforce logical separation between components, and organize your code in new and better ways.
Web browsers and NodeJS do not understand TypeScript code. It must first be converted to JavaScript through a process called compilation. The TypeScript compiler, which performs this compilation, is called tsc.
The short answer is definitely YES ! but you need some intermediate steps ! Please note that ,you can write plain old JavaScript in a TypeScript project without any problems since JavaScript is a subset of TypeScript ,you only need these steps if you are planning to use an external JavaScript library with TypeScript .
Here are my recommendations.
If you are using TypeScript on a web site, use modules to enclose a complete and stand-alone chunk of functionality and keep it in one file (unless it becomes unmanageable). Be conservative about how much access "module a" has to the inside bits of "module b".
Bundle and minify all of the generated JavaScript into a single file.
Declare your modules with:
module MyModule {
// ...
}
And make them available to other code files using a reference:
///<reference path="MyModule.ts" />
For a web app, you need to decide how script-heavy things are going to be. If things are going to be lightweight, treat it like a web site. If you are going to have a lot of scripts then AMD is your friend.
With AMD, you can use a folder structure to organise your code. Your files are your modules, so instead of using the module MyModule
declaration, you name your file MyModule.ts
. You can then organise your code using the folder and file structure and import the modules as you need them:
import myModule = module("./Messaging/Async/MyModule");
So think of the import
as your using
statement - except you need to give it a name.
At runtime, you'll need something to take care of loading the modules for you. RequireJS is a popular choice for this.
You just add one script tag to your page, which loads RequiresJS and tells it the name of your top-level module:
<script data-main="/Messaging/Async/MyModule" src="scripts/require.js"></script>
For a server app, you are almost certainly going to want to use CommonJS (which is supported by default by nodejs, for example).
It works largely like AMD (AMD is actually based on CommonJS) except the server will load the modules for you, so you don't need to include a module-loading script.
This is all guidance really. You could use web-site style bundling for really quite large programs if you wanted to - given that the script will be downloaded once and cached you may decide that the up-front cost is worth the simplicity.
So use the guidance until you think it doesn't fit your specific program and want to do things differently. The guidance is based on the principle of...
This is quite subjective, but for what it's worth we are using modules more or less as namespaces and therefore grouping together related classes in a single file, except in our viewmodel where we more or less stick to one file = one class, as we would for C#.
One reason for this is that in client-side development, we find ourselves creating many more very small classes and interfaces (often with only two or three parameters each), usually grouped about the workings of a particular component or view, and collating these in a single file just seems to make more sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With