Elpis - 抽离业务发布 npm 包
准备工作
关于抽离 elpis 中业务内容,我们需要实时测试,利用 npm link 将 elpis 软连接到 elpis-demo 中,将业务代码抽离到 elpis-demo 中,也就是作为使用 elpis 包的角度去慢慢抽离掉业务代码,使包使用更加丝滑。
elpis 引擎改动
在原引擎中,elpis-core 只会去自动挂载当前目录下的 controller service middleware 等,这里以 controller 为例,原代码:
// 读取 app/controller/**/**.js 下所有的文件
const controllerPath = path.resolve(app.businessPath, `.${sep}controller`);
const fileList = glob.sync( path.resolve(controllerPath, `.${sep}**${sep}**.js`) );
// 遍历所有文件目录,把内容加载到 app.controllers 下
const controllers = {};
fileList.forEach((file) => {
......
})
app.controller = controllers;
现在需要将业务添加上的 controller 一并读取出来挂载到 app 上,在其它层也是如此,如下:
const controller = {};
// 读取 elpis/app/controller 目录下的所有文件
const elpisControllerPath = path.resolve(
__dirname,
`..${sep}..${sep}app${sep}controller`,
);
const elpisFileList = glob.sync(
path.resolve(elpisControllerPath, `.${sep}**${sep}**.js`),
);
elpisFileList.forEach((file) => {
handleFile(file);
});
// 读取 业务根目录/app/controller 目录下的所有文件
const businessControllerPath = path.resolve(
app.businessPath,
`.${sep}controller`,
);
const businessFileList = glob.sync(
path.resolve(businessControllerPath, `.${sep}**${sep}**.js`),
);
businessFileList.forEach((file) => {
handleFile(file);
});
handleFile(file){
......
}
app.controller = controller;
webpack
webpack 的配置也需要做出修改,兼容业务上配置,以及相关路径修改:
// 加载业务 webpack 配置
let businessWebpackConfig = {};
try {
businessWebpackConfig = require(`${process.cwd()}/app/webpack.config.js`);
} catch (error) {
console.log('webpack.config.js not found');
}
module.exports = merge.smart(elpisWebpackConfig, businessWebpackConfig)
在 elpisWebpackConfig 中,其中引用的 loader 路径也需修改,改为请求绝对路径,如:
{
test: /\.js$/,
include: [
// 处理 elpis 目录
path.resolve(__dirname, '../../pages'),
// 处理 业务 目录
path.resolve(process.cwd(), './app/pages'),
],
use: {
loader: require.resolve('babel-loader'),
},
},
在测试中也会出现较多错误,如:
这项报错就是无法找到 @babel/runtime/helpers/defineProperty 模块,经过排查发现是是在生产配置中多线程打包中用到插件 @babel/plugin-transform-runtime 导致,解决方案直接安装 @babel/runtime 模块即可,npm i @babel/runtime --save。
动态组件兼容
在 elpis 中有自带动态组件,也支持去拓展,那么需要修改下原代码来兼容拓展出来的动态组件内容,如 schema-form 动态组件拓展表单组件,如下:
// form-item-config.js
import input from './complex-view/input/input.vue';
import inputNumber from './complex-view/input-number/input-number.vue';
import select from './complex-view/select/select.vue';
// 业务拓展 form-item 配置,$businessFormItemConfig 为别名,需在 webpack.config.js 中去配置
import BusinessFormItemConfig from '$businessFormItemConfig';
const FormItemConfig = {
input: {
component: input,
},
inputNumber: {
component: inputNumber,
},
select: {
component: select,
},
};
export default {
...FormItemConfig,
...BusinessFormItemConfig,
};
参考: 《哲玄课堂-大前端全栈实践》