feat: add support for TypeScript migration files

And add a guide to the documentation on how to set it up for NodeJS
This commit is contained in:
Joakim Carlstein 2023-12-20 12:06:20 +01:00 committed by Joakim Carlstein
parent 59eb90b8cb
commit 9a605a85f1
8 changed files with 163 additions and 14 deletions

View file

@ -0,0 +1,5 @@
---
'@emigrate/cli': minor
---
Add support for loading TypeScript migration files in the default loader

View file

@ -0,0 +1,5 @@
---
'@emigrate/cli': minor
---
Add a guide for running migration files written in TypeScript to the documentation

View file

@ -98,6 +98,15 @@ export default defineConfig({
}, },
], ],
}, },
{
label: 'Guides',
items: [
{
label: 'Using TypeScript',
link: '/guides/typescript/',
},
],
},
{ {
label: 'Plugins', label: 'Plugins',
items: [ items: [

View file

@ -72,7 +72,8 @@ The directory where the migration files are located. The given path should be ab
A module to import before running the migrations. This option can be specified multiple times. A module to import before running the migrations. This option can be specified multiple times.
Can for instance be used to load environment variables using [dotenv](https://github.com/motdotla/dotenv) with `--import dotenv/config`. Can for instance be used to load environment variables using [dotenv](https://github.com/motdotla/dotenv) with `--import dotenv/config`,
or for running migrations in NodeJS written in TypeScript with [tsx](https://github.com/privatenumber/tsx) (`--import tsx`), see the <Link href="/guides/typescript/">TypeScript guide</Link> for more information.
### `-s`, `--storage <name>` ### `-s`, `--storage <name>`

View file

@ -1,11 +0,0 @@
---
title: Example Guide
description: A guide in my new Starlight docs site.
---
Guides lead a user through a specific task they want to accomplish, often with a sequence of steps.
Writing a good guide requires thinking about what your users are trying to do.
## Further reading
- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework

View file

@ -0,0 +1,132 @@
---
title: Using TypeScript
description: A guide on how to support migration files written in TypeScript
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
import Link from '@components/Link.astro';
:::tip[Using Bun or Deno?]
If you are using [Bun](https://bun.sh) or [Deno](https://deno.land) you are already good to go as they both support TypeScript out of the box.
:::
You have at least the two following options to support running TypeScript migration files in NodeJS.
## Using `tsx`
If you want to be able to write and run migration files written in TypeScript the easiest way is to install the [`tsx`](https://github.com/privatenumber/tsx) package.
### Installing `tsx`
<Tabs>
<TabItem label="npm">
```bash
npm install tsx
```
</TabItem>
<TabItem label="pnpm">
```bash
pnpm add tsx
```
</TabItem>
<TabItem label="yarn">
```bash
yarn add tsx
```
</TabItem>
</Tabs>
:::note
You must install `tsx` as an ordinary dependency, not as a dev dependency,
in case you are pruning your development dependencies before deploying your application (which you should).
:::
### Loading TypeScript migrations
After installing `tsx` you can load it in two ways.
#### Via CLI
Using the <Link href="/commands/up/#-i---import-module">`--import`</Link> flag you can load `tsx` before running your migration files.
<Tabs>
<TabItem label="npm">
```bash
npx emigrate up --import tsx
```
</TabItem>
<TabItem label="pnpm">
```bash
pnpm emigrate up --import tsx
```
</TabItem>
<TabItem label="yarn">
```bash
yarn emigrate up --import tsx
```
</TabItem>
</Tabs>
#### Via configuration file
You can also directly import `tsx` in your configuration file.
```js title="emigrate.config.js" {1}
import 'tsx';
export default {
// ...
};
```
Then you can run your migration files as usual:
<Tabs>
<TabItem label="npm">
```bash
npx emigrate up
```
</TabItem>
<TabItem label="pnpm">
```bash
pnpm emigrate up
```
</TabItem>
<TabItem label="yarn">
```bash
yarn emigrate up
```
</TabItem>
</Tabs>
## Building TypeScript migrations
If you don't want to have `tsx` (or similar) as a dependency included in your production environment then
you can build your TypeScript migration files using the [`tsc`](https://www.typescriptlang.org/docs/handbook/compiler-options.html) compiler or
some other tool that are already part of your build process when transpiling your TypeScript code to JavaScript.
Assume that you have all of your migrations in a `src/migrations` directory and you have built them to a `dist/migrations` directory.
Then you can run your migration files by pointing to the `dist/migrations` directory:
<Tabs>
<TabItem label="npm">
```bash
npx emigrate up -d dist/migrations
```
</TabItem>
<TabItem label="pnpm">
```bash
pnpm emigrate up -d dist/migrations
```
</TabItem>
<TabItem label="yarn">
```bash
yarn emigrate up -d dist/migrations
```
</TabItem>
</Tabs>
:::note
If you're mixing languages for your migration files, e.g. you have both `.sql` and `.ts` files in `src/migrations`, make sure that they are all copied to the destination directory if not part of the TypeScript build process.
:::

View file

@ -3,8 +3,9 @@ title: Default Loader Plugin
--- ---
import { Tabs, TabItem } from '@astrojs/starlight/components'; import { Tabs, TabItem } from '@astrojs/starlight/components';
import Link from '@components/Link.astro';
The default loader plugin is responsible for importing migration files written in JavaScript. The default loader plugin is responsible for importing migration files written in JavaScript or TypeScript.
Migration files can be written using either CommonJS or ES Modules. Migration files can be written using either CommonJS or ES Modules.
## Supported extensions ## Supported extensions
@ -14,6 +15,13 @@ The default loader plugin supports the following extensions:
* `.js` - either CommonJS or ES Modules depending on your package.json's [`type` field](https://nodejs.org/api/packages.html#type) * `.js` - either CommonJS or ES Modules depending on your package.json's [`type` field](https://nodejs.org/api/packages.html#type)
* `.cjs` - CommonJS * `.cjs` - CommonJS
* `.mjs` - ES Modules * `.mjs` - ES Modules
* `.ts` - either CommonJS or ES Modules written in TypeScript
* `.cts` - CommonJS written in TypeScript
* `.mts` - ES Modules written in TypeScript
:::note
To enable TypeScript support in NodeJS you also need to follow the <Link href="/guides/typescript/">TypeScript setup guide</Link>.
:::
## Supported exports ## Supported exports

View file

@ -17,7 +17,7 @@ const promisifyIfNeeded = <T extends Function>(fn: T) => {
}; };
const loaderJs: LoaderPlugin = { const loaderJs: LoaderPlugin = {
loadableExtensions: ['.js', '.cjs', '.mjs'], loadableExtensions: ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts'],
async loadMigration(migration) { async loadMigration(migration) {
const migrationModule: unknown = await import(migration.filePath); const migrationModule: unknown = await import(migration.filePath);