Reputation: 15589
Say I put my code under src
and tests under spec
:
+ spec
+ --- classA.spec.ts
+ src
+ --- classA.ts
+ --- classB.ts
+ --- index.ts
+ tsconfig.json
I want to only transpile src
to the dist
folder. Since index.ts
is the entry point of my package, my tsconfig.json
look like this:
{
"compileOptions": {
"module": "commonjs"
"outDir": "dist"
},
"files": {
"src/index.ts",
"typings/main.d.ts"
}
}
However, this tsconfig.json
does not include the test files so I could not resolve dependencies in them.
On the other hand, if I include the test files into tsconfig.json
then they are also transpiled to dist
folder.
How do I solve this problem?
Upvotes: 134
Views: 110976
Reputation: 2436
Well, I thought I had a pretty terrible solution, but it doesn't even look that bad compared to some of this. I just updated the scripts.build
command in the package.json
file to remove the unwanted test
declarations emitted to dist
:
{
"scripts": {
"build": "vite build && rm -rf ./dist/test"
}
}
Upvotes: 0
Reputation: 28572
user1067920's answer was a good starting point, but I wanted to use vite, but you can't configure the vite tsconfig path. I found a plugin vite-plugin-tsconfig.
My goals:
tsconfig.json
to include tests, so my IDE will show errors for testsI had one issue with vite-plugin-tsconfig. The plugin works by replacing tsconfig.json
with a file you specify in the config:
import tsconfig from "vite-plugin-tsconfig";
...
tsconfig({
filename: "tsconfig.build.json",
}),
If I do what user1067920 suggests, "extends": "./tsconfig.json",
would be a circular reference.
I have 4 tsconfig files 😂️:
tsconfig.node.json
(unchanged, config used for vite (build process))tsconfig.json
{
"extends": "./tsconfig.base.json",
}
tsconfig.build.json
{
"extends": "./tsconfig.base.json",
"exclude": ["node_modules", "**/*.test.ts", "**/*.test.tsx"],
}
tsconfig.base.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noImplicitAny": true,
"noUncheckedIndexedAccess": true,
/* shadcn/ui as per https://ui.shadcn.com/docs/installation/vite */
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules"],
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Upvotes: 1
Reputation: 1572
Here is a detailed solution to manage sources and tests:
The solution is based on 2 tsconfig.json
files as mentioned in other answers.
The main ./tsconfig.json
(used for compilation and IDE):
{
"compileOptions": {
"module": "commonjs"
"outDir": "dist"
},
"include": [
"spec/**/*.spec.ts"
],
"files": [
"src/index.ts"
]
}
The second ./tsconfig-build.json
(used for build):
{
"extends": "./tsconfig.json",
"exclude": [
"spec/**/*.spec.ts"
]
}
Note: we exclude test files that have been included previously
Build command: tsc -p tsconfig-build.json
Or npm run build
if script is added in package.json
:
{
"scripts": {
"build": "tsc -p tsconfig-build.json",
}
Upvotes: 64
Reputation: 879
For me it was because my jest version was 26 and my ts-jest version was 27 so they were out of sync.
yarn jest --version
yarn add ts-jest@26
my jest.config.js
module.exports = {
preset: "ts-jest",
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
transform: {
"^.+\\.tsx?$": "ts-jest",
},
globals: {
"ts-jest": {
diagnostics: false,
},
},
testMatch: ["**/*.(test|spec).(ts|tsx|js|jsx)"],
coveragePathIgnorePatterns: ["/node_modules/"],
coverageReporters: ["json", "lcov", "text", "text-summary"],
transformIgnorePatterns: [
"<rootDir>/node_modules/(?!(firebase/.*|react/.*)/)",
],
testEnvironment: "jest-environment-jsdom-sixteen",
moduleNameMapper: {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"<rootDir>/__mocks__/mocks.js",
"\\.(css|less|scss)$": "<rootDir>/__mocks__/mocks.js",
"^src/(.*)": "<rootDir>/src/$1",
},
};
Upvotes: 0
Reputation: 1254
Simply add an include directory of the source files you want compiled and included in your build. Next, specify your exclude directory in tsconfig.json. For your use case it isn't necessary to have multiple tsconfig files.
{
"include": [ "src/**/*" ],
"exclude": [ "./spec" ]
}
Upvotes: 2
Reputation: 7173
This is somewhat dependent on whatever testing framework you're using but I like to use ts-node to compile my test files. Using mocha, your npm test
script might look like:
"mocha": "mocha test/ --compilers ts:ts-node/register --recursive"
In your tsconfig.json, make sure to remove the rootDir
option.
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"removeComments": true,
"sourceMap": true,
"outDir": "lib"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"lib",
"typings/**"
]
}
When you try to run typescript with rootDir
set to src
or whatever the base folder for your application code is, it'll disallow any compilation in a directory that sits outside, such a tests
. Using ts-node
, you can easily keep everything separate without having to have separate TypeScript configuration files.
Upvotes: 18
Reputation: 15589
I ended up defining multiple config files and use extends
to simplify them.
Say I have two files: tsconfig.json
and tsconfig.build.json
// tsconfig.json
{
...
"exclude": [...]
}
// tsconfig.build.json
{
...
"files": [ "typings/index.d.ts", "src/index.ts" ]
}
This way, I can have fine control on what to build (using tsc -p tsconfig.build.json
) and what the ts language service
(IDE) handles.
UPDATE: now as my projects grow, I ended up having more config files. I use the "extend" feature that is now available in TypeScript:
// tsconfig.base.json
{
// your common settings. Mostly "compilerOptions".
// Do not include "files" and "include" here,
// let individual config handles that.
// You can use "exclude" here, but with "include",
// It's pretty much not necessary.
}
// tsconfig.json
{
// This is used by `ts language service` and testing.
// Includes source and test files.
"extends": "./tsconfig.base.json",
"atom": { ... },
"compilerOptions": {
// I set outDir to place all test build in one place,
// and avoid accidentally running `tsc` littering test build to my `src` folder.
"outDir": "out/spec"
}
"include": [ ... ]
}
// tsconfig.commonjs.json or tsconfig.systemjs.json or tsconfig.global.json etc
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
// for some build this does not apply
"declaration": true/false,
"outDir": "dist/<cjs, sys, global, etc>",
"sourceRoot": "..."
},
// Only point to typings and the start of your source, e.g. `src/index.ts`
"files": [ ... ],
"include": [ ... ]
}
Upvotes: 102
Reputation: 22352
I think you should not use 'files' option in your config. Instead you can exclude unwanted files and have it like this:
{
"compilerOptions": {
"module": "commonjs",
"outDir": "dist"
},
"exclude": [
"node_modules",
"dist",
"typings/browser.d.ts",
"typings/browser/**"
]
}
This will preserve your original structure in the 'dist' folder without mixing tests and app js files:
--dist
----spec
-------....
----src
-------....
Upvotes: 2