typeorm_Nestjs 热更新 + typeorm 配置
Nestjs 開發(fā)環(huán)境熱更新的方案
Nestjs 的熱更新是基于 Webpack HMR(Hot-Module Replacement) 方案
警告請注意,webpack不會自動將您的資產(chǎn)(例如graphql文件)復制到dist文件夾。同樣,webpack與glob靜態(tài)路徑(例如TypeOrmModule中的實體屬性)不兼容。1 使用 CLI
如果您正在使用Nest CLI,配置過程非常簡單。CLI包裝webpack,它允許使用HotModuleReplacementPlugin。
安裝首先安裝依賴包:
$ npm i --save-dev webpack-node-externals配置在根目錄下創(chuàng)建 webpack.config.js,內(nèi)容如下:
const webpack = require('webpack');const nodeExternals = require('webpack-node-externals');module.exports = function(options) { return { ...options, entry: ['webpack/hot/poll?100', './src/main.ts'], watch: true, externals: [ nodeExternals({ whitelist: ['webpack/hot/poll?100'], }), ], plugins: [...options.plugins, new webpack.HotModuleReplacementPlugin()], };}此函數(shù)獲取包含默認webpack配置的原始對象,并返回一個修改后的對象,該對象帶有一個已應用的HotModuleReplacementPlugin插件。
Hot-Module Repacement為了啟用HMR,打開應用程序入口文件(main.ts)并添加幾個與webpack相關(guān)的指令,如下所示:
declare const module: any;async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); if (module.hot) { module.hot.accept(); module.hot.dispose(() => app.close()); }}bootstrap();在 package.json文件中增加如下兩條腳本
"build": "nest build --watch --webpack""start": "node dist/main",執(zhí)行如下命令
$ npm run buildWebpack 開始監(jiān)聽文件,在新的命令行窗口執(zhí)行
$ npm run start不使用 CLI
安裝
$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader配置創(chuàng)建 webpack.config.js 內(nèi)容如下:
const webpack = require('webpack');const path = require('path');const nodeExternals = require('webpack-node-externals');module.exports = { entry: ['webpack/hot/poll?100', './src/main.ts'], watch: true, target: 'node', externals: [ nodeExternals({ whitelist: ['webpack/hot/poll?100'], }), ], module: { rules: [ { test: /.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, mode: 'development', resolve: { extensions: ['.tsx', '.ts', '.js'], }, plugins: [new webpack.HotModuleReplacementPlugin()], output: { path: path.join(__dirname, 'dist'), filename: 'server.js', },};Hot-Module Replacement為了啟用HMR,打開應用程序入口文件(main.ts)并添加幾個與webpack相關(guān)的指令,如下所示:
declare const module: any;async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); if (module.hot) { module.hot.accept(); module.hot.dispose(() => app.close()); }}bootstrap();在 package.json 文件中加入以下腳本
"webpack": "webpack --config webpack.config.js""start": "node dist/server",執(zhí)行命令
$ npm run webpack新命令窗口下執(zhí)行
$ npm run startTypeorm 配置
由于webpack與glob靜態(tài)路徑不兼容,所以要想讓 typeorm 同樣支持熱更新,正常需要靜態(tài)引入 entity 而不是利用通配符方式。
如:
import { Cat } from '../cat/cat.entity';@Module({ imports: [ // provides: typeorm/Connection, typeorm/EntityManager TypeOrmModule.forRoot({ entities: [ Cat, ], }), ],})export class DatabaseModule { }但是這樣如果有很多 entity 會非常不便,幸運的是,webpack有一特性 require.context。允許收集所需文件的上下文。那么我們可以這樣:
// entity.context.ts (in root src folder)export const entityContext = require.context('.', true, /.entity.ts$/);// database.module.tsimport { entityContext } from '../entity.context';@Module({ imports: [ TypeOrmModule.forRoot({ entities: [ ...entityContext.keys().map(id => { const entityModule = entityContext(id); // We must get entity from module (commonjs) // Get first exported value from module (which should be entity class) const [entity] = Object.values(entityModule); return entity; }) ], }), ],})export class DatabaseModule { }但這個方案,對 production 不友好,所以還可以使用下面的方案:
import { Module } from '@nestjs/common';import { TypeOrmModule } from '@nestjs/typeorm';import { getMetadataArgsStorage } from 'typeorm';// The modules are loaded from here, hence importing the entitiesimport { AModule } from './a/a.module';import { BModule } from './b/b.module';@Module({ imports: [ AModule, BModule, TypeOrmModule.forRoot({ ..., entities: getMetadataArgsStorage().tables.map(tbl => tbl.target), migrations: ..., }), ]})export class AppModule {}這個方案的思路是:
由于webpack將所有代碼打包成一個單獨的包文件,為了讓HMR工作,這個包文件作為服務器加載并運行指定實體:* dirname + '/*/。ts'將導致typeorm需要那些文件(而實際的實體已經(jīng)在webpack包中加載了)。
當typeorm試圖獲取repository時,它會將傳入的實體與從js/ts文件中加載的實體配置進行比較(例如,從webpack包中加載用戶的getRepository)。
盡管它們有相同的名稱,但它們是從不同的模塊加載的兩個不同的類(函數(shù)),因此typeorm將無法找到正確的類。
我的解決方案是基于所有模塊都已加載的事實,因此應該已經(jīng)通過導入加載了所有實體。對于結(jié)構(gòu)良好的項目,NestJS尤其如此。具體來說,對于每個模塊,要么模塊本身,要么控制器將導入實體到某個地方。
通過利用@Entity裝飾器的內(nèi)部機制,我們將能夠獲得實體類的列表。
不確定這個是最佳方案,但的確運行良好。
-EOF-
參考
https://github.com/nestjs/nest/issues/755
總結(jié)
以上是生活随笔為你收集整理的typeorm_Nestjs 热更新 + typeorm 配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微商卖的果冻真能减肥吗
- 下一篇: 减肥一个月停一周再继续,要重新循环减重吗