Skip to content

Commit

Permalink
feat: transfor to new package
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed Feb 3, 2020
1 parent c549c6b commit 9144b48
Show file tree
Hide file tree
Showing 28 changed files with 325 additions and 132 deletions.
2 changes: 1 addition & 1 deletion packages/midway-core/package.json
@@ -1,5 +1,5 @@
{
"name": "midway-core",
"name": "@midwayjs/core",
"version": "1.16.3",
"description": "midway core",
"main": "dist/index",
Expand Down
42 changes: 25 additions & 17 deletions packages/midway-core/src/configuration.ts
@@ -1,4 +1,4 @@
import { CONFIGURATION_KEY } from '@midwayjs/decorator';
import { CONFIGURATION_KEY, InjectionConfigurationOptions } from '@midwayjs/decorator';
import { getClassMetadata } from 'injection';
import * as is from 'is-type-of';
import { dirname, isAbsolute, join } from 'path';
Expand All @@ -15,13 +15,13 @@ export class ContainerConfiguration implements IContainerConfiguration {
this.container = container;
}

addImports(imports: string[]) {
addImports(imports: string[] = [], baseDir?: string) {
// 处理 imports
for (let importPackage of imports) {
// 把相对路径转为绝对路径
if (isPath(importPackage)) {
if (!isAbsolute(importPackage)) {
importPackage = join(this.container.baseDir, importPackage);
importPackage = join(baseDir || this.container.baseDir, importPackage);
}
} else {
// for package
Expand All @@ -33,7 +33,17 @@ export class ContainerConfiguration implements IContainerConfiguration {
}

addImportObjects(importObjects: object) {
this.importObjects = importObjects;
if (importObjects) {
this.importObjects = importObjects;
}
}

addImportConfigs(importConfigs: string[], baseDir: string) {
if (importConfigs && importConfigs.length) {
this.container.getConfigService().add(importConfigs.map(importConfigPath => {
return join(baseDir || this.container.baseDir, importConfigPath);
}));
}
}

private resolvePackageBaseDir(packageName: string) {
Expand All @@ -42,45 +52,43 @@ export class ContainerConfiguration implements IContainerConfiguration {

load(packageName: string) {
let configuration;
let baseDir = packageName;
if (isPath(packageName)) {
const pkg = safeRequire(join(packageName, 'package.json'));
if (pkg && pkg.main) {
// 找到 package.json 中的 main 指定的文件目录
const innerDir = dirname(join(packageName, pkg.main));
configuration = safeRequire(join(innerDir, 'configuration'));
baseDir = dirname(join(packageName, pkg.main));
configuration = safeRequire(join(baseDir, 'configuration'));
}
if (!configuration) {
// 找外层目录
configuration = safeRequire(join(packageName, 'configuration'));
}
} else {
// 查找包中的文件
const innerDir = this.resolvePackageBaseDir(packageName);
configuration = safeRequire(join(innerDir, 'configuration'));
baseDir = this.resolvePackageBaseDir(packageName);
configuration = safeRequire(join(baseDir, 'configuration'));
if (!configuration) {
configuration = safeRequire(`${packageName}/configuration`);
}
}
this.loadConfiguration(configuration);
this.loadConfiguration(configuration, baseDir);
}

loadConfiguration(configuration) {
loadConfiguration(configuration, baseDir) {
if (configuration) {
// 可能导出多个
const configurationExports = this.getConfigurationExport(configuration);
for (const configurationExport of configurationExports) {
const configurationOptions = getClassMetadata(
const configurationOptions: InjectionConfigurationOptions = getClassMetadata(
CONFIGURATION_KEY,
configurationExport
);

if (configurationOptions) {
if (configurationOptions.imports) {
this.addImports(configurationOptions.imports);
}
if (configurationOptions.importObjects) {
this.addImportObjects(configurationOptions.importObjects);
}
this.addImports(configurationOptions.imports, baseDir);
this.addImportObjects(configurationOptions.importObjects);
this.addImportConfigs(configurationOptions.importConfigs, baseDir);
}
}
}
Expand Down
44 changes: 27 additions & 17 deletions packages/midway-core/src/container.ts
Expand Up @@ -15,7 +15,9 @@ import * as is from 'is-type-of';
import { join } from 'path';
import { ContainerConfiguration } from './configuration';
import { FUNCTION_INJECT_KEY, MidwayHandlerKey } from './constant';
import { IMidwayContainer } from './interface';
import { IConfigService, IEnvironmentService, IMidwayContainer } from './interface';
import { MidwayConfigService } from './service/configService';
import { MidwayEnvironmentService } from './service/environmentService';

const DEFAULT_PATTERN = ['**/**.ts', '**/**.tsx', '**/**.js', '!**/**.d.ts'];
const DEFAULT_IGNORE_PATTERN = [
Expand All @@ -38,46 +40,34 @@ interface FrameworkDecoratorMetadata {
const MAIN_MODULE_KEY = '__main__';

export class MidwayContainer extends Container implements IMidwayContainer {
controllersIds: string[] = [];
middlewaresIds: string[] = [];
handlerMap: Map<string, (handlerKey: string, instance?: any) => any>;
// 仅仅用于兼容requestContainer的ctx
ctx = {};
isTsMode;
readyBindModules: Map<string, Set<any>> = new Map();
importDirectory = [];
configurations = [];
configService: IConfigService;
environmentService: IEnvironmentService;

constructor(
baseDir: string = process.cwd(),
parent: IApplicationContext = undefined,
isTsMode = true
) {
super(baseDir, parent);
this.isTsMode = isTsMode;
}

init(): void {
this.handlerMap = new Map();
this.environmentService = new MidwayEnvironmentService();
this.configService = new MidwayConfigService(this);
super.init();

this.registerEachCreatedHook();

// 防止直接从applicationContext.getAsync or get对象实例时依赖当前上下文信息出错
// ctx is in requestContainer
this.registerObject('ctx', this.ctx);
}

/**
* update current context in applicationContext
* for mock and other case
* @param ctx ctx
* @deprecated
*/
updateContext(ctx) {
this.ctx = Object.assign({}, ctx || {});
}

/**
* load directory and traverse file to find bind class
* @param opts
Expand Down Expand Up @@ -348,4 +338,24 @@ export class MidwayContainer extends Container implements IMidwayContainer {
this.configurations.push(containerConfiguration);
return containerConfiguration;
}

getConfigService() {
return this.configService;
}

getEnvironmentService() {
return this.environmentService;
}

getCurrentEnv() {
return this.environmentService.getCurrentEnvironment();
}

async ready() {
super.ready();
// 加载配置
await this.configService.load();
}
}

// TODO 测试的 ctx,看看行不行
20 changes: 18 additions & 2 deletions packages/midway-core/src/interface.ts
@@ -1,13 +1,29 @@
import { IContainer } from 'injection';

export interface IContainerConfiguration {
addImports(imports: string[]);
addImports(imports: string[], baseDir?: string);
addImportObjects(importObjects: any[]);
addImportConfigs(importConfigs: string[], baseDir: string);
load(packageName: string);
loadConfiguration(configuration: any);
loadConfiguration(configuration: any, baseDir: string);
getImportDirectory(): string[];
}

export interface IMidwayContainer extends IContainer {
createConfiguration();
getConfigService(): IConfigService;
getEnvironmentService(): IEnvironmentService;
getCurrentEnv(): string;
}

export interface IConfigService {
add(configFilePaths: string[]);
addObject(obj: object);
load();
getConfiguration();
}

export interface IEnvironmentService {
getCurrentEnvironment(): string;
setCurrentEnvironment(environment: string);
}
5 changes: 3 additions & 2 deletions packages/midway-core/src/loader.ts
@@ -1,5 +1,6 @@
import * as path from 'path';
import { MidwayContainer } from './container';
import { Container } from 'injection';

function buildLoadDir(baseDir, dir) {
if (!path.isAbsolute(dir)) {
Expand All @@ -23,8 +24,8 @@ export class ContainerLoader {
}

initialize() {
this.pluginContext = new MidwayContainer(this.baseDir);
this.applicationContext = new MidwayContainer(this.baseDir, undefined, this.isTsMode);
this.pluginContext = new Container(this.baseDir);
this.applicationContext = new MidwayContainer(this.baseDir, undefined);
this.applicationContext.registerObject('baseDir', this.baseDir);
this.applicationContext.registerObject('isTsMode', this.isTsMode);
}
Expand Down
16 changes: 3 additions & 13 deletions packages/midway-core/src/requestContainer.ts
@@ -1,26 +1,16 @@
import { ManagedValue, VALUE_TYPE } from 'injection';
import { ManagedValue, VALUE_TYPE, REQUEST_CTX_KEY } from 'injection';
import { MidwayContainer } from './container';

export class MidwayRequestContainer extends MidwayContainer {

applicationContext: MidwayContainer;
ctx;

constructor(applicationContext, ctx?) {
constructor(ctx, applicationContext) {
super();
this.parent = applicationContext;
this.applicationContext = applicationContext;

if (ctx) {
this.updateContext(ctx);
}
}

updateContext(ctx) {
// this.registry.clearAll();
this.ctx = ctx;
// register ctx
this.registerObject('ctx', ctx);
this.registerObject(REQUEST_CTX_KEY, ctx);
// register contextLogger
this.registerObject('logger', ctx.logger);
}
Expand Down
99 changes: 99 additions & 0 deletions packages/midway-core/src/service/configService.ts
@@ -0,0 +1,99 @@
import * as extend from 'extend2';
import * as is from 'is-type-of';
import { basename } from 'path';
import { IConfigService, IMidwayContainer } from '../interface';

const debug = require('debug')('midway:config');

export class MidwayConfigService implements IConfigService {

envDirMap: Map<string, Set<string>>;
configuration;
isReady = false;
container: IMidwayContainer;
externalObject: object[] = [];

constructor(container) {
this.container = container;
this.envDirMap = new Map();
}

add(configFilePaths) {
for (const dir of configFilePaths) {
const env = this.getConfigEnv(dir);
const envSet = this.getEnvSet(env);
envSet.add(dir);
}
}

addObject(obj: object) {
if (this.isReady) {
extend(true, this.configuration, obj);
} else {
this.externalObject.push(obj);
}
}

getEnvSet(env) {
if (!this.envDirMap.has(env)) {
this.envDirMap.set(env, new Set());
}
return this.envDirMap.get(env);
}

getConfigEnv(configFilePath) {
// parse env
const configFileBaseName = basename(configFilePath);
const splits = configFileBaseName.split('.');
const suffix = splits.pop();
if (suffix !== 'js' && suffix !== 'ts') {
return suffix;
}
return splits.pop();
}

async load() {
// get default
const defaultSet = this.getEnvSet('default');
// get current set
const currentEnvSet = this.getEnvSet(this.container.getCurrentEnv());
// merge set
const target = {};
for (const filename of [...defaultSet, ...currentEnvSet]) {
const config = await this.loadConfig(filename);

if (!config) {
continue;
}

debug('Loaded config %s, %j', filename, config);
extend(true, target, config);
}
if (this.externalObject.length) {
for (const externalObject of this.externalObject) {
if (externalObject) {
debug('Loaded external object %j', externalObject);
extend(true, target, externalObject);
}
}
}
this.configuration = target;
}

async getConfiguration() {
if (!this.isReady) {
await this.load();
this.isReady = true;
}
return this.configuration;
}

async loadConfig(configFilename): Promise<object> {
const exports = require(configFilename);
let result = exports;
if (is.function(exports)) {
result = await exports.apply(null, [].concat(this.container));
}
return result;
}
}
16 changes: 16 additions & 0 deletions packages/midway-core/src/service/environmentService.ts
@@ -0,0 +1,16 @@
import { IEnvironmentService } from '../interface';

export class MidwayEnvironmentService implements IEnvironmentService {
environment: string;

getCurrentEnvironment() {
if (!this.environment) {
this.environment = process['MIDWAY_SERVER_ENV'] || process['NODE_ENV'] || 'production';
}
return this.environment;
}

setCurrentEnvironment(environment: string) {
this.environment = environment;
}
}
@@ -0,0 +1,4 @@
{
"name": "midway-plugin-mock",
"main": "src/index.ts"
}

0 comments on commit 9144b48

Please sign in to comment.