თაიპსქრიპტ - NX + Nest.js + TypeORM - Webpack + მიგრაციები
მაშინ, მე დავიწყე პროექტი NX-ის გამოყენებით (Nest.js + Angular). დამჭირდება მონაცემთა ბაზა, ამიტომ შევარჩიე TypeORM. ყველაფერი კარგად მუშაობს „serve“ რეჟიმში, მაგრამ როგორ უნდა ვაიღებდე მიგრაციების კონფიგურაცია?
რეგულარულ Nest.js პროექტში, dist დირექტორიაში არსებულ ყველაფერს აქვს იგივე სტრუქტურა, რაც თქვენს პროექტს, ამიტომ მიგრაციებიც იქ შედგენილია და კოპირდება. ასე რომ, თუ თქვენ გაქვთ TypeORM სწორად კონფიგურირებული, თქვენი migrationsRun დროშა დაყენებული true და სწორად დაყენებული migrations ბილიკი, მიგრაცია გაშვებულია აპის დაწყებაზე.
პრობლემა ის არის, რომ NX იყენებს webpack-ს, ამიტომ dist-ში მთლიან სტრუქტურას ვერ დაინახავთ, იქ იქნება მხოლოდ ერთი main.js ფაილი და სხვა არაფერი. გადაცემის ფაილები იქ დაგეგმილი არ არის.
ჩემი კითხვა შემდეგია: რა არის საუკეთესო გზა ამ გამოსასწორებლად? ხომ არ უნდა ვცადო webpack-ის გადაკონფიგურირება? თუ ამისთვის არსებობს უკეთესი გზა?
ჩემი პროექტის სტრუქტურა ასე ან ისედაც გამოიყურება:
project/
├─ apps/
│ ├─ api/
│ │ ├─ src/
│ │ │ ├─ config/
│ │ │ │ ├─ database/
│ │ │ │ │ ├─ typeorm.config.ts
│ │ │ ├─ database/
│ │ │ │ ├─ migrations/
| | | | | ├─ 1668904379611-SomeMigration.ts
├─ dist/
│ ├─ apps/
│ │ ├─ api/
│ │ │ ├─ main.js
typeorm.config.ts host: process.env.MYSQL_HOST,
port: +process.env.MYSQL_PORT,
username: process.env.MYSQL_USER,
database: process.env.MYSQL_DATABASE,
password: process.env.MYSQL_PASSWORD,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
migrations: [__dirname + '/../../**/database/migrations/*{.ts,.js}'],
extra: {
charset: 'utf8mb4_unicode_ci',
},
synchronize: false,
migrationsRun: true,
logging: true,
autoLoadEntities: true,
//რედაქტირება
მე მივხვდი, რომ პრობლემა Webpack-შია, არა NX-ში. Webpack ყველაფერს ერთ main.js ფაილში ერევა.
უპასუხე #1
მე თვითონაც ჩამივლია იგივე პრობლემა webpack-ის გამოყენებისას.
TypeORM-ის FAQ დოკუმენტაციის მიხედვით, თქვენ უნდა გამოიყენოთ სპეციალური კონფიგურაცია webpack-ისთვის. ეს მუშაობს, თუ თქვენი მიგრაციის ფაილები "შენდეგებული"ა, მხოლოდ SQL-ით შედგენილი და არა entity-ებით (მაგალითად seed მიგრაციაში). უფრო რთული ხდება უფრო კომპლექსური ფაილების შემთხვევაში.
თქვენ შეგიძლიათ გამოიყენოთ webpack-merge დანამატი, რათა შექმნათ განსხვავებულად თქვენი main.js და თითოეული მიგრაციის ფაილი და შეინახოთ ერთი webpack.config ფაილი.
არ დაგავიწყდეს, რომ მიგრაციის ფაილები ახლა JS-შია. უნდა შეამოწმე კოდი პროდაქშენისთვის. განსაკუთრებით typeorm CLI-სა და datasource-ის გზასთან დაკავშირებით.
მე გთავაზობთ წაიკითხოთ კიდევ ერთი პოსტი ამ თემაზე
გ ვიმედოვარ, რომ ეს დახმარების იქნება.
პასუხი #2
მე აქ გავუზიარებ ჩემს სეგმენტებს, იმედია, ვიღაცას დაეხმარება. პრობლემა არის იმასთან დაკავშირებით, როგორ კუმულირდება კოდი webpack-ის მიერ, განსაკუთრებით /migrations და /entities.
პროჯექტის სტრუქტურა:
apps
└── backend
├── src
│ ├── app
│ └── main.ts
├── Dockerfile
├── data-source.ts
├── docker-compose.yml
└── webpack.config.js
libs
├── shared-lib
└── typeorm
├── project.json
├── src
│ ├── index.ts
│ └── lib
│ ├── entities
│ └── migrations
├── tsconfig.json
└── tsconfig.lib.json
webpack.config.js
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
module.exports = {
plugins: [
new NxAppWebpackPlugin({
main: './src/main.ts',
target: 'node',
compiler: 'tsc',
tsConfig: './tsconfig.app.json',
outputPath: 'dist/apps/backend',
outputHashing: 'none',
optimization: false,
sourceMap: true,
}),
],
};
data-source.ts
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import * as entities from '@nxapp/typeorm'; // I exported normally "export * from './lib/entities'" in /libs/typeorm/src/index.ts;
import { DataSource, DataSourceOptions } from 'typeorm';
const contexts = (require as any).context(
'../../libs/typeorm/src/lib/migrations/',
true,
/\.ts$/,
);
const migrations = contexts
.keys()
.map((modulePath) => contexts(modulePath))
.reduce((result, migrationModule) => {
return Object.assign(result, migrationModule);
});
const { DB_HOST, DB_USERNAME, DB_PASSWORD, DB_PORT, DB_NAME } = process.env;
const dataSourceOptions: DataSourceOptions = {
type: 'postgres' as const,
host: DB_HOST,
port: +DB_PORT,
username: DB_USERNAME,
password: DB_PASSWORD,
database: DB_NAME,
synchronize: false,
logging: true,
entities: Object.values(entities),
migrations: Object.values(migrations),
migrationsRun: true,
};
export const typeOrmModuleOptions: TypeOrmModuleOptions = {
...dataSourceOptions,
};
export default new DataSource(dataSourceOptions);
აპპ.მოდული.ts
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forRoot(typeOrmModuleOptions),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
typeorm ბიბლიოთეკის project.json
შეგიძლიათ გამოიყენოთ TypeORM დოკუმენტაციაში აღინიშნული ნაგულისხმები მონაცემთა წყაროს კონფიგურაცია მიგრაციის ფაილების გენერაციისთვის
{
"name": "typeorm",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/typeorm/src",
"projectType": "library",
"tags": [],
"// targets": "to see all targets run: nx show project typeorm --web",
"targets": {
"migration-generate": {
"command": "ts-node -r tsconfig-paths/register --project {projectRoot}/tsconfig.json ./node_modules/.bin/typeorm migration:generate -d {projectRoot}/data-source.ts -p {projectRoot}/src/lib/migrations/{args.name}",
"options": {
"envFile": "{workspaceRoot}/apps/backend/.env"
}
},
"migration-run": {
"command": "ts-node -r tsconfig-paths/register --project {projectRoot}/tsconfig.json ./node_modules/.bin/typeorm migration:run -d {projectRoot}/data-source.ts",
"options": {
"envFile": "{workspaceRoot}/apps/backend/.env"
}
},
"migration-revert": {
"command": "ts-node -r tsconfig-paths/register --project {projectRoot}/tsconfig.json ./node_modules/.bin/typeorm migration:revert -d {projectRoot}/data-source.ts",
"options": {
"envFile": "{workspaceRoot}/apps/backend/.env"
}
}
}
}
ბედნიერი კოდირება :)
