Reputation: 1337
What would be an idiomatic directory structure for a TypeScript project?
I would like the following features in such a structure:
Upvotes: 47
Views: 51832
Reputation: 1352
This is an evolving thing for me, but for node projects I am setting up an /src and /dist directory using tsconfig outDir to point to the dist directory:
/root
|__dist/
|__src/
|____lib/
|____etc...
For absolute paths, I use "imports" in package.json:
"imports": {
"#src/*": "./dist/*",
"#lib/*": "./dist/lib/*",
"#root/*": "./*"
},
keep in mind that when it transpiles, it does not touch the import statements which means you need to write them from the perspective of the js code that is created. For me, I feel like it makes more logical sense when developing to write imports from the src/ perspective, which is why you see a src/ mapping to dist/.
Personally, I set the package.json type to module for the more modern imports/exports (even though I know it can transpile to commonJS style require modules), and I target for the latest ES version - reasoning being that if it's just back-end code anyway, I care a lot less about backewards compatibility with older node versions.
The one thing that's kind of annoying is the lack of any built-in cleaning solution for the dist folder if you are using the --watch flag, but personally I just set up nodemon to watch the src/ directory and then run something like:
"scripts": {"dev-watch": "nodemon --watch src --ext \"*\" --exec \"tsc && node dist/app.js\""}
Upvotes: 1
Reputation: 8211
It is very hard to give any concrete advice, since this hugely depends on the project size, tools, platform etc.
--outDir
option which you can use to output to separate directory. However, you would also probably like to bundle so output to single file might be more preferable, as long as you create map files as well for debugging. You can structure all of this very nicely with Gulp for example.Upvotes: 3
Reputation: 2823
I would recommend generating a single-file output. Be it browser or for Node, its just a better idea. Bear in mind that most IDEs can hide .gitignore
d files, so an uncluttered file-pane shouldn't be a problem to attain, even if you let the .js
files sit right next to their .ts
files.
You can technically use --outDir
to output the way you want by setting up your tsconfig.json
appropriately.
This is fairly trivial! Just maintain a /tests
. Imports work simply by directory traversal like so import {MyClass} from "../src/modules/my-class"
(where the ../
is to get out of /tests
).
This is more challenging in the browser than on Node — the latter has require
s working out of the box for TypeScript.
Strongly recommend you go with something like webpack
, but if you insist on living life on the dangerous side, here is a browser-friendly require that I use to rapidly iterate on TypeScript code without having a build process setup.
Since absolute paths are necessary for working web imports, here is how you can use my require()
hack with TypeScript (typically for a fast debugging session that doesn't require rebuilding).
/entities/user.ts
import {Username} from "../entities/username";
import {Password} from "../entities/password";
export class User {
username: Username;
password: Password;
}
Where Username
and Password
are export
ed classes in /entities/username.ts
and /entities/password.ts
respectively.
While the ../entities/
might seem extraneous, notice that it is essential for the browser to have appropriate absolute paths to our Username
and Password
entities. :)
Upvotes: 19
Reputation: 1337
Looks like I was doing it wrong. I was trying the following structure:
src
|---- lib
|-----|---- mymodule.ts
|---- tests
|-----|---- mymodule.tests.ts
However, I was attempting to compile the source code under lib
directory separately from the test code under tests
.
find src/lib -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir lib
and then the tests code:
find src/tests -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir tests
This caused the tests
folder to have another lib
sub-directory and a tests
sub-directory. This was not what I intended to have.
To solve my problem I needed to compile them together, so now my command is:
find src -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir .
Thanks everybody for the help.
Upvotes: 8