mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
docs: collect all migrations documentation in one place (#11674)
* docs: collect all migrations documentation in one place * links * vite * fic * link to vite project * Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * ai review suggestions * docs: collect all migrations documentation in one place * links * vite * fic * link to vite project * ai review suggestions * Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * format * single redirect * fix bad merge * auto-run * restore cli * add migration create * fix postgresql syntax --------- Co-authored-by: Giorgio Boa <35845425+gioboa@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
parent
3ac605359d
commit
b639d33aee
@ -148,7 +148,7 @@ For more information see the [Postgres documentation](https://www.postgresql.org
|
||||
|
||||
TypeORM does not support some index options and definitions (e.g. `lower`, `pg_trgm`) due to many database-specific differences and multiple
|
||||
issues with getting information about existing database indices and synchronizing them automatically. In such cases you should create the index manually
|
||||
(for example, in migrations) with any index signature you want. To make TypeORM ignore these indices during synchronization, use `synchronize: false`
|
||||
(for example, in [the migrations](../migrations/01-why.md)) with any index signature you want. To make TypeORM ignore these indices during synchronization, use `synchronize: false`
|
||||
option on the `@Index` decorator.
|
||||
|
||||
For example, you create an index with case-insensitive comparison:
|
||||
|
||||
@ -124,66 +124,15 @@ typeorm subscriber:create path-to-subscriber-dir/subscriber
|
||||
|
||||
Learn more about [Subscribers](./4-listeners-and-subscribers.md).
|
||||
|
||||
## Create a new migration
|
||||
## Manage migrations
|
||||
|
||||
You can create a new migration using CLI:
|
||||
* `typeorm migration:create` - [create](../migrations/03-creating.md) empty migration
|
||||
* `typeorm migration:generate` - [generate](../migrations/04-generating.md) migration comparing entities with actual database schema
|
||||
* `typeorm migration:run` - [execute](../migrations/05-executing.md) all migrations
|
||||
* `typeorm migration:revert` - [revert](../migrations/06-reverting.md) last migration
|
||||
* `typeorm migration:show` - [list](../migrations/07-status.md) all migrations with their execution status
|
||||
|
||||
```shell
|
||||
typeorm migration:create path-to-migrations-dir/migrationName
|
||||
```
|
||||
|
||||
Learn more about [Migrations](./1-migrations.md).
|
||||
|
||||
## Generate a migration from existing table schema
|
||||
|
||||
Automatic migration generation creates a new migration file
|
||||
and writes all sql queries that must be executed to update the database.
|
||||
|
||||
If no there were no changes generated, the command will exit with code 1.
|
||||
|
||||
```shell
|
||||
typeorm migration:generate path/to/Migration -d path/to/datasource
|
||||
```
|
||||
|
||||
The rule of thumb is to generate a migration after each entity change.
|
||||
the -d argument value should specify the path where your DataSource instance is defined.
|
||||
You can specify the path and name of the migration with the first argument.
|
||||
|
||||
Learn more about [Migrations](./1-migrations.md).
|
||||
|
||||
## Run migrations
|
||||
|
||||
To execute all pending migrations use following command:
|
||||
|
||||
```shell
|
||||
typeorm migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
Learn more about [Migrations](./1-migrations.md).
|
||||
|
||||
## Revert migrations
|
||||
|
||||
To revert the most recently executed migration use the following command:
|
||||
|
||||
```shell
|
||||
typeorm migration:revert -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
This command will undo only the last executed migration.
|
||||
You can execute this command multiple times to revert multiple migrations.
|
||||
Learn more about [Migrations](./1-migrations.md).
|
||||
|
||||
## Show migrations
|
||||
|
||||
To show all migrations and whether they've been run or not use following command:
|
||||
|
||||
```shell
|
||||
typeorm migration:show -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
[X] = Migration has been ran
|
||||
|
||||
[ ] = Migration is pending/unapplied
|
||||
Learn more about [Migrations](../migrations/01-why.md).
|
||||
|
||||
## Sync database schema
|
||||
|
||||
|
||||
@ -28,12 +28,6 @@ Different RDBMS-es have their own specific options.
|
||||
Example: `subscribers: [PostSubscriber, AppSubscriber, "subscriber/*.js", "modules/**/subscriber/*.js"]`.
|
||||
Learn more about [Subscribers](../advanced-topics/4-listeners-and-subscribers.md).
|
||||
|
||||
- `migrations` - Migrations to be loaded and used for this data source.
|
||||
It accepts both migration classes and directories from which to load.
|
||||
Directories support glob patterns.
|
||||
Example: `migrations: [FirstMigration, SecondMigration, "migration/*.js", "modules/**/migration/*.js"]`.
|
||||
Learn more about [Migrations](../advanced-topics/1-migrations.md).
|
||||
|
||||
- `logging` - Indicates if logging is enabled or not.
|
||||
If set to `true` then query and error logging will be enabled.
|
||||
You can also specify different types of logging to be enabled, for example `["query", "error", "schema"]`.
|
||||
@ -67,13 +61,13 @@ Different RDBMS-es have their own specific options.
|
||||
Note that for MongoDB database it does not create schema, because MongoDB is schemaless.
|
||||
Instead, it syncs just by creating indices.
|
||||
|
||||
- `migrationsRun` - Indicates if migrations should be auto run on every application launch.
|
||||
As an alternative, you can use CLI and run migration:run command.
|
||||
- `migrations` - [Migrations](../migrations/01-why.md) to be loaded and used for this data source
|
||||
|
||||
- `migrationsTableName` - Name of the table in the database which is going to contain information about executed migrations.
|
||||
By default, this table is called "migrations".
|
||||
- `migrationsRun` - Indicates if [migrations](../migrations/01-why.md) should be auto-run on every application launch.
|
||||
|
||||
- `migrationsTransactionMode` - Control transactions for migrations (default: `all`), can be one of `all` | `none` | `each`
|
||||
- `migrationsTableName` - Name of the table in the database which is going to contain information about executed [migrations](../migrations/01-why.md).
|
||||
|
||||
- `migrationsTransactionMode` - Controls transaction mode when running [migrations](../migrations/01-why.md).
|
||||
|
||||
- `metadataTableName` - Name of the table in the database which is going to contain information about table metadata.
|
||||
By default, this table is called "typeorm_metadata".
|
||||
@ -85,7 +79,7 @@ Different RDBMS-es have their own specific options.
|
||||
eg. `.where("user.firstName = :search OR user.lastName = :search")` becomes `WHERE (user.firstName = ? OR user.lastName = ?)` instead of `WHERE user.firstName = ? OR user.lastName = ?`
|
||||
|
||||
- `invalidWhereValuesBehavior` - Controls how null and undefined values are handled in where conditions across all TypeORM operations (find operations, query builders, repository methods).
|
||||
|
||||
|
||||
- `null` behavior options:
|
||||
- `'ignore'` (default) - skips null properties
|
||||
- `'sql-null'` - transforms null to SQL NULL
|
||||
|
||||
@ -11,7 +11,7 @@ You can create a view entity by defining a new class and mark it with `@ViewEnti
|
||||
- `database` - database name in selected DB server.
|
||||
- `schema` - schema name.
|
||||
- `expression` - view definition. **Required parameter**.
|
||||
- `dependsOn` - List of other views on which the current views depends. If your view uses another view in its definition, you can add it here so that migrations are generated in the correct order.
|
||||
- `dependsOn` - List of other views on which the current views depends. If your view uses another view in its definition, you can add it here so that [migrations](../migrations/01-why.md) are generated in the correct order.
|
||||
|
||||
`expression` can be string with properly escaped columns and tables, depend on database used (postgres in example):
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ TypeORM is highly influenced by other ORMs, such as [Hibernate](http://hibernate
|
||||
- Cascades.
|
||||
- Indices.
|
||||
- Transactions.
|
||||
- Migrations and automatic migrations generation.
|
||||
- [Migrations](../migrations/01-why.md) with automatic generation.
|
||||
- Connection pooling.
|
||||
- Replication.
|
||||
- Using multiple database instances.
|
||||
@ -1195,7 +1195,7 @@ There are several extensions that simplify working with TypeORM and integrating
|
||||
- ER Diagram generator - [typeorm-uml](https://github.com/eugene-manuilov/typeorm-uml/)
|
||||
- another ER Diagram generator - [erdia](https://www.npmjs.com/package/erdia/)
|
||||
- Create, drop and seed database - [typeorm-extension](https://github.com/tada5hi/typeorm-extension)
|
||||
- Automatically update `data-source.ts` after generating migrations/entities - [typeorm-codebase-sync](https://www.npmjs.com/package/typeorm-codebase-sync)
|
||||
- Automatically update `data-source.ts` after generating [migrations](../migrations/01-why.md)/entities - [typeorm-codebase-sync](https://www.npmjs.com/package/typeorm-codebase-sync)
|
||||
- Easy manipulation of `relations` objects - [typeorm-relations](https://npmjs.com/package/typeorm-relations)
|
||||
- Automatically generate `relations` based on a GraphQL query - [typeorm-relations-graphql](https://npmjs.com/package/typeorm-relations-graphql)
|
||||
|
||||
|
||||
@ -178,7 +178,7 @@ module.exports = {
|
||||
|
||||
### Bundling Migration Files
|
||||
|
||||
By default Webpack tries to bundle everything into one file. This can be problematic when your project has migration files which are meant to be executed after bundled code is deployed to production. To make sure all your migrations can be recognized and executed by TypeORM, you may need to use "Object Syntax" for the `entry` configuration for the migration files only.
|
||||
By default Webpack tries to bundle everything into one file. This can be problematic when your project has migration files which are meant to be executed after bundled code is deployed to production. To make sure all your [migrations](../migrations/01-why.md) can be recognized and executed by TypeORM, you may need to use "Object Syntax" for the `entry` configuration for the migration files only.
|
||||
|
||||
```javascript
|
||||
const glob = require("glob")
|
||||
@ -210,7 +210,7 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
Also, since Webpack 4, when using `mode: 'production'`, files are optimized by default which includes mangling your code in order to minimize file sizes. This breaks the migrations because TypeORM relies on their names to determine which has already been executed. You may disable minimization completely by adding:
|
||||
Also, since Webpack 4, when using `mode: 'production'`, files are optimized by default which includes mangling your code in order to minimize file sizes. This breaks the [migrations](../migrations/01-why.md) because TypeORM relies on their names to determine which has already been executed. You may disable minimization completely by adding:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
@ -256,93 +256,6 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
## How to use Vite for the backend?
|
||||
|
||||
Using TypeORM in a Vite project is pretty straight forward. However, when you use migrations, you will run into "...migration name is wrong. Migration class name should have a
|
||||
JavaScript timestamp appended." errors when running the production build.
|
||||
On production builds, files are [optimized by default](https://vite.dev/config/build-options#build-minify) which includes mangling your code in order to minimize file sizes.
|
||||
|
||||
You have 3 options to mitigate this. The 3 options are shown belown as diff to this basic "vite.config.ts"
|
||||
|
||||
```typescript
|
||||
import legacy from "@vitejs/plugin-legacy"
|
||||
import vue from "@vitejs/plugin-vue"
|
||||
import path from "path"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
build: {
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Option 1: Disable minify
|
||||
|
||||
This is the most crude option and will result in significantly larger files. Add `build.minify = false` to your config.
|
||||
|
||||
```diff
|
||||
--- basic vite.config.ts
|
||||
+++ disable minify vite.config.ts
|
||||
@@ -7,6 +7,7 @@
|
||||
export default defineConfig({
|
||||
build: {
|
||||
sourcemap: true,
|
||||
+ minify: false,
|
||||
},
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
```
|
||||
|
||||
### Option 2: Disable esbuild minify identifiers
|
||||
|
||||
Vite uses esbuild as the default minifier. You can disable mangling of identifiers by adding `esbuild.minifyIdentifiers = false` to your config.
|
||||
This will result in smaller file sizes, but depending on your code base you will get diminishing returns as all identifiers will be kept at full length.
|
||||
|
||||
```diff
|
||||
--- basic vite.config.ts
|
||||
+++ disable esbuild minify identifiers vite.config.ts
|
||||
@@ -8,6 +8,7 @@
|
||||
build: {
|
||||
sourcemap: true,
|
||||
},
|
||||
+ esbuild: { minifyIdentifiers: false },
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
```
|
||||
|
||||
### Option 3: Use terser as minifier while keeping only the migration class names
|
||||
|
||||
Vite supports using terser as minifier. Terser is slower then esbuild, but offers more fine grained control over what to minify.
|
||||
Add `minify: 'terser'` with `terserOptions.mangle.keep_classnames: /^Migrations\d+$/` and `terserOptions.compress.keep_classnames: /^Migrations\d+$/` to your config.
|
||||
These options will make sure classnames that start with "Migrations" and end with numbers are not renamed during minification.
|
||||
|
||||
Make sure terser is available as dev dependency in your project: `npm add -D terser`.
|
||||
|
||||
```diff
|
||||
--- basic vite.config.ts
|
||||
+++ terser keep migration class names vite.config.ts
|
||||
@@ -7,6 +7,11 @@
|
||||
export default defineConfig({
|
||||
build: {
|
||||
sourcemap: true,
|
||||
+ minify: 'terser',
|
||||
+ terserOptions: {
|
||||
+ mangle: { keep_classnames: /^Migrations\d+$/ },
|
||||
+ compress: { keep_classnames: /^Migrations\d+$/ },
|
||||
+ },
|
||||
},
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
```
|
||||
|
||||
## How to use TypeORM in ESM projects?
|
||||
|
||||
Make sure to add `"type": "module"` in the `package.json` of your project so TypeORM will know to use `import( ... )` on files.
|
||||
|
||||
42
docs/docs/migrations/01-why.md
Normal file
42
docs/docs/migrations/01-why.md
Normal file
@ -0,0 +1,42 @@
|
||||
# How migrations work?
|
||||
|
||||
Once you get into production you'll need to synchronize model changes into the database.
|
||||
Typically, it is unsafe to use `synchronize: true` for schema synchronization on production once
|
||||
you get data in your database. Here is where migrations come to help.
|
||||
|
||||
A migration is just a single file with SQL queries to update a database schema
|
||||
and apply new changes to an existing database.
|
||||
|
||||
Let's say you already have a database and a `Post` entity:
|
||||
|
||||
```typescript
|
||||
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm"
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
title: string
|
||||
|
||||
@Column()
|
||||
text: string
|
||||
}
|
||||
```
|
||||
|
||||
And your entity worked in production for months without any changes.
|
||||
You have thousands of posts in your database.
|
||||
|
||||
Now you need to make a new release and rename `title` to `name`.
|
||||
What would you do?
|
||||
|
||||
You need to create a new migration with the following SQL query (PostgreSQL dialect):
|
||||
|
||||
```sql
|
||||
ALTER TABLE "post" RENAME COLUMN "title" TO "name";
|
||||
```
|
||||
|
||||
Once you run this SQL query your database schema is ready to work with your new codebase.
|
||||
TypeORM provides a place where you can write such sql queries and run them when needed.
|
||||
This place is called "migrations".
|
||||
71
docs/docs/migrations/02-setup.md
Normal file
71
docs/docs/migrations/02-setup.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Setup
|
||||
|
||||
Before working with migrations you need to setup your [DataSource](../data-source/1-data-source.md) options properly:
|
||||
|
||||
```ts
|
||||
export default new DataSource({
|
||||
// basic setup
|
||||
synchronize: false,
|
||||
migrations: [ /*...*/ ],
|
||||
|
||||
// optional
|
||||
migrationsRun: false,
|
||||
migrationsTableName: 'migrations',
|
||||
migrationsTransactionMode: 'all'
|
||||
|
||||
// other options...
|
||||
})
|
||||
```
|
||||
|
||||
## `synchronise`
|
||||
|
||||
Turning off automatic schema synchronisation is essential for working with migrations. Otherwise they would make no sense.
|
||||
|
||||
## `migrations`
|
||||
|
||||
Defines list of migrations that need to be loaded by TypeORM. It accepts both migration classes and directories from which to load.
|
||||
|
||||
The easiest is to specify the directory where your migration files are located (glob patterns are supported):
|
||||
|
||||
```ts
|
||||
migrations: [__dirname + '/migration/**/*{.js,.ts}']
|
||||
```
|
||||
|
||||
Defining both `.js` and `.ts` extensions would allow you to run migrations in development and from compiled to JavaScript for production (eg. from Docker image).
|
||||
|
||||
Alternatively you could also specify exact classes to get more fine grained control:
|
||||
|
||||
```ts
|
||||
import FirstMigration from 'migrations/TIMESTAMP-first-migration'
|
||||
import SecondMigration from 'migrations/TIMESTAMP-second-migration'
|
||||
|
||||
export default new DataSource({
|
||||
migrations: [FirstMigration, SecondMigration]
|
||||
})
|
||||
```
|
||||
|
||||
but it also requires more manual work and can be error prone.
|
||||
|
||||
- `migrationsRun` - Indicates if [migrations](../migrations/01-why.md) should be auto-run on every application launch.
|
||||
|
||||
## Optional settings
|
||||
|
||||
### `migrationsRun`
|
||||
|
||||
Indicates if migrations should be auto-run on every application launch. Default: `false`
|
||||
|
||||
### `migrationsTableName`
|
||||
|
||||
You might want to specify the name of the table that will store information about executed migrations. By default it is called `'migrations'`.
|
||||
|
||||
```ts
|
||||
migrationsTableName: 'some_custom_migrations_table'
|
||||
```
|
||||
|
||||
### `migrationsTransactionMode`
|
||||
|
||||
Controls transaction mode when running migrations. Possible options are:
|
||||
|
||||
- `all` (_default_) - wraps migrations run into a single transaction
|
||||
- `none`
|
||||
- `each`
|
||||
56
docs/docs/migrations/03-creating.md
Normal file
56
docs/docs/migrations/03-creating.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Creating manually
|
||||
|
||||
You can create a new migration using CLI by specifying the name and location of the migration:
|
||||
|
||||
```shell
|
||||
npx typeorm migration:create <path/to/migrations>/<migration-name>
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```shell
|
||||
npx typeorm migration:create src/db/migrations/post-refactoring
|
||||
```
|
||||
|
||||
After you run the command you can see a new file generated in the `src/db/migrations` directory named `{TIMESTAMP}-post-refactoring.ts` where `{TIMESTAMP}` is the current timestamp when the migration was generated.
|
||||
|
||||
Now you can open the file and add your migration sql queries there. You should see the following content inside your migration:
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
async up(queryRunner: QueryRunner): Promise<void> {}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {}
|
||||
}
|
||||
```
|
||||
|
||||
There are two methods you must fill with your migration code: `up` and `down`.
|
||||
`up` has to contain the code you need to perform the migration.
|
||||
`down` has to revert whatever `up` changed.
|
||||
`down` method is used to revert the last migration.
|
||||
|
||||
Inside both `up` and `down` you have a `QueryRunner` object.
|
||||
All database operations are executed using this object.
|
||||
Learn more about [query runner](../query-runner.md).
|
||||
|
||||
Let's see what the migration looks like with our `Post` changes:
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" RENAME COLUMN "title" TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" RENAME COLUMN "name" TO "title"`,
|
||||
) // reverts things made in "up" method
|
||||
}
|
||||
}
|
||||
```
|
||||
117
docs/docs/migrations/04-generating.md
Normal file
117
docs/docs/migrations/04-generating.md
Normal file
@ -0,0 +1,117 @@
|
||||
# Generating
|
||||
|
||||
TypeORM is able to automatically generate migration files based on the changes you made to the entities, comparing them with existing database schema on the server.
|
||||
|
||||
Automatic migration generation creates a new migration file and writes all sql queries that must be executed to update the database. If no changes are detected, the command will exit with code `1`.
|
||||
|
||||
Let's say you have a `Post` entity with a `title` column, and you have changed the name `title` to `name`.
|
||||
|
||||
You can generate migration with of the following command:
|
||||
|
||||
```shell
|
||||
typeorm migration:generate -d <path/to/datasource> <migration-name>
|
||||
```
|
||||
|
||||
The `-d` argument value should specify the path where your [DataSource](../data-source/1-data-source.md) instance is defined.
|
||||
|
||||
Alternatively you can also specify name with `--name` param
|
||||
|
||||
```shell
|
||||
typeorm migration:generate -- -d <path/to/datasource> --name=<migration-name>
|
||||
```
|
||||
|
||||
or use a full path:
|
||||
|
||||
```shell
|
||||
typeorm migration:generate -d <path/to/datasource> <path/to/migrations>/<migration-name>
|
||||
```
|
||||
|
||||
Assuming you used `post-refactoring` as a name, it will generate a new file called `{TIMESTAMP}-post-refactoring.ts` with the following content:
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can also output your migrations as Javascript files using the `o` (alias for `--outputJs`) flag. This is useful for Javascript only projects in which TypeScript additional packages are not installed. This command, will generate a new migration file `{TIMESTAMP}-PostRefactoring.js` with the following content:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @typedef {import('typeorm').MigrationInterface} MigrationInterface
|
||||
* @typedef {import('typeorm').QueryRunner} QueryRunner
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @implements {MigrationInterface}
|
||||
*/
|
||||
module.exports = class PostRefactoringTIMESTAMP {
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By default, it generates CommonJS JavaScript code with the `o` (alias for `--outputJs`) flag, but you can also generate ESM code with the `esm` flag. This is useful for Javascript projects that use ESM:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @typedef {import('typeorm').MigrationInterface} MigrationInterface
|
||||
* @typedef {import('typeorm').QueryRunner} QueryRunner
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @implements {MigrationInterface}
|
||||
*/
|
||||
export class PostRefactoringTIMESTAMP {
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See, you don't need to write the queries on your own.
|
||||
|
||||
The rule of thumb for generating migrations is that you generate them after **each** change you made to your models. To apply multi-line formatting to your generated migration queries, use the `p` (alias for `--pretty`) flag.
|
||||
29
docs/docs/migrations/05-executing.md
Normal file
29
docs/docs/migrations/05-executing.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Executing and reverting
|
||||
|
||||
Once you have a migration to run on production, you can run them using a CLI command:
|
||||
|
||||
```shell
|
||||
typeorm migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
**`typeorm migration:create` and `typeorm migration:generate` will create `.ts` files, unless you use the `o` flag (see more in [Generating migrations](04-generating.md)). The `migration:run` and `migration:revert` commands only work on `.js` files. Thus the typescript files need to be compiled before running the commands.** Alternatively, you can use `ts-node` with `typeorm` to run `.ts` migration files.
|
||||
|
||||
Example with `ts-node`:
|
||||
|
||||
```shell
|
||||
npx typeorm-ts-node-commonjs migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
Example with `ts-node` in ESM projects:
|
||||
|
||||
```shell
|
||||
npx typeorm-ts-node-esm migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
```shell
|
||||
npx typeorm-ts-node-esm migration:generate ./src/migrations/update-post-table -d ./src/data-source.ts
|
||||
```
|
||||
|
||||
This command will execute all pending migrations and run them in a sequence ordered by their timestamps.
|
||||
This means all sql queries written in the `up` methods of your created migrations will be executed.
|
||||
That's all! Now you have your database schema up-to-date.
|
||||
11
docs/docs/migrations/06-reverting.md
Normal file
11
docs/docs/migrations/06-reverting.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Reverting
|
||||
|
||||
If for some reason you want to revert the changes, you can run:
|
||||
|
||||
```shell
|
||||
typeorm migration:revert -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
This command will execute `down` in the latest executed migration.
|
||||
|
||||
If you need to revert multiple migrations you must call this command multiple times.
|
||||
11
docs/docs/migrations/07-status.md
Normal file
11
docs/docs/migrations/07-status.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Status
|
||||
|
||||
To show all migrations and whether they've been run or not use following command:
|
||||
|
||||
```shell
|
||||
typeorm migration:show -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
[X] = Migration has been ran
|
||||
|
||||
[ ] = Migration is pending/unapplied
|
||||
42
docs/docs/migrations/08-faking.md
Normal file
42
docs/docs/migrations/08-faking.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Faking Migrations and Rollbacks
|
||||
|
||||
You can also fake run a migration using the `--fake` flag (`-f` for short). This will add the migration
|
||||
to the migrations table without running it. This is useful for migrations created after manual changes
|
||||
have already been made to the database or when migrations have been run externally
|
||||
(e.g. by another tool or application), and you still would like to keep a consistent migration history.
|
||||
|
||||
```shell
|
||||
typeorm migration:run -d path-to-datasource-config --fake
|
||||
```
|
||||
|
||||
This is also possible with rollbacks.
|
||||
|
||||
```shell
|
||||
typeorm migration:revert -d path-to-datasource-config --fake
|
||||
```
|
||||
|
||||
### Transaction modes
|
||||
|
||||
By default, TypeORM will run all your migrations within a single wrapping transaction.
|
||||
This corresponds to the `--transaction all` flag.
|
||||
If you require more fine grained transaction control, you can use the `--transaction each` flag to wrap every migration individually, or the `--transaction none` flag to opt out of wrapping the migrations in transactions altogether.
|
||||
|
||||
In addition to these flags, you can also override the transaction behavior on a per-migration basis by setting the `transaction` property on the `MigrationInterface` to `true` or `false`. This only works in the `each` or `none` transaction mode.
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class AddIndexTIMESTAMP implements MigrationInterface {
|
||||
transaction = false
|
||||
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX CONCURRENTLY post_names_idx ON post(name)`,
|
||||
)
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX CONCURRENTLY post_names_idx`)
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -1,348 +1,7 @@
|
||||
# Migrations
|
||||
|
||||
## How migrations work?
|
||||
|
||||
Once you get into production you'll need to synchronize model changes into the database.
|
||||
Typically, it is unsafe to use `synchronize: true` for schema synchronization on production once
|
||||
you get data in your database. Here is where migrations come to help.
|
||||
|
||||
A migration is just a single file with sql queries to update a database schema
|
||||
and apply new changes to an existing database.
|
||||
|
||||
Let's say you already have a database and a post entity:
|
||||
|
||||
```typescript
|
||||
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm"
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
title: string
|
||||
|
||||
@Column()
|
||||
text: string
|
||||
}
|
||||
```
|
||||
|
||||
And your entity worked in production for months without any changes.
|
||||
You have thousands of posts in your database.
|
||||
|
||||
Now you need to make a new release and rename `title` to `name`.
|
||||
What would you do?
|
||||
|
||||
You need to create a new migration with the following SQL query (postgres dialect):
|
||||
|
||||
```sql
|
||||
ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name";
|
||||
```
|
||||
|
||||
Once you run this SQL query your database schema is ready to work with your new codebase.
|
||||
TypeORM provides a place where you can write such sql queries and run them when needed.
|
||||
This place is called "migrations".
|
||||
|
||||
## Creating a new migration
|
||||
|
||||
**Pre-requisites**: [Installing CLI](./6-using-cli.md#installing-cli)
|
||||
|
||||
Before creating a new migration you need to setup your data source options properly:
|
||||
|
||||
```ts
|
||||
import { DataSource } from "typeorm"
|
||||
|
||||
export default new DataSource({
|
||||
type: "mysql",
|
||||
host: "localhost",
|
||||
port: 3306,
|
||||
username: "test",
|
||||
password: "test",
|
||||
database: "test",
|
||||
entities: [
|
||||
/*...*/
|
||||
],
|
||||
migrations: [
|
||||
/*...*/
|
||||
],
|
||||
migrationsTableName: "custom_migration_table",
|
||||
})
|
||||
```
|
||||
|
||||
Here we setup two options:
|
||||
|
||||
- `"migrationsTableName": "migrations"` - Specify this option only if you need the migration table name to be different from `"migrations"`.
|
||||
- `"migrations": [/*...*/]` - list of migrations that need to be loaded by TypeORM
|
||||
|
||||
Once you setup the connection options you can create a new migration using CLI:
|
||||
|
||||
```shell
|
||||
typeorm migration:create ./path-to-migrations-dir/PostRefactoring
|
||||
```
|
||||
|
||||
Here, `PostRefactoring` is the name of the migration - you can specify any name you want.
|
||||
After you run the command you can see a new file generated in the "migration" directory
|
||||
named `{TIMESTAMP}-PostRefactoring.ts` where `{TIMESTAMP}` is the current timestamp when the migration was generated.
|
||||
Now you can open the file and add your migration sql queries there.
|
||||
|
||||
You should see the following content inside your migration:
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
async up(queryRunner: QueryRunner): Promise<void> {}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {}
|
||||
}
|
||||
```
|
||||
|
||||
There are two methods you must fill with your migration code: `up` and `down`.
|
||||
`up` has to contain the code you need to perform the migration.
|
||||
`down` has to revert whatever `up` changed.
|
||||
`down` method is used to revert the last migration.
|
||||
|
||||
Inside both `up` and `down` you have a `QueryRunner` object.
|
||||
All database operations are executed using this object.
|
||||
Learn more about [query runner](../query-runner.md).
|
||||
|
||||
Let's see what the migration looks like with our `Post` changes:
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" RENAME COLUMN "title" TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" RENAME COLUMN "name" TO "title"`,
|
||||
) // reverts things made in "up" method
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Running and reverting migrations
|
||||
|
||||
Once you have a migration to run on production, you can run them using a CLI command:
|
||||
|
||||
```shell
|
||||
typeorm migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
**`typeorm migration:create` and `typeorm migration:generate` will create `.ts` files, unless you use the `o` flag (see more in [Generating migrations](#generating-migrations)). The `migration:run` and `migration:revert` commands only work on `.js` files. Thus the typescript files need to be compiled before running the commands.** Alternatively, you can use `ts-node` with `typeorm` to run `.ts` migration files.
|
||||
|
||||
Example with `ts-node`:
|
||||
|
||||
```shell
|
||||
npx typeorm-ts-node-commonjs migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
Example with `ts-node` in ESM projects:
|
||||
|
||||
```shell
|
||||
npx typeorm-ts-node-esm migration:run -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
```shell
|
||||
npx typeorm-ts-node-esm migration:generate ./src/migrations/update-post-table -d ./src/data-source.ts
|
||||
```
|
||||
|
||||
This command will execute all pending migrations and run them in a sequence ordered by their timestamps.
|
||||
This means all sql queries written in the `up` methods of your created migrations will be executed.
|
||||
That's all! Now you have your database schema up-to-date.
|
||||
|
||||
If for some reason you want to revert the changes, you can run:
|
||||
|
||||
```shell
|
||||
typeorm migration:revert -- -d path-to-datasource-config
|
||||
```
|
||||
|
||||
This command will execute `down` in the latest executed migration.
|
||||
If you need to revert multiple migrations you must call this command multiple times.
|
||||
|
||||
### Faking Migrations and Rollbacks
|
||||
|
||||
You can also fake run a migration using the `--fake` flag (`-f` for short). This will add the migration
|
||||
to the migrations table without running it. This is useful for migrations created after manual changes
|
||||
have already been made to the database or when migrations have been run externally
|
||||
(e.g. by another tool or application), and you still would like to keep a consistent migration history.
|
||||
|
||||
```shell
|
||||
typeorm migration:run -d path-to-datasource-config --fake
|
||||
```
|
||||
|
||||
This is also possible with rollbacks.
|
||||
|
||||
```shell
|
||||
typeorm migration:revert -d path-to-datasource-config --fake
|
||||
```
|
||||
|
||||
### Transaction modes
|
||||
|
||||
By default, TypeORM will run all your migrations within a single wrapping transaction.
|
||||
This corresponds to the `--transaction all` flag.
|
||||
If you require more fine grained transaction control, you can use the `--transaction each` flag to wrap every migration individually, or the `--transaction none` flag to opt out of wrapping the migrations in transactions altogether.
|
||||
|
||||
In addition to these flags, you can also override the transaction behavior on a per-migration basis by setting the `transaction` property on the `MigrationInterface` to `true` or `false`. This only works in the `each` or `none` transaction mode.
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class AddIndexTIMESTAMP implements MigrationInterface {
|
||||
transaction = false
|
||||
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX CONCURRENTLY post_names_idx ON post(name)`,
|
||||
)
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX CONCURRENTLY post_names_idx`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Generating migrations
|
||||
|
||||
TypeORM is able to automatically generate migration files with schema changes you made.
|
||||
|
||||
Let's say you have a `Post` entity with a `title` column, and you have changed the name `title` to `name`.
|
||||
You can run following command:
|
||||
|
||||
```shell
|
||||
typeorm migration:generate PostRefactoring -d path-to-datasource-config
|
||||
```
|
||||
|
||||
If you encounter any error, it require you have the path to migration name and data source. You can try this option
|
||||
|
||||
```shell
|
||||
typeorm migration:generate -d <path/to/datasource> path/to/migrations/<migration-name>
|
||||
```
|
||||
|
||||
And it will generate a new migration called `{TIMESTAMP}-PostRefactoring.ts` with the following content:
|
||||
|
||||
```typescript
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can also output your migrations as Javascript files using the `o` (alias for `--outputJs`) flag. This is useful for Javascript only projects in which TypeScript additional packages are not installed. This command, will generate a new migration file `{TIMESTAMP}-PostRefactoring.js` with the following content:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @typedef {import('typeorm').MigrationInterface} MigrationInterface
|
||||
* @typedef {import('typeorm').QueryRunner} QueryRunner
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @implements {MigrationInterface}
|
||||
*/
|
||||
module.exports = class PostRefactoringTIMESTAMP {
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By default, it generates CommonJS JavaScript code with the `o` (alias for `--outputJs`) flag, but you can also generate ESM code with the `esm` flag. This is useful for Javascript projects that use ESM:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @typedef {import('typeorm').MigrationInterface} MigrationInterface
|
||||
* @typedef {import('typeorm').QueryRunner} QueryRunner
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @implements {MigrationInterface}
|
||||
*/
|
||||
export class PostRefactoringTIMESTAMP {
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {QueryRunner} queryRunner
|
||||
*/
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See, you don't need to write the queries on your own.
|
||||
The rule of thumb for generating migrations is that you generate them after **each** change you made to your models. To apply multi-line formatting to your generated migration queries, use the `p` (alias for `--pretty`) flag.
|
||||
|
||||
## DataSource option
|
||||
|
||||
If you need to run/revert/generate/show your migrations use the `-d` (alias for `--dataSource`) and pass the path to the file where your DataSource instance is defined as an argument
|
||||
|
||||
```shell
|
||||
typeorm -d <your-data-source-path> migration:{run|revert}
|
||||
```
|
||||
|
||||
## Timestamp option
|
||||
|
||||
If you need to specify a timestamp for the migration name, use the `-t` (alias for `--timestamp`) and pass the timestamp (should be a non-negative number)
|
||||
|
||||
```shell
|
||||
typeorm -t <specific-timestamp> migration:{create|generate}
|
||||
```
|
||||
|
||||
You can get a timestamp from:
|
||||
|
||||
```js
|
||||
Date.now()
|
||||
/* OR */ new Date().getTime()
|
||||
```
|
||||
|
||||
## Using migration API to write migrations
|
||||
# Query Runner API
|
||||
|
||||
In order to use an API to change a database schema you can use `QueryRunner`.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
import {
|
||||
MigrationInterface,
|
||||
16
docs/docs/migrations/10-extra.md
Normal file
16
docs/docs/migrations/10-extra.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Extra options
|
||||
|
||||
## Timestamp
|
||||
|
||||
If you need to specify a timestamp for the migration name, use the `-t` (alias for `--timestamp`) and pass the timestamp (should be a non-negative number)
|
||||
|
||||
```shell
|
||||
typeorm -t <specific-timestamp> migration:{create|generate}
|
||||
```
|
||||
|
||||
You can get a timestamp from:
|
||||
|
||||
```js
|
||||
Date.now()
|
||||
/* OR */ new Date().getTime()
|
||||
```
|
||||
86
docs/docs/migrations/11-vite.md
Normal file
86
docs/docs/migrations/11-vite.md
Normal file
@ -0,0 +1,86 @@
|
||||
# Vite
|
||||
|
||||
Using TypeORM in a [Vite](https://vite.dev) project is pretty straight forward. However, when you use [migrations](../migrations/01-why.md), you will run into "...migration name is wrong. Migration class name should have a
|
||||
JavaScript timestamp appended." errors when running the production build.
|
||||
On production builds, files are [optimized by default](https://vite.dev/config/build-options#build-minify) which includes mangling your code in order to minimize file sizes.
|
||||
|
||||
You have 3 options to mitigate this. The 3 options are shown below as diff to this basic `vite.config.ts`
|
||||
|
||||
```typescript
|
||||
import legacy from "@vitejs/plugin-legacy"
|
||||
import vue from "@vitejs/plugin-vue"
|
||||
import path from "path"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
build: {
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Option 1: Disable minify
|
||||
|
||||
This is the most crude option and will result in significantly larger files. Add `build.minify = false` to your config.
|
||||
|
||||
```diff
|
||||
--- basic vite.config.ts
|
||||
+++ disable minify vite.config.ts
|
||||
@@ -7,6 +7,7 @@
|
||||
export default defineConfig({
|
||||
build: {
|
||||
sourcemap: true,
|
||||
+ minify: false,
|
||||
},
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
```
|
||||
|
||||
## Option 2: Disable esbuild minify identifiers
|
||||
|
||||
Vite uses esbuild as the default minifier. You can disable mangling of identifiers by adding `esbuild.minifyIdentifiers = false` to your config.
|
||||
This will result in smaller file sizes, but depending on your code base you will get diminishing returns as all identifiers will be kept at full length.
|
||||
|
||||
```diff
|
||||
--- basic vite.config.ts
|
||||
+++ disable esbuild minify identifiers vite.config.ts
|
||||
@@ -8,6 +8,7 @@
|
||||
build: {
|
||||
sourcemap: true,
|
||||
},
|
||||
+ esbuild: { minifyIdentifiers: false },
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
```
|
||||
|
||||
## Option 3: Use terser as minifier while keeping only the migration class names
|
||||
|
||||
Vite supports using terser as minifier. Terser is slower then esbuild, but offers more fine grained control over what to minify.
|
||||
Add `minify: 'terser'` with `terserOptions.mangle.keep_classnames: /^Migrations\d+$/` and `terserOptions.compress.keep_classnames: /^Migrations\d+$/` to your config.
|
||||
These options will make sure classnames that start with "Migrations" and end with numbers are not renamed during minification.
|
||||
|
||||
Make sure terser is available as dev dependency in your project: `npm add -D terser`.
|
||||
|
||||
```diff
|
||||
--- basic vite.config.ts
|
||||
+++ terser keep migration class names vite.config.ts
|
||||
@@ -7,6 +7,11 @@
|
||||
export default defineConfig({
|
||||
build: {
|
||||
sourcemap: true,
|
||||
+ minify: 'terser',
|
||||
+ terserOptions: {
|
||||
+ mangle: { keep_classnames: /^Migrations\d+$/ },
|
||||
+ compress: { keep_classnames: /^Migrations\d+$/ },
|
||||
+ },
|
||||
},
|
||||
plugins: [vue(), legacy()],
|
||||
resolve: {
|
||||
```
|
||||
@ -101,7 +101,7 @@ export const redirects = [
|
||||
},
|
||||
{ from: "/data-source-api", to: "/docs/data-source/data-source-api" },
|
||||
|
||||
{ from: "/migrations", to: "/docs/advanced-topics/migrations" },
|
||||
{ from: "/migrations", to: "/docs/migrations" },
|
||||
{ from: "/transactions", to: "/docs/advanced-topics/transactions" },
|
||||
{ from: "/indices", to: "/docs/advanced-topics/indices" },
|
||||
{
|
||||
@ -123,4 +123,5 @@ export const redirects = [
|
||||
{ from: "/getting-started", to: "/docs/getting-started" },
|
||||
{ from: "/future-of-typeorm", to: "/docs/future-of-typeorm" },
|
||||
{ from: "/query-runner", to: "/docs/query-runner" },
|
||||
{ from: "/docs/advanced-topics/migrations", to: "/docs/migrations" },
|
||||
]
|
||||
|
||||
@ -35,6 +35,11 @@ const sidebars: SidebarsConfig = {
|
||||
label: "Relations",
|
||||
items: [{ type: "autogenerated", dirName: "relations" }],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Migrations",
|
||||
items: [{ type: "autogenerated", dirName: "migrations" }],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Working with Entity Manager",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user