Example of file organization:
app/feature1/model.ts
model.spec.ts
controller.ts
controller.spec.ts
template.html
documentation.md
feature2/model.ts
model.spec.ts
controller.ts
controller.spec.ts
template.html
documentation.md
tsconfig.json <-- list *.ts files + third-party *.d.ts (ex: angular.d.ts)
tsconfig.spec.json <-- list *.spec.ts files + third-party *.d.ts (ex: jasmine.d.ts)
tsc works fine. However vscode does not properly highlight files listed in tsconfig.spec.json
(like #5828).
Using TypeScript 1.8.10 and vscode 1.0
This behaves as intended. there is only one special tsconfig.json
. the other ones can be passed explicitly to tsc, but when automatic search is done, either in tsc or in tsserver, only tsconfig.json
is looked up.
Ok, so with tsserver
then how can you organize code by features/components in a simple way? It is a valid use case.
TypeScript very first description line:
TypeScript is a language for application-scale JavaScript
then how can you organize code by features/components?
not sure i understand what you mean by this. if you have a tsconfig per feature/component it is going to work. what is not, is having multiple build configurations for the same feature/component in the IDE.
@mhegazy
not sure i understand what you mean by this
by features/components/modules:
app/feature1/model.ts
model.spec.ts
controller.ts
controller.spec.ts
template.html
style.css
feature.png
README.md
feature2/model.ts
model.spec.ts
controller.ts
controller.spec.ts
template.html
style.css
feature.png
README.md
vs by type of files:
src/models/feature1_model.ts
feature2_model.ts
controllers/feature1_controller.ts
feature2_controller.ts
templates/feature1_template.html
feature2_template.html
doc/feature1.md
feature2.md
styles/feature1.css
feature2.css
img/feature1.png
feature2.png
test/feature1_model.spec.ts
feature2_model.spec.ts
feature1_controller.spec.ts
feature2_controller.spec.ts
Link from my previous comment: https://www.google.fr/search?q=organize+code+by+feature
Examples of AngularJS articles:
Note: most articles don't mention where the tests should go because most people don't write tests and thus don't mention it.
Obviously you want your tests as close as possible to the code they test, not at the other side of your hard drive, same for your code documentation (you've recognized the 'by file type' organization here).
Writing tests and documentation is no fun, your code organization should not make it even harder else you can be sure your team won't never update the tests nor the documentation.
I still do not understand why you can not do this with one tsconfig.json per folder.
why you can not do this with one tsconfig.json per folder
Nobody wants to ship something bundled with the tests on a website, so you need 2 tsconfig.json :)
Also having 1 build for the app and 1 build for the tests helps: you can easily experiment/hack with the app code without having compile errors about the now outdated tests. (typical workflow: hack -> looks good? -> clean things up + write tests).
Sure you can have 3 tsconfig.json instead of 2:
=> More things to maintain :/
Nobody wants to ship something bundled with the tests on a website, so you need 2 tsconfig.json :)
so why not two tsconfig.json files in two folders, i.e. src\tsconfig.json
and test\tsconfig.json
?
srctsconfig.json and testtsconfig.json
Does not solve the problem, see #5828 (my first attempt before TypeScript 1.8 came out with the tsc -project fullpath
feature).
I think allowing a tsconfig.json to reference other tsconfig.json (TypeScript 2.1) will simplify things:
You have 3 tsconfig.json files but the one for the IDE is just an empty shell that points to the others: easy to maintain.
It still feels awkward: go explain to somebody why you have 3 tsconfig.json files...
Another better (and complementary?) solution can be multiple "targets"/builds/projects inside 1 tsconfig.json file (see #1928):
{
"compilerOptions": {
"noImplicitAny": true,
"removeComments": false,
"sourceMap": true
},
"files": [
"common/util.ts"
]
"projects": {
"app": {
"compilerOptions": {
"outFile": "app.js"
},
"files": [
"feature1/model.ts",
"feature1/controller.ts",
"feature2/model.ts",
"feature2/controller.ts"
]
},
"unittests": {
"compilerOptions": {
"outFile": "unittests.js"
},
"files": [
"feature1/model.spec.ts",
"feature1/controller.spec.ts",
"feature2/model.spec.ts",
"feature2/controller.spec.ts"
]
},
"e2etests": {
"compilerOptions": {
"outFile": "e2etests.js"
},
"files": [
"feature1/e2e.spec.ts",
"feature2/e2e.spec.ts"
]
},
"app-es3-amd": {
"compilerOptions": {
"target": "es3",
"module": "amd",
"outFile": "app-es3-amd.js"
},
"files": [
"feature1/model.ts",
"feature1/controller.ts",
"feature2/model.ts",
"feature2/controller.ts"
]
}
}
}
This is not the intended use of tsconfig.json. it is not meant to be a build orchestration tool nor a solution file. a single tsconfig.json represents a single invocation to tsc.exe/tsc.js. and that is that. for more interesting build/configuration consider using other build tools e.g. MSBuild, grunt or gulp.
my recommendations for this scenario are:
consider using other build tools e.g. MSBuild, grunt or gulp [...] use a build tool to ensure building the tests will build the sources
Obviously, how can you do without? sass/less, minification, launch a server, move files around, call tsc -p...
use two tsconfig.json files, one in sources and one in tests.
Does not please the IDE, see #5828. You can check for yourself: https://github.com/tkrotoff/vscode-tsconfig.conf-issue
Anyway...
use two tsconfig.json files, one in sources and one in tests.
This is the one I'd recommend as well. The test file should be in a folder _above_ the src
. TSServer will work as it is
I'll work on improving the _set project_ in alm to take more than files by tsconfig.json
name at some point so it shows more than just tsconfig.json
exact matches https://github.com/alm-tools/alm/blob/master/docs/features/omni-search.md#project-search
:rose:
Does not please the IDE, see #5828. You can check for yourself: https://github.com/tkrotoff/vscode-tsconfig.conf-issue
I see now, so you want the tests to be next to your app, but not in the production release. so why not have two tsconfig.json, at the root, one tsconfig.json
(includes all files, tests and sources), and another one tsconfig.production.json
that excludes the test files?
you want the tests to be next to your app, but not in the production release
YES! :-)
one tsconfig.json (includes all files, tests and sources), and another one tsconfig.production.json that excludes the test files?
Exactly what I do now
no need for an uber project that unify them
Multiple "targets"/builds/projects inside 1 tsconfig.json has already been proposed: #1928.
This + allowing tsconfig.json to reference other tsconfig.json files cleanly solved all use cases.
Multiple "targets"/builds/projects inside 1 tsconfig.json has already been proposed: #1928.
I do not think we will be parametrizing tsconfig.json any time soon, for the same reason i listed earlier. tsconfig.json is just an easy way to call tsc.exe with a punch of parameters. if you want to do something fancier, you should use a build system/ solution file (whatever that would be in your editor).
This + allowing tsconfig.json to reference other tsconfig.json files cleanly solved all use cases.
you can see my argument against using tsconfig.json as a build manager in https://github.com/Microsoft/TypeScript/issues/3469#issuecomment-111254952.
extends works for maintaining multiple build files, but there's still an editor issue. Jetbrains (IntelliJ / WebStorm) recently implemented IDE support for selecting the appropriate tsconfig file by exclude / include / files: see the blog post and bug
A rough description, they have configurable file name patterns for config files, expanding the lookup for tsconfig.json
(say, to tsconfig.*.json
- it seems they reverted the default pattern list since the post to just tsconfig.json
again), and for each edited file select the first found config where the paths match.
Therefore, you could have, for example:
tsconfig-base.json
with common settings (not directly used)tsconfig.web.json
with lib: ['dom'], types: []
and include: ['src'], exclude: ['*.test.ts', '**/__mocks__']
tsconfig.test.json
with types: ['node', 'jest']
and include: ['src/**/*.test.ts', 'src/**/__mocks__']
tsconfig.scripts.json
with types: ['node']
and exclude: ['node_modules', 'src']
And have the editor know that, e.g. describe()
is invalid in scripts/start.ts
, and window.location
is invalid in src/App.test.ts
This is an incredibly annoying problem.
I understand the argument that tsc
shouldn't be used as a build tool, and tsconfig.json shouldn't be used as build configuration. But it is because MS is using tsc
as a linter that this issue is a problem for us.
Real-world example:
/tsconfig.json
/src/**/*.ts
/src/**/*.spec.ts
/tsconfig.json
obviously excludes *.spec.ts
so they aren't compiled into /lib
and distributed to npm.something.spec.ts
uses decorators (mocha-typescript
) - VSCode gives many "Experimental support for decorators is a feature that is subject..."We will not put our tests in a separate /tests
folder because they are not visible. When specs are beside the files they're testing, it is easy to see when tests are missing or haven't been updated. So with the spec files in the same folder as the source code, how exactly would one go about telling tsc/VSCode that there are different requirements for spec files?
I have tried putting a spec-specific tsconfig.json
in the /src/
folder and leaving the main tsconfig.json
in the root. That didn't work.
I can see that this isn't necessarily a typescript issue - for me it's more of a VS Code configuration issue - I should be able to specify which tsconfig
matches which files - but I think the request here is that it "just work" because the files themselves already have the matchers needed to decide which config to use. There would just need to be some way to register all the config files or some naming convention, etc.
I'm more in favor of a VSCode config file that would register my two tsconfig.json
files and based on the include/exclude settings in the file choose the proper config to pass to tsc for the file I'm looking at.
I don't have the perfect solution, but I know that putting things like this at the top of all my spec files:
// - tests require packages from devDependencies
// - mocha has side-effects
// - chai has odd syntax
/* tslint:disable no-implicit-dependencies no-import-side-effect no-unused-expression function-name max-classes-per-file no-any */
shouldn't be necessary. And looking at this makes the problems panel in VS Code useless.
Most helpful comment
This is an incredibly annoying problem.
I understand the argument that
tsc
shouldn't be used as a build tool, and tsconfig.json shouldn't be used as build configuration. But it is because MS is usingtsc
as a linter that this issue is a problem for us.Real-world example:
/tsconfig.json
/src/**/*.ts
/src/**/*.spec.ts
/tsconfig.json
obviously excludes*.spec.ts
so they aren't compiled into/lib
and distributed to npm.something.spec.ts
uses decorators (mocha-typescript
) - VSCode gives many "Experimental support for decorators is a feature that is subject..."We will not put our tests in a separate
/tests
folder because they are not visible. When specs are beside the files they're testing, it is easy to see when tests are missing or haven't been updated. So with the spec files in the same folder as the source code, how exactly would one go about telling tsc/VSCode that there are different requirements for spec files?I have tried putting a spec-specific
tsconfig.json
in the/src/
folder and leaving the maintsconfig.json
in the root. That didn't work.I can see that this isn't necessarily a typescript issue - for me it's more of a VS Code configuration issue - I should be able to specify which
tsconfig
matches which files - but I think the request here is that it "just work" because the files themselves already have the matchers needed to decide which config to use. There would just need to be some way to register all the config files or some naming convention, etc.I'm more in favor of a VSCode config file that would register my two
tsconfig.json
files and based on the include/exclude settings in the file choose the proper config to pass to tsc for the file I'm looking at.I don't have the perfect solution, but I know that putting things like this at the top of all my spec files:
shouldn't be necessary. And looking at this makes the problems panel in VS Code useless.