-
Notifications
You must be signed in to change notification settings - Fork 38
midway2.x 深度躺坑记(持续更新)
小编曾是 Koa 的 Contributor。也基于 Koa 自己搭建过 Web 框架,整过亿级流量的服务,单台4核8G机器 QPS 去到15000(前面就简单水一下……^_^)
从 egg.js 1.x 到 egg.js 2.x 再到 midway 1.x midway 2.x 一路玩过来,颇有些波折。今天主要记录下从 midway 1.x 到 midway 2.x 迁移到一些坑点。 同时这个仓库会有 midway1.x midway2.x 到一些实践。
在 JS/TS 项目中,我们都喜欢配置路径别名,以便于深层减少 ../../
都使用,使得 import 的时候,代码显得更简洁一些。
在 midway 1.x 中,按照官方文档在 tsconfig.json 中配置了 paths 无效 配置即可
而在 midway 2.x 中,情况有些变化,项目启动最先加载的文件不再是 plugin.ts
而是 configuration.ts
。
所以更改配置的位置即可
src/configuration.ts
// eslint-disable-next-line node/no-unpublished-import
import 'tsconfig-paths/register';
.
.
.
在 midway 1.x 中,基于 egg.js 作为下层框架,在中间件配置里面,可以设置 match/ignore 对特殊的路径进行启用/屏蔽操作
src/config/config.default.ts
config.jwt = {
enable: true,
client: {
secret: '123456',
},
ignore: ['/auth/login', '/ping'],
}
在npm run test
的时候,这个配置是无效的。需要在项目根目录建立一个文件 jest.config.js
,指定moduleNameMapper的配置
内容如下:
const path = require('path');
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['<rootDir>/test/fixtures'],
coveragePathIgnorePatterns: ['<rootDir>/test/'],
moduleNameMapper: {
"^@/(.*)$": '<rootDir>src/$1'
}
};
如上,在 midway 2.x 中是不起作用的。原因 midwayjs/packeges/web/app.js#didLoad 这个函数没有写这块逻辑。
将 midway 依赖版本更新到2.3.12后可以解决这问题。下面是核心代码 midway/packages/web/app.js#L19
async didLoad() {
// 这里的逻辑是为了兼容老 cluster 模式
if (this.app.options['isClusterMode'] !== false) {
this.framework = new Framework().configure({
processType: 'application',
app: this.app,
globalConfig: this.app.config,
});
Bootstrap.configure({
baseDir: this.app.appDir,
}).load(this.framework);
await Bootstrap.run();
this.app.options['webFramework'] = this.framework;
}
// 等 midway 加载完成后,再去 use 中间件
for (const name of this.appMiddleware) {
if (this.app.getApplicationContext().registry.hasDefinition(name)) {
const mwIns = await this.app.generateMiddleware(name);
this.app.use(mwIns);
} else {
// egg
const options = this.app.config[name];
if (options.enable === false) {
continue;
}
// support options.match and options.ignore
const mw = this.app.middlewares[name](options);
if (!options.match && !options.ignore) {
this.app.use(mw);
} else {
const match = pathMatching(options);
const fn = (ctx, next) => {
if (!match(ctx)) return next();
return mw(ctx, next);
};
fn._name = mw._name + 'middlewareWrapper';
this.app.use(fn);
}
}
}
}
特别注意的一点,如果有自定义的中间件,在 config.middleware
中使用时,如果没有为该中间件配置 enable 属性,启动是会抛错的。截止2020/10/13日小编已经修复该问题,查看PR: fix: when middleware config options is undefined, options.match
出现错误
TypeError: Cannot convert undefined or null to object
出现这个问题的原因是,受 @midwayjs/orm
依赖到影响,@midwayjs/core
内声明的 MidwayFrameworkType
在依赖包安装到 node_modules 后,由于内外包到引用问题,为 undefined. (也就是说没有安装到正确到版本)
不过该问题现在已经修复了。
以下2020年12月21日更新
最近发现 midway2.x 在 Node.js 10.x 版本跑 CI 会经常丢失 applicationContext,如果你正在使用 Node.js 10.x 的版本,建议升级使用最新的 LTS 版本。排查该问题后,会在文章更新最新的状态。