简介
@lcap/nasl-unified-frontend-generator
是前端代码翻译器。
它采用插件化的架构,以NASL语法树的根节点App
为输入,输出可以运行的前端应用源代码。其架构如下图所示。
除开输入和输出,整个翻译器的架构由以下部分构成:
- IR构建器(IR Builder):以NASL语法(也包括配置)为输入,以IR为输出。将NASL 语法树上的信息进行收集、转换,成为便于后续代码生成使用的表示。
- IR (Intermediate Representation):框架无关、语言中立的中间表示。我们将 NASL 处理成为结构相对稳定的IR。
- 插件系统和插件生态。插件系统会定义插件的接口,并加载插件;插件生态预计包含如下插件:
- JavaScript/TypeScript代码生成:框架无关的JavaScript/TypeScript代码生成,供框架代码生成调用。
- 框架代码生成:分为两个插件,分别处理React、Vue的代码生成。它们依赖JavaScript代码生成插件、组件库适配器,维护框架特有的逻辑、组件调用方式。
- 状态管理:框架代码生成插件往往需要将状态管理实现为一个插件。在我们提供的React代码生成插件中,我们对实现了基于MobX的状态管理插件。
- 应用路由:包括应用路由提取和应用路由生成。
- 国际化:进行i18nKey的管理和文案的国际化。
- 项目结构:负责应用目录结构的控制,支持自定义。
- 组件库适配器:框架代码生成和具体组件库的一层中间抽象,可以在这里实现具体组件库的适配。
- 预置组(Presets):提供CodeWave平台的默认的,到Vue、React翻译的插件配置。
- 微前端:支持飞冰、乾坤开箱即用,支持接入自研的微前端框架。
- 应用代码生成器:加载各个插件,负责驱动整个代码生成流程。应用代码生成器从本质上来讲也是一个插件。
- ...(随着接口的开放,插件系统可以为源码定制提供更多的可能性)
开发者若有源码的定制需求,可以通过插件系统提供的机制,实现对源码的定制。
插件系统
目前插件有两种形态共存。
- 通过
makePlugin
函数实现的简单插件。这些插件在API文档中展示为后缀为Plugin
的Variable
。 - 通过依赖注入库
inversify
实现的依赖注入插件。这些插件在API文档中展示为后缀为Plugin
的Class
。
简单插件会逐渐向依赖注入插件演进。把一个makePlugin
实现的插件迁移到inversify
实现的依赖注入插件不需要对逻辑做太多的改造,成本比较低。
简单插件
从makePlugin
函数实现插件是非常简单的:
export interface NASLPlugin<Functions extends {} = {}> {
name: string;
functions: Functions;
}
export function makePlugin<Functions extends {}>({
name,
functions,
}: NASLPlugin<Functions>) {
const plugin = {
name,
functions,
};
return plugin;
}
修改从makePlugin
创建的插件也非常简单,只需要覆写其functions
属性中的对应方法即可。
依赖注入插件
依赖注入插件所依靠的依赖注入(DI,Dependency Injection)机制,使用inversify来实现。
通过在依赖注入容器(DI Container)中针对不同的Token注入不同的服务,就可以将整个代码生成服务中用到的某个插件完全替换;也可以为了方便直接修改依赖注入插件类的prototype
上的方法来改变它的行为。
修改依赖注入插件的例子请参考快速上手。
预置定制点
我们将一些常见的定制点预置成为插件。通过扩展、配置这些插件,就可以实现常见需求的定制。
package.json
定制
我们提供了 package.json
的定制插件,可以方便地修改项目的脚本(scripts)、生产依赖(dependencies)、开发依赖(devDependencies)等配置项。
项目布局定制
项目布局因项目开发规范而异。根据开发规范调整生成出的项目的目录结构,你可以直接通过配置配置这些插件来实现常见需求的定制。
项目性能优化定制
项目性能优化是前端开发中的重要环节。我们通过插件提供了项目性能常见优化点的配置,方便根据需求对生成出的项目进行性能调优。
前端脚手架定制
目前,导出的源码不使用脚手架,并使用rspack进行打包。我们提供了这个插件将对打包过程的定制权力完全交给你。
你可以通过将这个插件和package.json
定制插件一起使用,来将项目的打包工具替换成为webpack、Vite或者自研的脚手架。
微前端定制
我们将微前端的入口逻辑封装成为了插件。这个插件默认支持乾坤、飞冰的微前端接入,你也可以通过使用这个插件来让导出的项目接入自研的微前端。
插件的依赖关系
graph LR
helper[playground/helper.ts]
compile[src/compile.ts]
default-container[src/default-container.ts]
translate-nasl-to-react-app[src/translate-nasl-to-react-app.ts]
project-organization-plugin[src/plugins/misc/project-organization-plugin.ts]
ir-builder-plugin[src/plugins/ir-builder-plugin.ts]
micro-frontend-plugin[src/plugins/misc/micro-frontend/micro-frontend-plugin.ts]
javascript-codegen-plugin[src/plugins/language/javascript-codegen-plugin.ts]
metadata-plugin[src/plugins/misc/metadata-plugin.ts]
defaultErrorMessage[src/plugins/language/asset/defaultErrorMessage.ts]
microApp[src/plugins/misc/micro-frontend/script/microApp.ts]
icestark[src/plugins/misc/micro-frontend/script/icestark.ts]
qiankun[src/plugins/misc/micro-frontend/script/qiankun.ts]
react-codegen-plugin[src/plugins/react/react-codegen-plugin.ts]
react-router-plugin[src/plugins/react/react-router-plugin.ts]
api-client-plugin[src/plugins/api-client-plugin.ts]
jsx-codegen-plugin[src/plugins/language/jsx-codegen-plugin.ts]
code-format-plugin[src/plugins/misc/code-format-plugin.ts]
file-system-plugin[src/plugins/misc/file-system/file-system-plugin.ts]
routes-extraction-plugin[src/plugins/misc/routes-extraction-plugin.ts]
react-component-lib-hack-plugin[src/plugins/react/react-component-lib-hack-plugin.ts]
react-slot-plugin[src/plugins/react/react-slot-plugin.ts]
react-state-manager-mobx-plugin[src/plugins/react/react-state-manager-mobx-plugin.ts]
react-state-manager-vanilla-plugin[src/plugins/react/react-state-manager-vanilla-plugin.ts]
class app myClass1
helper --> compile
compile --> default-container
compile --> translate-nasl-to-react-app
compile --> project-organization-plugin
default-container --> ir-builder-plugin
default-container --> micro-frontend-plugin
ir-builder-plugin --> javascript-codegen-plugin
ir-builder-plugin --> metadata-plugin
javascript-codegen-plugin --> defaultErrorMessage
micro-frontend-plugin --> microApp
microApp --> icestark
microApp --> qiankun
translate-nasl-to-react-app --> project-organization-plugin
project-organization-plugin --> react-codegen-plugin
project-organization-plugin --> react-router-plugin
react-codegen-plugin --> api-client-plugin
react-codegen-plugin --> ir-builder-plugin
react-codegen-plugin --> javascript-codegen-plugin
react-codegen-plugin --> jsx-codegen-plugin
react-codegen-plugin --> code-format-plugin
react-codegen-plugin --> file-system-plugin
react-codegen-plugin --> metadata-plugin
react-codegen-plugin --> project-organization-plugin
react-codegen-plugin --> routes-extraction-plugin
react-codegen-plugin --> react-component-lib-hack-plugin
react-codegen-plugin --> react-router-plugin
react-codegen-plugin --> react-slot-plugin
react-codegen-plugin --> react-state-manager-mobx-plugin
react-codegen-plugin --> react-state-manager-vanilla-plugin
api-client-plugin --> react-codegen-plugin
jsx-codegen-plugin --> react-codegen-plugin
react-component-lib-hack-plugin --> ir-builder-plugin
react-component-lib-hack-plugin --> react-codegen-plugin
react-router-plugin --> javascript-codegen-plugin
react-router-plugin --> jsx-codegen-plugin
react-router-plugin --> routes-extraction-plugin
react-router-plugin --> react-codegen-plugin
react-slot-plugin --> ir-builder-plugin
react-state-manager-mobx-plugin --> ir-builder-plugin
react-state-manager-mobx-plugin --> react-codegen-plugin
react-state-manager-mobx-plugin --> react-state-manager-vanilla-plugin
react-state-manager-vanilla-plugin --> ir-builder-plugin
react-state-manager-vanilla-plugin --> javascript-codegen-plugin
react-state-manager-vanilla-plugin --> react-codegen-plugin