如何防止装饰器在 TypeScript 中导入节点模块?
How do i prevent decorators from importing node modules in TypeScript?
我正在尝试使用打字稿中的 typeorm 库在 TypeScript 2 Express 服务器和 Angular 2 之间创建 DTO/DAO 模式。
为简洁起见,我将这些对象称为 DTO,但它们只是一堆字段和注释。
import {autoserialize} from "cerialize";
import {DTOReport} from "./reports.dto";
import { PrimaryGeneratedColumn} from "typeorm/decorator/columns/PrimaryGeneratedColumn"
import { CreateDateColumn } from "typeorm/decorator/columns/CreateDateColumn";
import { Column } from "typeorm/decorator/columns/Column";
import { JoinColumn } from "typeorm/decorator/relations/JoinColumn";
import { OneToOne } from "typeorm/decorator/relations/OneToOne";
import { ManyToOne } from "typeorm/decorator/relations/ManyToOne";
import { OneToMany } from "typeorm/decorator/relations/OneToMany";
import { Table } from "typeorm/decorator/tables/Table";
import { ColumnTypes } from "typeorm/metadata/types/ColumnTypes";
@Table()
export class DTOSourceFile {
@PrimaryGeneratedColumn()
@autoserialize
id: number;
@Column()
@autoserialize
locationURL: string;
@CreateDateColumn()
@autoserialize
createdAt: Date;
@OneToMany(type => DTOReport, report => report.source, {nullable: true})
@autoserialize report: DTOReport;
@autoserialize reportId: number;
@Column(ColumnTypes.TEXT)
@autoserialize
originalname: string;
@Column(ColumnTypes.JSON)
@autoserialize
mutler: string;
}
我小心翼翼地只导入装饰器。但是,在编译时我看到一个请求返回根 index.ts 文件。
"use strict";
const ColumnTypes_1 = require("../../metadata/types/ColumnTypes");
const ColumnTypeUndefinedError_1 = require("../error/ColumnTypeUndefinedError");
const index_1 = require("../../index"); // < --- THIS
const PrimaryColumnCannotBeNullableError_1 = require("../error/PrimaryColumnCannotBeNullableError");
/**
* Column decorator is used to mark a specific class property as a table column.
* Only properties decorated with this decorator will be persisted to the database when entity be saved.
* Primary columns also creates a PRIMARY KEY for this column in a db.
*/
function PrimaryColumn(typeOrOptions, options) {
let type;
if (typeof typeOrOptions === "string") {
type = typeOrOptions;
}
else {
options = typeOrOptions;
}
return function (object, propertyName) {
const reflectedType = ColumnTypes_1.ColumnTypes.typeToString(Reflect.getMetadata("design:type", object, propertyName));
// if type is not given implicitly then try to guess it
if (!type)
type = ColumnTypes_1.ColumnTypes.determineTypeFromFunction(Reflect.getMetadata("design:type", object, propertyName));
// if column options are not given then create a new empty options
if (!options)
options = {};
// check if there is no type in column options then set type from first function argument, or guessed one
if (!options.type)
options = Object.assign({ type: type }, options);
// if we still don't have a type then we need to give error to user that type is required
if (!options.type)
throw new ColumnTypeUndefinedError_1.ColumnTypeUndefinedError(object, propertyName);
// check if column is not nullable, because we cannot allow a primary key to be nullable
if (options.nullable)
throw new PrimaryColumnCannotBeNullableError_1.PrimaryColumnCannotBeNullableError(object, propertyName);
// implicitly set a primary to column options
options = Object.assign({ primary: true }, options);
// create and register a new column metadata
const args = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "regular",
options: options
};
index_1.getMetadataArgsStorage().columns.add(args); // < --- THIS
};
}
exports.PrimaryColumn = PrimaryColumn;
//# sourceMappingURL=PrimaryColumn.js.map
Angular2 的 webpack 编译器产生的错误清楚地显示了问题,因为它随后尝试加载节点依赖项。
WARNING in ./~/typeorm/driver/sqlserver/SqlServerDriver.js
Module not found: Error: Can't resolve 'mssql' in '/Users/jmurphy/projects/ubq/web/node_modules/typeorm/driver/sqlserver'
@ ./~/typeorm/driver/sqlserver/SqlServerDriver.js 256:25-41
@ ./~/typeorm/connection/ConnectionManager.js
@ ./~/typeorm/index.js
@ ./~/typeorm/decorator/columns/PrimaryGeneratedColumn.js
@ ./src/app/dtos/lens.dto.ts
@ ./src/app/lens/lens.component.ts
@ ./src/app/app.module.ts
@ ./src/app/index.ts
@ ./src/main.ts
@ multi main
Child html-webpack-plugin for "index.html":
Asset Size Chunks Chunk Names
index.html 2.88 kB 0
webpack: bundle is now VALID.
有没有办法允许 TypeORM 装饰器存在于浏览器项目中而无需尝试加载节点依赖项?
链接:
TypeORM 来源:
https://github.com/typeorm/typeorm/blob/master/src/decorator/columns/PrimaryColumn.ts
我认为这个库不是为在网络浏览器中工作而设计的,但也许有一个解决方案。装饰器使用在 /index.ts
处声明的 getMetadataArgsStorage
函数。 /index.ts
导入了很多导致您遇到问题的东西。
您可以看到 here getMetadataArgsStorage
函数如何使用 defaultContainer
和 MetadataArgsStorage
。
如果 getMetadataArgsStorage
从 index.ts
移动到一个新文件,它可能对您有效,但您需要发送 PR到 GitHub.
上的项目
问题是 this line,因为 ConnectionManager
导入了所有驱动程序:
import * as fs from "fs";
import {Connection} from "./Connection";
import {ConnectionNotFoundError} from "./error/ConnectionNotFoundError";
import {MysqlDriver} from "../driver/mysql/MysqlDriver";
import {ConnectionOptions} from "./ConnectionOptions";
import {DriverOptions} from "../driver/DriverOptions";
import {Driver} from "../driver/Driver";
import {MissingDriverError} from "./error/MissingDriverError";
import {PostgresDriver} from "../driver/postgres/PostgresDriver";
import {AlreadyHasActiveConnectionError} from "./error/AlreadyHasActiveConnectionError";
import {Logger} from "../logger/Logger";
import {SqliteDriver} from "../driver/sqlite/SqliteDriver";
import {OracleDriver} from "../driver/oracle/OracleDriver";
import {SqlServerDriver} from "../driver/sqlserver/SqlServerDriver";
import {OrmUtils} from "../util/OrmUtils";
import {CannotDetermineConnectionOptionsError} from "./error/CannotDetermineConnectionOptionsError";
/**
* ConnectionManager is used to store and manage all these different connections.
* It also provides useful factory methods to simplify connection creation.
*/
export class ConnectionManager {
// ...
我建议你向 typeorm 的作者解释你的用例。也可以提到,如果不是所有的驱动程序都默认导入,那将是很好的。最好只加载所需的驱动程序(在你的情况下 none)。
我正在尝试使用打字稿中的 typeorm 库在 TypeScript 2 Express 服务器和 Angular 2 之间创建 DTO/DAO 模式。
为简洁起见,我将这些对象称为 DTO,但它们只是一堆字段和注释。
import {autoserialize} from "cerialize";
import {DTOReport} from "./reports.dto";
import { PrimaryGeneratedColumn} from "typeorm/decorator/columns/PrimaryGeneratedColumn"
import { CreateDateColumn } from "typeorm/decorator/columns/CreateDateColumn";
import { Column } from "typeorm/decorator/columns/Column";
import { JoinColumn } from "typeorm/decorator/relations/JoinColumn";
import { OneToOne } from "typeorm/decorator/relations/OneToOne";
import { ManyToOne } from "typeorm/decorator/relations/ManyToOne";
import { OneToMany } from "typeorm/decorator/relations/OneToMany";
import { Table } from "typeorm/decorator/tables/Table";
import { ColumnTypes } from "typeorm/metadata/types/ColumnTypes";
@Table()
export class DTOSourceFile {
@PrimaryGeneratedColumn()
@autoserialize
id: number;
@Column()
@autoserialize
locationURL: string;
@CreateDateColumn()
@autoserialize
createdAt: Date;
@OneToMany(type => DTOReport, report => report.source, {nullable: true})
@autoserialize report: DTOReport;
@autoserialize reportId: number;
@Column(ColumnTypes.TEXT)
@autoserialize
originalname: string;
@Column(ColumnTypes.JSON)
@autoserialize
mutler: string;
}
我小心翼翼地只导入装饰器。但是,在编译时我看到一个请求返回根 index.ts 文件。
"use strict";
const ColumnTypes_1 = require("../../metadata/types/ColumnTypes");
const ColumnTypeUndefinedError_1 = require("../error/ColumnTypeUndefinedError");
const index_1 = require("../../index"); // < --- THIS
const PrimaryColumnCannotBeNullableError_1 = require("../error/PrimaryColumnCannotBeNullableError");
/**
* Column decorator is used to mark a specific class property as a table column.
* Only properties decorated with this decorator will be persisted to the database when entity be saved.
* Primary columns also creates a PRIMARY KEY for this column in a db.
*/
function PrimaryColumn(typeOrOptions, options) {
let type;
if (typeof typeOrOptions === "string") {
type = typeOrOptions;
}
else {
options = typeOrOptions;
}
return function (object, propertyName) {
const reflectedType = ColumnTypes_1.ColumnTypes.typeToString(Reflect.getMetadata("design:type", object, propertyName));
// if type is not given implicitly then try to guess it
if (!type)
type = ColumnTypes_1.ColumnTypes.determineTypeFromFunction(Reflect.getMetadata("design:type", object, propertyName));
// if column options are not given then create a new empty options
if (!options)
options = {};
// check if there is no type in column options then set type from first function argument, or guessed one
if (!options.type)
options = Object.assign({ type: type }, options);
// if we still don't have a type then we need to give error to user that type is required
if (!options.type)
throw new ColumnTypeUndefinedError_1.ColumnTypeUndefinedError(object, propertyName);
// check if column is not nullable, because we cannot allow a primary key to be nullable
if (options.nullable)
throw new PrimaryColumnCannotBeNullableError_1.PrimaryColumnCannotBeNullableError(object, propertyName);
// implicitly set a primary to column options
options = Object.assign({ primary: true }, options);
// create and register a new column metadata
const args = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "regular",
options: options
};
index_1.getMetadataArgsStorage().columns.add(args); // < --- THIS
};
}
exports.PrimaryColumn = PrimaryColumn;
//# sourceMappingURL=PrimaryColumn.js.map
Angular2 的 webpack 编译器产生的错误清楚地显示了问题,因为它随后尝试加载节点依赖项。
WARNING in ./~/typeorm/driver/sqlserver/SqlServerDriver.js
Module not found: Error: Can't resolve 'mssql' in '/Users/jmurphy/projects/ubq/web/node_modules/typeorm/driver/sqlserver'
@ ./~/typeorm/driver/sqlserver/SqlServerDriver.js 256:25-41
@ ./~/typeorm/connection/ConnectionManager.js
@ ./~/typeorm/index.js
@ ./~/typeorm/decorator/columns/PrimaryGeneratedColumn.js
@ ./src/app/dtos/lens.dto.ts
@ ./src/app/lens/lens.component.ts
@ ./src/app/app.module.ts
@ ./src/app/index.ts
@ ./src/main.ts
@ multi main
Child html-webpack-plugin for "index.html":
Asset Size Chunks Chunk Names
index.html 2.88 kB 0
webpack: bundle is now VALID.
有没有办法允许 TypeORM 装饰器存在于浏览器项目中而无需尝试加载节点依赖项?
链接:
TypeORM 来源: https://github.com/typeorm/typeorm/blob/master/src/decorator/columns/PrimaryColumn.ts
我认为这个库不是为在网络浏览器中工作而设计的,但也许有一个解决方案。装饰器使用在 /index.ts
处声明的 getMetadataArgsStorage
函数。 /index.ts
导入了很多导致您遇到问题的东西。
您可以看到 here getMetadataArgsStorage
函数如何使用 defaultContainer
和 MetadataArgsStorage
。
如果 getMetadataArgsStorage
从 index.ts
移动到一个新文件,它可能对您有效,但您需要发送 PR到 GitHub.
问题是 this line,因为 ConnectionManager
导入了所有驱动程序:
import * as fs from "fs";
import {Connection} from "./Connection";
import {ConnectionNotFoundError} from "./error/ConnectionNotFoundError";
import {MysqlDriver} from "../driver/mysql/MysqlDriver";
import {ConnectionOptions} from "./ConnectionOptions";
import {DriverOptions} from "../driver/DriverOptions";
import {Driver} from "../driver/Driver";
import {MissingDriverError} from "./error/MissingDriverError";
import {PostgresDriver} from "../driver/postgres/PostgresDriver";
import {AlreadyHasActiveConnectionError} from "./error/AlreadyHasActiveConnectionError";
import {Logger} from "../logger/Logger";
import {SqliteDriver} from "../driver/sqlite/SqliteDriver";
import {OracleDriver} from "../driver/oracle/OracleDriver";
import {SqlServerDriver} from "../driver/sqlserver/SqlServerDriver";
import {OrmUtils} from "../util/OrmUtils";
import {CannotDetermineConnectionOptionsError} from "./error/CannotDetermineConnectionOptionsError";
/**
* ConnectionManager is used to store and manage all these different connections.
* It also provides useful factory methods to simplify connection creation.
*/
export class ConnectionManager {
// ...
我建议你向 typeorm 的作者解释你的用例。也可以提到,如果不是所有的驱动程序都默认导入,那将是很好的。最好只加载所需的驱动程序(在你的情况下 none)。