diff --git a/website/versioned_docs/version-29.0/babel7-or-ts.md b/website/versioned_docs/version-29.0/babel7-or-ts.md new file mode 100644 index 0000000000..d25375ba18 --- /dev/null +++ b/website/versioned_docs/version-29.0/babel7-or-ts.md @@ -0,0 +1,76 @@ +--- +id: babel7-or-ts +title: Babel7 or TypeScript +--- + +In Sept. 2018 Babel7 got released with an interesting preset: `@babel/preset-typescript`. + +The goal is to make it easy for users using Babel to try TypeScript without moving out from Babel, just by adding a preset in their Babel config (here is the [MSDN blog post](https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/) about TypeScript and Babel 7). + +## Limitations + +While `@babel/preset-typescript` is a great preset, you must know the limitation of it. Here is what is possible with TypeScript (and `ts-jest`), which is not with Babel7 and `@babel/preset-typescript`: + +#### No type-checking + +This is the big **PRO** of using TypeScript vs Babel, you have type-checking out of the box. + +You'll get a more fluent TDD experience (when using `ts-jest`) since files will be type-checked at the same time they're compiled and ran. + +Here TypeScript will throw while Babel won't: + +```ts +const str: string = 42 +``` + +With Babel, files are transpiled as isolated modules, there is no notion of "project". With TypeScript, files are part of a project and are compiled in that scope. + +--- + +#### No `namespace` + +```ts +namespace app { + export const VERSION = '1.0.0' + export class App { + /* ... */ + } +} +``` + +--- + +#### No `const enum` + +```ts +const enum Directions { + Up, + Down, + Left, + Right, +} +``` + +--- + +#### No declaration merging (`enum`, `namespace`, ...) + +You won't be able to do [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html). + +--- + +#### No legacy `import`/`export` + +```ts +import lib = require('lib') +// ... +export = myVar +``` + +--- + +#### No caret type-casting with JSX enabled + +```ts +const val = input +``` diff --git a/website/versioned_docs/version-29.0/contributing.md b/website/versioned_docs/version-29.0/contributing.md new file mode 100644 index 0000000000..f2b57691e7 --- /dev/null +++ b/website/versioned_docs/version-29.0/contributing.md @@ -0,0 +1,174 @@ +--- +id: contributing +title: Contributing +--- + +When contributing to this repository, please first discuss the change you wish to make via [`ts-jest` GitHub discussion](https://github.com/kulshekhar/ts-jest/discussions) or [issue](https://github.com/kulshekhar/ts-jest/issues) with the owners of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Ensure the tests are passing and that you have latest `main` branch merged in. +2. Update the `docs/` with details of your changes if required. +3. If possible, squash your commits. There must be only one commit in your PR (until a review). Then after each review requesting changes, DO NOT squash your commits with the one before the review, so that we can see intermediate modifications. +4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you do not have permission to do that, you may request the second reviewer to merge it for you. + +_These are internal technical documents. If you're not a contributor to `ts-jest`, but simply trying to use the library you'll find nothing of value here_ + +## E2E Testing + +### Preparing + +The preparation of E2E test directory is done in `scripts/e2e.js`. Here is the process: + +```plantuml +start + +:bundle ts-jest; +note right +will build ts-jest before creating the bundle +end note + +:create temp work dir; +note right +`e2e/~__workdir_symlink__` links to it +except on CI environments +end note + +while (for each template) +note right +templates are in `e2e/~__templates__/` +end note + +if (template's build directory) then (exists) +:wipe but `node_modules` dir; +else (not exists) +:create; +endif + +:copy files from template's dir to its build dir; + +if (package lock file) then (exists) +:read metadata; + + if (package lock file) then (has changed) + :remove `node_modules` dir; + + :npm install (or ci); + + :npm install ts-jest bundle; + + else if (ts-jest bundle) then (has changed) + :npm install ts-jest bundle; + + else (hasn't changed) + endif + :write updated metadata; + +else (not exists) +endif + +endwhile (done) + +:all templates ready; + +stop +``` + +### Running + +When a test-case needs to be run with a given template within tests, here is what's happening (in `e2e/__helpers__/test-case/runtime.ts`): + +```plantuml +start + +:create work dir; +note right +It'll be different per test-case +and per template basis. +end note +-> e2e/~__workdir_symlink__/{template}/{test-case}; + +if (has a node_modules dir?) then (yes) +:symlink node_modules; +note left +avoid re-running npm install +for each test case and template; +end note +else (no) +endif + +:copy files from template; +note right +all files in template dir are +copied to test case work dir +except `node_modules` and +`package-lock.json` +end note + +while (for each file in test case dir) +if (is snapshot dir) then (yes) +:symlink dir; +note left +snapshots directories are symlinked +to test case source dir so that +updating them would update in the +source folder +end note + +else if (is jest.config.js) then (yes) +if (jest.config.js is function?) then (yes) +:call with parent content; +note left +allows for +extending +end note +else (no) +endif + +else (others) +:copy; +note right +all files in test case source +dir are copied to the work dir +except `node_modules` and +`package-lock.json` +end note + +endif +endwhile + +:create special files; +note right +some special files are created +to handle hooks for example and +grab `process()` IO for later +expectations +end note + +:update package.json; +note right +set a custom but fixed name +and version in package.json +which is specific to the +test case + template +end note + +#tomato:run tests; + +while (for each snapshot) is (missing in test case) +:copy; +note right +while we symlinked each snapshots +directory, newly created snapshots +in non existing dir will need to +be copied over into +e2e/~__cases__/{test-case} +end note +endwhile + +:return results; + +stop +``` diff --git a/website/versioned_docs/version-29.0/debugging.md b/website/versioned_docs/version-29.0/debugging.md new file mode 100644 index 0000000000..3d814c7e52 --- /dev/null +++ b/website/versioned_docs/version-29.0/debugging.md @@ -0,0 +1,30 @@ +--- +id: debugging +title: Debugging ts-jest +--- + +You can activate the debug logger by setting the environment variable `TS_JEST_LOG` before running tests. +The output of the logger will be in **ts-jest.log** in current working directory. + +The debug logger contains some useful information about how internal `ts-jest` works, including which files are processed, +which Jest config or TypeScript config is used etc. + +**Linux/MacOS** + +``` +export TS_JEST_LOG=ts-jest.log +``` + +**Windows** + +Command Prompt (cmd) + +``` +set TS_JEST_LOG=ts-jest.log +``` + +PowerShell + +``` +$env:TS_JEST_LOG = 'ts-jest.log' +``` diff --git a/website/versioned_docs/version-29.0/getting-started/installation.md b/website/versioned_docs/version-29.0/getting-started/installation.md new file mode 100644 index 0000000000..62ea81eec4 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/installation.md @@ -0,0 +1,58 @@ +--- +id: installation +title: Installation +--- + +### Dependencies + +You can install `ts-jest` and dependencies all at once with one of the following commands. + +#### NPM + +```sh +npm install --save-dev jest typescript ts-jest @types/jest +``` + +#### Yarn + +```sh +yarn add --dev jest typescript ts-jest @types/jest +``` + +:::tip + +Tip: If you get an error with the following `npm` commands such as `npx: command not found`, you can replace `npx XXX` with `node node_modules/.bin/XXX` from the root of your project. + +::: + +### Jest config file + +#### Creating + +By default, Jest can run without any config files, but it will not compile `.ts` files. +To make it transpile TypeScript with `ts-jest`, we will need to create a configuration file that will tell Jest to use a `ts-jest` preset. + +`ts-jest` can create the configuration file for you automatically: + +#### NPM + +```sh +npx ts-jest config:init +``` + +#### Yarn + +```sh +yarn ts-jest config:init +``` + +This will create a basic Jest configuration file which will inform Jest about how to handle `.ts` files correctly. + +You can also use the `jest --init` command (prefixed with either `npx` or `yarn` depending on what you're using) to have more options related to Jest. +However, answer `no` to the Jest question about whether or not to enable TypeScript. Instead, add the line: `preset: "ts-jest"` to the `jest.config.js` file afterwards. + +#### Customizing + +For customizing jest, please follow their [official guide online](https://jestjs.io/docs/en/configuration.html). + +`ts-jest` specific options can be found [here](options). diff --git a/website/versioned_docs/version-29.0/getting-started/options.md b/website/versioned_docs/version-29.0/getting-started/options.md new file mode 100644 index 0000000000..4a3b6ce6e3 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options.md @@ -0,0 +1,114 @@ +--- +id: options +title: Options +--- + +### Introduction + +All `ts-jest` specific options can be defined in Jest `transform` config object in the `package.json` file of your project, +or through a `jest.config.js`, or `jest.config.ts` file. + +```json +// package.json +{ + // [...] + "jest": { + "transform": { + "": [ + "ts-jest", + { + // ts-jest configuration goes here + } + ] + } + } +} +``` + +Or through JavaScript: + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + // ts-jest configuration goes here + }, + ], + }, +} +``` + +:::tip + +To utilize IDE suggestions, you can use `JSDoc` comments to provide suggested `ts-jest` configs for your Jest config: + +```js +/** @type {import('ts-jest').InitialOptionsTsJest} */ +module.exports = config = { + // [...] + transform: { + '': [ + 'ts-jest', + { + // ts-jest configuration goes here and your IDE will suggest which configs when typing + }, + ], + }, +} +``` + +::: + +Or through TypeScript (if `ts-node` is installed): + +```ts +// jest.config.ts +import type { InitialOptionsTsJest } from 'ts-jest' + +const config: InitialOptionsTsJest = { + transform: { + '': [ + 'ts-jest', + { + // ts-jest configuration goes here + }, + ], + }, +} +export default config +``` + +:::important + +When using TypeScript Jest config file, Jest will use `ts-node` to compile the config file. `ts-jest` doesn't take part in +that process. + +::: + +### Options + +All options have default values which should fit most of the projects. Click on the option's name to see details and example(s). + +| Option | Description | Type | Default | +| ------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ----------------------------- | -------------- | +| [**`compiler`**][compiler] | [TypeScript module to use as compiler.][compiler] | `string` | `"typescript"` | +| [**`tsconfig`**][tsconfig] | [TypeScript compiler related configuration.][tsconfig] | `string`\|`object`\|`boolean` | _auto_ | +| [**`isolatedModules`**][isolatedmodules] | [Disable type-checking][isolatedmodules] | `boolean` | _disabled_ | +| [**`astTransformers`**][asttransformers] | [Custom TypeScript AST transformers][asttransformers] | `object` | _auto_ | +| [**`diagnostics`**][diagnostics] | [Diagnostics related configuration.][diagnostics] | `boolean`\|`object` | _enabled_ | +| [**`babelConfig`**][babelconfig] | [Babel(Jest) related configuration.][babelconfig] | `boolean`\|`string`\|`object` | _disabled_ | +| [**`stringifyContentPathRegex`**][stringifycontentpathregex] | [Files which will become modules returning self content.][stringifycontentpathregex] | `string`\|`RegExp` | _disabled_ | +| [**`useESM`**][useesm] | [Enable ESM support][useesm] | `boolean` | _auto_ | + +[compiler]: options/compiler +[tsconfig]: options/tsconfig +[isolatedmodules]: options/isolatedModules +[asttransformers]: options/astTransformers +[diagnostics]: options/diagnostics +[babelconfig]: options/babelConfig +[stringifycontentpathregex]: options/stringifyContentPathRegex +[useesm]: options/useESM diff --git a/website/versioned_docs/version-29.0/getting-started/options/astTransformers.md b/website/versioned_docs/version-29.0/getting-started/options/astTransformers.md new file mode 100644 index 0000000000..1998f7746d --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/astTransformers.md @@ -0,0 +1,105 @@ +--- +title: AST transformers option +--- + +`ts-jest` by default does hoisting for a few `jest` methods via a TypeScript AST transformer. One can also create custom +TypeScript AST transformers and provide them to `ts-jest` to include into compilation process. + +The option is `astTransformers` and it allows ones to specify which 3 types of TypeScript AST transformers to use with `ts-jest`: + +- `before` means your transformers get run before TS ones, which means your transformers will get raw TS syntax + instead of transpiled syntax (e.g `import` instead of `require` or `define` ). +- `after` means your transformers get run after TS ones, which gets transpiled syntax. +- `afterDeclarations` means your transformers get run during `d.ts` generation phase, allowing you to transform output type declarations. + +### Examples + +#### Basic Transformers + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + astTransformers: { + before: ['my-custom-transformer'], + }, + }, + ], + }, +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + "transform": { + "": [ + "ts-jest", + { + "astTransformers": { + "before": ["my-custom-transformer"] + } + } + ] + } + } +} +``` + +#### Configuring transformers with options + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + astTransformers: { + before: [ + { + path: 'my-custom-transformer-that-needs-extra-opts', + options: {}, // extra options to pass to transformers here + }, + ], + }, + }, + ], + }, +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + "transform": { + "": [ + "ts-jest", + { + "astTransformers": { + "before": [ + { + "path": "my-custom-transformer-that-needs-extra-opts", + "options": {} // extra options to pass to transformers here + } + ] + } + } + ] + } + } +} +``` + +### Writing custom TypeScript AST transformers + +To write a custom TypeScript AST transformers, one can take a look at [the one](https://github.com/kulshekhar/ts-jest/tree/main/src/transformers) that `ts-jest` is using. diff --git a/website/versioned_docs/version-29.0/getting-started/options/babelConfig.md b/website/versioned_docs/version-29.0/getting-started/options/babelConfig.md new file mode 100644 index 0000000000..73a6ee27c4 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/babelConfig.md @@ -0,0 +1,140 @@ +--- +title: Babel Config option +--- + +`ts-jest` by default does **NOT** use Babel. But you may want to use it, especially if your code rely on Babel plugins to make some transformations. `ts-jest` can call the BabelJest processor once TypeScript has transformed the source into JavaScript. + +The option is `babelConfig` and it works pretty much as the `tsconfig` option, except that it is disabled by default. Here is the possible values it can take: + +- `false`: the default, disables the use of Babel +- `true`: enables Babel processing. `ts-jest` will try to find a `.babelrc`, `.babelrc.js`, `babel.config.js` file or a `babel` section in the `package.json` file of your project and use it as the config to pass to `babel-jest` processor. +- `{ ... }`: inline [Babel options](https://babeljs.io/docs/en/next/options). You can also set this to an empty object (`{}`) so that the default Babel config file is not used. + +### Examples + +#### Use default `babelrc` file + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + babelConfig: true, + }, + ], + }, +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + "transform": { + "": [ + "ts-jest", + { + "babelConfig": true + } + ] + } + } +} +``` + +#### Path to a `babelrc` file + +The path should be relative to the current working directory where you start Jest from. You can also use `\` in the path, or use an absolute path (this last one is strongly not recommended). + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + babelConfig: 'babelrc.test.js', + }, + ], + }, +} +``` + +```js +// OR jest.config.js with require for babelrc +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + babelConfig: require('./babelrc.test.js'), + }, + ], + }, +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + "transform": { + "": [ + "ts-jest", + { + "babelConfig": "babelrc.test.js" + } + ] + } + } +} +``` + +#### Inline compiler options + +Refer to the [Babel options](https://babeljs.io/docs/en/next/options) to know what can be used there. + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '': [ + 'ts-jest', + { + babelConfig: { + comments: false, + plugins: ['@babel/plugin-transform-for-of'], + }, + }, + ], + }, +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + "transform": { + "": [ + "ts-jest", + { + "babelConfig": { + "comments": false, + "plugins": ["@babel/plugin-transform-for-of"] + } + } + ] + } + } +} +``` diff --git a/website/versioned_docs/version-29.0/getting-started/options/compiler.md b/website/versioned_docs/version-29.0/getting-started/options/compiler.md new file mode 100644 index 0000000000..0d21700a85 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/compiler.md @@ -0,0 +1,44 @@ +--- +title: Compiler option +--- + +The `compiler` option allows you to define the compiler to be used. It'll be used to load the NodeJS module holding the TypeScript compiler. + +The default value is `typescript`, which will load the original [TypeScript compiler module](https://www.npmjs.com/package/typescript). +The loaded version will depend on the one installed in your project. + +If you use a custom compiler, such as `ttypescript`, make sure its API is the same as the original TypeScript, at least for what `ts-jest` is using. + +### Example + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "compiler": "ttypescript" + } + ] + } + } +} +``` diff --git a/website/versioned_docs/version-29.0/getting-started/options/diagnostics.md b/website/versioned_docs/version-29.0/getting-started/options/diagnostics.md new file mode 100644 index 0000000000..09958e8e00 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/diagnostics.md @@ -0,0 +1,191 @@ +--- +title: Diagnostics option +--- + +The `diagnostics` option configures error reporting. +It can both be enabled/disabled entirely or limited to a specific type of errors and/or files. + +If a diagnostic is not filtered out, `ts-jest` will fail the compilation and your test. + +### Disabling/enabling + +By default all diagnostics are enabled. This is the same as setting the `diagnostics` option to `true`. +To disable all diagnostics, set `diagnostics` to `false`. +This might lead to slightly better performance, especially if you're not using Jest's cache. + +### Advanced configuration + +The `diagnostics` option's value can also accept an object for more advanced configuration. Each config. key is optional: + +- **`warnOnly`**: If specified and `true`, diagnostics will be reported but won't stop compilation (default: _disabled_). +- **`ignoreCodes`**: List of TypeScript error codes to ignore. Complete list can be found [there](https://github.com/Microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json). By default here are the ones ignored: + - `6059`: _'rootDir' is expected to contain all source files._ + - `18002`: _The 'files' list in config file is empty._ (it is strongly recommended including this one) + - `18003`: _No inputs were found in config file._ +- **`exclude`**: If specified, diagnostics of source files which path **matches** will be ignored. This works a bit + similar to `tsconfig` option [exclude](https://www.typescriptlang.org/tsconfig#exclude) with the only difference is that + in TypeScript, `exclude` will also exclude files from compilation process. +- **`pretty`**: Enables/disables colorful and pretty output of errors (default: _enabled_). + +### Examples + +#### Disabling diagnostics + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "diagnostics": false + } + ] + } + } +} +``` + +#### Advanced options + +##### Enabling diagnostics for test files only + +Assuming all your test files ends with `.spec.ts` or `.test.ts`, using the following config will enable error reporting only for those files: + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "diagnostics": { + "exclude": ["!**/*.(spec|test).ts"] + } + } + ] + } + } +} +``` + +##### Do not fail on first error + +While some diagnostics are stop-blockers for the compilation, most of them are not. If you want the compilation (and so your tests) to continue when encountering those, set the `warnOnly` to `true`: + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "diagnostics": { + "warnOnly": true + } + } + ] + } + } +} +``` + +##### Ignoring some error codes + +All TypeScript error codes can be found [there](https://github.com/Microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json). The `ignoreCodes` option accepts this values: + +1. A single `number` (example: `1009`): unique error code to ignore +2. A `string` with a code (example `"1009"`, `"TS1009"` or `"TS1009"`) +3. A `string` with a list of the above (example: `"1009, TS2571, 4072"`) +4. An `array` of one or more from `1` or `3` (example: `[1009, "TS2571", "6031"]`) + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "diagnostics": { + "ignoreCodes": [2571, 6031, 18003] + } + } + ] + } + } +} +``` diff --git a/website/versioned_docs/version-29.0/getting-started/options/isolatedModules.md b/website/versioned_docs/version-29.0/getting-started/options/isolatedModules.md new file mode 100644 index 0000000000..fa74347415 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/isolatedModules.md @@ -0,0 +1,70 @@ +--- +title: Isolated Modules option +--- + +By default `ts-jest` uses TypeScript compiler in the context of a project (yours), with full type-checking and features. +But it can also be used to compile each file separately, what TypeScript calls an 'isolated module'. +That's what the `isolatedModules` option (which defaults to `false`) does. + +You'll lose type-checking ability and some features such as `const enum`, but in the case you plan on using Jest with the cache disabled (`jest --no-cache`), your tests will then run much faster. + +Here is how to disable type-checking and compile each file as an isolated module: + +### Example + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "isolatedModules": true + } + ] + } + } +} +``` + +## Performance + +Using `isolatedModules: false` comes with a cost of performance comparing to `isolatedModules: true`. There is a way +to improve the performance when using this mode by changing the value of `include` in `tsconfig` which is used by `ts-jest`. +The least amount of files which are provided in `include`, the more performance the test run can gain. + +### Example + +```json +// tsconfig.json +{ + // ...other configs + "include": ["my-typings/*", "my-global-modules/*"] +} +``` + +## Caveats + +Limiting the amount of files loaded via `include` can greatly boost performance when running tests. However, the trade off +is `ts-jest` might not recognize all files which are intended to use with `jest`. One can run into issues with custom typings, +global modules, etc... + +The suggested solution is what is needed for the test environment should be captured by +glob patterns in `include`, to gain both performance boost and avoid breaking behaviors. diff --git a/website/versioned_docs/version-29.0/getting-started/options/stringifyContentPathRegex.md b/website/versioned_docs/version-29.0/getting-started/options/stringifyContentPathRegex.md new file mode 100644 index 0000000000..f3302665d0 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/stringifyContentPathRegex.md @@ -0,0 +1,56 @@ +--- +title: Stringify content option +--- + +The `stringifyContentPathRegex` option has been kept for backward compatibility of `__HTML_TRANSFORM__` +It's a regular expression pattern used to match the path of file to be transformed. +If it matches, the file will be exported as a module exporting its content. + +Let's say for example that you have a file `foo.ts` which contains `export default "bar"`, and your `stringifyContentPathRegex` is set to `foo\\.ts$`, the resulting module won't be the result of compiling `foo.ts` source, but instead it'll be a module which exports the string `"export default \"bar\""`. + +**CAUTION**: Whatever file(s) you want to match with `stringifyContentPathRegex` pattern, you must ensure the Jest `transform` option pointing to `ts-jest` matches them. You may also have to add the extension(s) of this/those file(s) to `moduleFileExtensions` Jest option. + +### Example + +In the `jest.config.js` version, you could do as in the `package.json` version of the config, but extending from the preset will ensure more compatibility without any changes when updating. + +```js +// jest.config.js +// Here `defaults` can be replaced with any other preset +const { defaults: tsjPreset } = require('ts-jest/presets') + +module.exports = { + // [...] + moduleFileExtensions: [...tsjPreset.moduleFileExtensions, 'html'], + transform: { + ...tsjPreset.transform, + '\\.html$': 'ts-jest', + }, + transform: { + '` in the path to start from the project root dir. + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "tsconfig": "tsconfig.test.json" + } + ] + } + } +} +``` + +#### Inline compiler options + +Refer to the TypeScript [compiler options][] for reference. +It's basically the same object you'd put in your `tsconfig.json`'s `compilerOptions`. + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "tsconfig": { + "importHelpers": true + } + } + ] + } + } +} +``` + +#### Disable auto-lookup + +By default `ts-jest` will try to find a `tsconfig.json` in your project. But you may not want to use it at all and keep TypeScript default options. You can achieve this by setting `tsconfig` to `false`. + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "tsconfig": { + "tsconfig": false + } + } + ] + } + } +} +``` + +[compiler options]: https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options diff --git a/website/versioned_docs/version-29.0/getting-started/options/useESM.md b/website/versioned_docs/version-29.0/getting-started/options/useESM.md new file mode 100644 index 0000000000..9bd28aa794 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/options/useESM.md @@ -0,0 +1,41 @@ +--- +title: useESM option +--- + +The `useESM` option allows `ts-jest` to transform codes to ESM syntax **if possible**. + +The default value is **false**, `ts-jest` will transform codes to `CommonJS` syntax. + +### Examples + +```js +// jest.config.js +module.exports = { + // [...] + transform: { + '": [ + "ts-jest", + { + "useESM": true + } + ] + } + } +} +``` diff --git a/website/versioned_docs/version-29.0/getting-started/paths-mapping.md b/website/versioned_docs/version-29.0/getting-started/paths-mapping.md new file mode 100644 index 0000000000..ab1584623d --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/paths-mapping.md @@ -0,0 +1,68 @@ +--- +id: paths-mapping +title: Paths mapping +--- + +If you use ["baseUrl" and "paths" options](https://www.typescriptlang.org/docs/handbook/module-resolution.html) in your `tsconfig` file, you should make sure the ["moduleNameMapper"](https://jestjs.io/docs/configuration#modulenamemapper-objectstring-string--arraystring) option in your Jest config is setup accordingly. + +`ts-jest` provides a helper to transform the mapping from `tsconfig` to Jest config format, but it needs the `.js` version of the config file. + +### Example + +#### TypeScript config + +With the below config in your `tsconfig`: + +```json +// tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@App/*": ["src/*"], + "lib/*": ["common/*"] + } + } +} +``` + +#### Jest config (without helper) + +```js +// jest.config.js +module.exports = { + // [...] + moduleNameMapper: { + '^@App/(.*)$': '/src/$1', + '^lib/(.*)$': '/common/$1', + }, +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + "moduleNameMapper": { + "^@App/(.*)$": "/src/$1", + "^lib/(.*)$": "/common/$1" + } + } +} +``` + +#### Jest config (with helper) + +```js +// jest.config.js +const { pathsToModuleNameMapper } = require('ts-jest') +// In the following statement, replace `./tsconfig` with the path to your `tsconfig` file +// which contains the path mapping (ie the `compilerOptions.paths` option): +const { compilerOptions } = require('./tsconfig') + +module.exports = { + // [...] + moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths /*, { prefix: '/' } */), +} +``` diff --git a/website/versioned_docs/version-29.0/getting-started/presets.md b/website/versioned_docs/version-29.0/getting-started/presets.md new file mode 100644 index 0000000000..15643e11aa --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/presets.md @@ -0,0 +1,105 @@ +--- +id: presets +title: Presets +--- + +### The presets + +:::important + +Starting from **v28.0.0**, `ts-jest` will gradually opt in adoption of `esbuild`/`swc` more to improve the performance. To make the transition smoothly, we introduce `legacy` presets as a fallback when the new codes don't work yet. + +::: + +`ts-jest` comes with several presets, covering most of the project's base configuration: + +| Preset name | Description | +| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ts-jest/presets/default`
or `ts-jest` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/default-legacy`
or `ts-jest/legacy` (**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/default-esm`
| TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/default-esm-legacy`
(**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/js-with-ts` | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`) will be transformed by `ts-jest` to **CommonJS** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-ts-legacy` (**LEGACY**) | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`) will be transformed by `ts-jest` to **CommonJS** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-ts-esm` | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`) will be transformed by `ts-jest` to **ESM** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-ts-esm-legacy` (**LEGACY**) | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`) will be transformed by `ts-jest` to **ESM** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-babel` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, and JavaScript files (`.js`, `jsx`) will be transformed by `babel-jest`. | +| `ts-jest/presets/js-with-babel-legacy` (**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, and JavaScript files (`.js`, `jsx`) will be transformed by `babel-jest`. | +| `ts-jest/presets/js-with-babel-esm` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, and JavaScript files (`.js`, `jsx`, `.mjs`) will be transformed by `babel-jest`. | +| `ts-jest/presets/js-with-babel-esm-legacy` (**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, and JavaScript files (`.js`, `jsx`, `.mjs`) will be transformed by `babel-jest`. | + +### Basic usage + +In most cases, simply setting the `preset` key to the desired preset name in your Jest config should be enough to start +using TypeScript with Jest (assuming you added `ts-jest` to your `devDependencies` of course): + +```js +// jest.config.js +module.exports = { + // [...] + // Replace `ts-jest` with the preset you want to use + // from the above list + preset: 'ts-jest', +} +``` + +```json +// OR package.json +{ + // [...] + "jest": { + // Replace `ts-jest` with the preset you want to use + // from the above list + "preset": "ts-jest" + } +} +``` + +**Note:** presets use `testMatch`, like Jest does in its defaults. If you want to use `testRegex` instead in your configuration, you MUST set `testMatch` to `null` or Jest will bail. + +### Advanced + +Any preset can also be used with other options. +If you're already using another preset, you might want only some specific settings from the chosen `ts-jest` preset. +In this case you'll need to use the JavaScript version of Jest config (comment/uncomment according to your use case): + +```js +// jest.config.js +const { defaults: tsjPreset } = require('ts-jest/presets') +// const { defaultsESM: tsjPreset } = require('ts-jest/presets') +// const { jsWithTs: tsjPreset } = require('ts-jest/presets') +// const { jsWithTsESM: tsjPreset } = require('ts-jest/presets') +// const { jsWithBabel: tsjPreset } = require('ts-jest/presets') +// const { jsWithBabelESM: tsjPreset } = require('ts-jest/presets') + +module.exports = { + // [...] + transform: { + ...tsjPreset.transform, + // [...] + }, +} +``` + +Or through TypeScript (if `ts-node` is installed): + +```ts +// jest.config.ts +import type { InitialOptionsTsJest } from 'ts-jest' +import { defaults as tsjPreset } from 'ts-jest/presets' +// import { defaultsESM as tsjPreset } from 'ts-jest/presets' +// import { jsWithTs as tsjPreset } from 'ts-jest/presets' +// import { jsWithTsESM as tsjPreset } from 'ts-jest/presets' +// import { jsWithBabel as tsjPreset } from 'ts-jest/presets' +// import { jsWithBabelESM as tsjPreset } from 'ts-jest/presets' + +const config: InitialOptionsTsJest = { + // [...] + transform: { + ...tsjPreset.transform, + // [...] + }, +} + +export default config +``` diff --git a/website/versioned_docs/version-29.0/getting-started/version-checking.md b/website/versioned_docs/version-29.0/getting-started/version-checking.md new file mode 100644 index 0000000000..58c4f5ec67 --- /dev/null +++ b/website/versioned_docs/version-29.0/getting-started/version-checking.md @@ -0,0 +1,24 @@ +--- +id: version-checking +title: Version checking +--- + +By default, `ts-jest` supports a range of versions for `jest`/`typescript`. One uses incompatible versions will receive a warning +message while running tests. This warning message can be opt-out by setting environment variable `TS_JEST_DISABLE_VER_CHECKER`: + +**Linux/MacOS** + +``` +export TS_JEST_DISABLE_VER_CHECKER=true +``` + +**Windows** + +``` +set TS_JEST_DISABLE_VER_CHECKER=true +``` + +### Note + +As long as the environment variable `TS_JEST_DISABLE_VER_CHECKER` stays, the warning message will no longer show. +This can lead to unexpected errors due to the usage of incompatible versions' dependencies. Use this environment variable with precautions. diff --git a/website/versioned_docs/version-29.0/guides/esm-support.md b/website/versioned_docs/version-29.0/guides/esm-support.md new file mode 100644 index 0000000000..a36682263d --- /dev/null +++ b/website/versioned_docs/version-29.0/guides/esm-support.md @@ -0,0 +1,126 @@ +--- +id: esm-support +title: ESM Support +--- + +To use `ts-jest` with ESM support: + +- Check [ESM Jest documentation](https://jestjs.io/docs/en/ecmascript-modules). +- Enable [useESM](../getting-started/options/useESM) `true` for `ts-jest` config. +- Include `.ts` in [extensionsToTreatAsEsm](https://jestjs.io/docs/en/next/configuration#extensionstotreatasesm-arraystring) Jest config option. +- Ensure that `tsconfig` has `module` with value for ESM, e.g. `ES2015` or `ES2020` etc... + +### ESM presets + +There are also [3 presets](../getting-started/presets.md) to work with ESM. + +### Examples + +#### Manual configuration + +```js +// jest.config.js +module.exports = { + // [...] + extensionsToTreatAsEsm: ['.ts'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '": [ + "ts-jest", + { + "useESM": true + } + ] + } + } +} +``` + +#### Use ESM presets + +:::important + +Starting from **v28.0.0**, `ts-jest` will gradually switch to `esbuild`/`swc` to transform `ts` to `js`. To make the transition smoothly, we introduce `legacy` presets as a fallback when the new codes don't work yet. + +::: + +```js +// jest.config.js +module.exports = { + // [...] + preset: 'ts-jest/presets/default-esm', // or other ESM presets + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '": [ + "ts-jest", + { + "useESM": true + } + ] + } + } +} +``` + +#### Support `.mts` extension + +To work with `.mts` extension, besides the requirement to run Jest and `ts-jest` in ESM mode, there are a few extra requirements to be met: + +- `package.json` should contain `"type": "module"` +- A custom Jest resolver to resolve `.mjs` extension, see our simple one at https://github.com/kulshekhar/ts-jest/blob/main/e2e/native-esm-ts/mjs-resolver.ts +- `tsconfig.json` should at least contain these following options + +```json +{ + "compilerOptions": { + "module": "Node16", // or "NodeNext" + "target": "ESNext", + "moduleResolution": "Node16", // or "NodeNext" + "esModuleInterop": true + } +} +``` diff --git a/website/versioned_docs/version-29.0/guides/mock-es6-class.md b/website/versioned_docs/version-29.0/guides/mock-es6-class.md new file mode 100644 index 0000000000..ef9d91573f --- /dev/null +++ b/website/versioned_docs/version-29.0/guides/mock-es6-class.md @@ -0,0 +1,47 @@ +--- +id: mock-es6-class +title: Mock ES6 class +--- + +TypeScript is transpiling your ts file and your module is likely being imported using ES2015s import. +`const soundPlayer = require('./sound-player')`. Therefore creating an instance of the class that was exported as +a default will look like this: `new soundPlayer.default()`. However if you are mocking the class as suggested by the documentation. + +```js +jest.mock('./sound-player', () => { + return jest.fn().mockImplementation(() => { + return { playSoundFile: mockPlaySoundFile } + }) +}) +``` + +You will get the error + +``` +TypeError: sound_player_1.default is not a constructor +``` + +because `soundPlayer.default` does not point to a function. Your mock has to return an object which has a property default +that points to a function. + +```js +jest.mock('./sound-player', () => { + return { + default: jest.fn().mockImplementation(() => { + return { + playSoundFile: mockPlaySoundFile, + } + }), + } +}) +``` + +For named imports, like `import { OAuth2 } from './oauth'`, replace `default` with imported module name, `OAuth2` in this example: + +```js +jest.mock('./oauth', () => { + return { + OAuth2: ... // mock here + } +}) +``` diff --git a/website/versioned_docs/version-29.0/guides/react-native.md b/website/versioned_docs/version-29.0/guides/react-native.md new file mode 100644 index 0000000000..bbcf14776e --- /dev/null +++ b/website/versioned_docs/version-29.0/guides/react-native.md @@ -0,0 +1,56 @@ +--- +id: react-native +title: Using with React Native +--- + +To use `ts-jest` with React Native + TypeScript and Babel 7, you'll first need to follow [this tutorial](https://reactnative.dev/blog/2018/05/07/using-typescript-with-react-native). + +After that, some little modifications will be required as follows: + +### Babel config + +If you didn't yet, move any Babel config from `.babelrc` to `babel.config.js`. It should at least contain: + +```js +// babel.config.js +module.exports = { + presets: ['module:metro-react-native-babel-preset'], +} +``` + +### TypeScript Configuration + +Create a new `tsconfig.spec.json` at the root of your project with the following content + +```json +// tsconfig.spec.json +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "jsx": "react" + } +} +``` + +### Jest config + +In the same way that you moved Babel config, move Jest config from `jest` key of `package.json` to `jest.config.js`. It should look like this: + +```js +// jest.config.js +const { defaults: tsjPreset } = require('ts-jest/presets') + +module.exports = { + preset: 'react-native', + transform: { + '^.+\\.jsx$': 'babel-jest', + '^.+\\.tsx?$': [ + 'ts-jest', + { + tsconfig: 'tsconfig.spec.json', + }, + ], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], +} +``` diff --git a/website/versioned_docs/version-29.0/guides/troubleshooting.md b/website/versioned_docs/version-29.0/guides/troubleshooting.md new file mode 100644 index 0000000000..f416b3fab7 --- /dev/null +++ b/website/versioned_docs/version-29.0/guides/troubleshooting.md @@ -0,0 +1,7 @@ +--- +id: troubleshooting +title: Troubleshooting +--- + +You can check Jest [troubleshooting guide](https://jestjs.io/docs/en/troubleshooting) or visit `ts-jest` [troubleshooting +guide](https://github.com/kulshekhar/ts-jest/blob/main/TROUBLESHOOTING.md) diff --git a/website/versioned_docs/version-29.0/guides/using-with-monorepo.md b/website/versioned_docs/version-29.0/guides/using-with-monorepo.md new file mode 100644 index 0000000000..62cb36bf8e --- /dev/null +++ b/website/versioned_docs/version-29.0/guides/using-with-monorepo.md @@ -0,0 +1,8 @@ +--- +id: using-with-monorepo +title: Using with monorepo +--- + +To use `ts-jest` in a project with monorepo structure, you'll need to use [Jest projects configuration](https://jestjs.io/docs/next/configuration#projects-arraystring--projectconfig). + +When using Jest `projects` configuration, Jest will run `ts-jest` against each project which is defined in the configuration. diff --git a/website/versioned_docs/version-29.0/introduction.md b/website/versioned_docs/version-29.0/introduction.md new file mode 100644 index 0000000000..32b0b2d94e --- /dev/null +++ b/website/versioned_docs/version-29.0/introduction.md @@ -0,0 +1,16 @@ +--- +id: introduction +title: Introduction +description: A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript. +slug: / +--- + +`ts-jest` is a Jest [transformer](https://jestjs.io/docs/next/code-transformation#writing-custom-transformers) with source map support that lets you use Jest to test projects written in TypeScript. + +It supports all features of TypeScript including type-checking. [Read more about Babel7 + `preset-typescript` **vs** TypeScript (and `ts-jest`)](babel7-or-ts). + +:::important + +We are not doing semantic versioning and `23.10` is a re-write, run `npm i -D ts-jest@"<23.10.0"` to go back to the previous version + +::: diff --git a/website/versioned_docs/version-29.0/migration.md b/website/versioned_docs/version-29.0/migration.md new file mode 100644 index 0000000000..c55c9ee739 --- /dev/null +++ b/website/versioned_docs/version-29.0/migration.md @@ -0,0 +1,34 @@ +--- +id: migration +title: Migration from <=23.10 +--- + +You can use the `config:migrate` tool of `ts-jest` CLI if you're coming from an older version to help you migrate your Jest configuration. + +_If you're using `jest.config.js`:_ + +### NPM + +```sh +npx ts-jest config:migrate jest.config.js +``` + +### Yarn + +```sh +yarn ts-jest config:migrate jest.config.js +``` + +_If you're using `jest` config property of `package.json`:_ + +### NPM + +```sh +npx ts-jest config:migrate package.json +``` + +### Yarn + +```sh +yarn ts-jest config:migrate package.json +``` diff --git a/website/versioned_docs/version-29.0/processing.md b/website/versioned_docs/version-29.0/processing.md new file mode 100644 index 0000000000..bf881e2bd1 --- /dev/null +++ b/website/versioned_docs/version-29.0/processing.md @@ -0,0 +1,147 @@ +--- +id: processing +title: Processing flow +--- + +_These are internal technical documents. If you're not a contributor to `ts-jest`, but simply trying to use the library you'll find nothing of value here_ + +## Jest process + +```plantuml +start + +:require('file'); + +if (has a transform?) then (yes) +if (transformer has getCacheKey?) then (yes) +:transformer.getCacheKey(...); +else (no) +:use jest built-in; +endif + +if (in cache?) then (yes) +:use cache content; +else (no) +:transformer.process(...); +:update cache; +endif + +else (no) +endif + +:require(); + +end +``` + +## `ts-jest` process + +```plantuml +|processor| +start + +:tsJest.process(source); + +if (should stringify?) then (yes) +:json stringify; +-> update +source; + +else (no) +endif + +if (filename ends with .d.ts) then (yes) +:wipe source; +note right +no need to compile +definition files +end note + +else (no) + +|#Thistle|compiler (cached)| +if (isolated modules?) then (yes) +else (no) +:create and cache +ts lang service; +endif + +-> source; + +if (in persistent cache?) then (yes) +:update mem cache +from persistent cache; + +else (no) +if (isolated modules?) then (yes) +:compile with +transpileModule; +note left +files will be compiled +as isolated modules +end note + + else (no) + :compile with + service; + note left + make use of the service + created above and cached + + mem cache is used when + reading files + end note + + endif + + :custom AST + transformers; + note left + here is where hoisting of + jest.mock is done, as well as + user-defined transformations + based on config + end note + + -> compiled source; + + :fix source maps; + :update mem cache; + :update persistent cache; + +endif +|processor| + +-> update +source; + +endif + +if (should use babel?) then (yes) +:babelJest.process(source); +note left +calls babel-jest +processor +end note +-> update +source; + +else (no) +endif + +if (has afterProcess hook?) then (yes) +:call afterProcess hook; +-> update +source; +note left +if the hook returns +something it'll be +used as new source +end note + +endif + +:transformed source; + +end +``` diff --git a/website/versioned_sidebars/version-29.0-sidebars.json b/website/versioned_sidebars/version-29.0-sidebars.json new file mode 100644 index 0000000000..4e2b4d8a29 --- /dev/null +++ b/website/versioned_sidebars/version-29.0-sidebars.json @@ -0,0 +1,89 @@ +{ + "version-29.0-docs": [ + { + "collapsed": true, + "type": "category", + "label": "ts-jest", + "items": [ + { + "type": "doc", + "id": "version-29.0/introduction" + }, + { + "type": "doc", + "id": "version-29.0/processing" + }, + { + "type": "doc", + "id": "version-29.0/contributing" + } + ] + }, + { + "collapsed": false, + "type": "category", + "label": "Getting Started", + "items": [ + { + "type": "doc", + "id": "version-29.0/getting-started/installation" + }, + { + "type": "doc", + "id": "version-29.0/getting-started/presets" + }, + { + "type": "doc", + "id": "version-29.0/getting-started/options" + }, + { + "type": "doc", + "id": "version-29.0/getting-started/paths-mapping" + }, + { + "type": "doc", + "id": "version-29.0/getting-started/version-checking" + } + ] + }, + { + "collapsed": false, + "type": "category", + "label": "Guides", + "items": [ + { + "type": "doc", + "id": "version-29.0/guides/esm-support" + }, + { + "type": "doc", + "id": "version-29.0/guides/mock-es6-class" + }, + { + "type": "doc", + "id": "version-29.0/guides/react-native" + }, + { + "type": "doc", + "id": "version-29.0/guides/troubleshooting" + }, + { + "type": "doc", + "id": "version-29.0/guides/using-with-monorepo" + } + ] + }, + { + "type": "doc", + "id": "version-29.0/babel7-or-ts" + }, + { + "type": "doc", + "id": "version-29.0/migration" + }, + { + "type": "doc", + "id": "version-29.0/debugging" + } + ] +} diff --git a/website/versions.json b/website/versions.json index f539972e58..4553dc14d4 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,5 @@ [ + "29.0", "28.0", "27.1", "27.0",