在本系列的上一篇博客中,笔者分享了如何在Nocobase中创建插件,但那个插件太简单,仅仅注册了collection,今天要分享的是如何用plugin创建页面,并且打包分发,这在对Nocobase进行定制化相当有用。
创建插件
我们还是打开Nocobase开发环境,新建一个插件, 例如 @merthmagic/plugin-add-page
yarn pm create @merthmagic/plugin-add-page
创建成功后,插件代码在package/plugins/@merthmagic/plugin-add-page
下.
创建单个页面
Nocobase是基于react的,所以创建页面组件和react一样. 我们先创建一个about
页面做个简单的测试.
在src/client/
目录下,有个index.tsx
文件,我们修改这个文件
import React, { useEffect } from 'react';
import { Plugin, useDocumentTitle } from '@nocobase/client';
const AboutPage = () => {
const { setTitle } = useDocumentTitle();
useEffect(() => {
setTitle('About');
}, []);
return (<div>About Page</div>);
}
export class PluginAddPageClient extends Plugin {
async afterAdd() {
// await this.app.pm.add()
}
async beforeLoad() { }
// You can get and modify the app instance here
async load() {
console.log(this.app);
this.app.router.add('about', {
path: '/about',
Component: AboutPage,
});
// this.app.addComponents({})
// this.app.addScopes({})
// this.app.addProvider()
// this.app.addProviders()
// this.app.router.add()
}
}
export default PluginAddPageClient;
保存代码后,开发环境自动编译,编译完成后,打开http://localhost:13000/about
,发现可以访问了。
创建嵌套页面
刚才创建的是单个页面,如果我们希望创建嵌套路由的页面,并挂载到默认的admin
路径下,可以如下操作。
首先,我们创建一个单独的文件,放置页面组件,如 MaterialPage.tsx
import React, { useEffect } from 'react';
import { Outlet, Link } from 'react-router-dom';
import { useDocumentTitle } from '@nocobase/client';
export const MaterialPage = () => {
return (
<div>
<h1>Material Page</h1>
<ul>
<li>
<Link to="video">Video</Link>
</li>
<li>
<Link to="image">Image</Link>
</li>
</ul>
<Outlet></Outlet>
</div>
)
}
export const MaterialVideo = () => {
const { setTitle } = useDocumentTitle();
useEffect(() => {
setTitle('Material Video')
}, []);
return (<div>Material Video</div>)
}
export const MateriaImage = () => {
const { setTitle } = useDocumentTitle();
useEffect(() => {
setTitle('Material Image')
}, []);
return (<div>Material Image</div>)
}
然后在插件的index.ts
中引用这个文件,并且进行路由的挂载,此时,代码修改如下:
import React, { useEffect } from 'react';
import { Plugin, useDocumentTitle } from '@nocobase/client';
import { MaterialPage, MaterialVideo, MateriaImage } from './MaterialPage'
const AboutPage = () => {
const { setTitle } = useDocumentTitle();
useEffect(() => {
setTitle('About');
}, []);
return (<div>About Page</div>);
}
export class PluginAddPageClient extends Plugin {
async afterAdd() {
// await this.app.pm.add()
}
async beforeLoad() { }
// You can get and modify the app instance here
async load() {
console.log(this.app);
this.app.router.add('about', {
path: '/merthmagic/about',
Component: AboutPage,
});
this.app.router.add('admin.material', {
path: '/admin/material',
Component: MaterialPage,
})
this.app.router.add('admin.material.video', {
path: '/admin/material/video',
Component: MaterialVideo,
})
this.app.router.add('admin.material.image', {
path: '/admin/material/image',
Component: MateriaImage,
})
// this.app.addComponents({})
// this.app.addScopes({})
// this.app.addProvider()
// this.app.addProviders()
// this.app.router.add()
}
}
export default PluginAddPageClient;
通过代码我们可以看到,为了挂载在admin下,app.router.add
方法调用时,变成了this.app.router.add('admin.material',...)
, 这样就可以实现向某个已有的路由下挂载子路由.
打开页面,发现已经可以访问
打包分发
以上是在开发环境进行的开发,在开发完成后,还需要打包后安装到生产环境。通过yarn打包即可.
首先进行一次全量编译,让plugin把依赖的package全部也打包:
# 在项目根目录执行
yarn build
全量编译后,打包plugin:
yarn build @merthmagic/plugin-add-page --tar
如果看到类似下面的输出信息,则打包成功
yarn run v1.22.22
$ nocobase build @merthmagic/plugin-add-page --tar
$ tsup
@merthmagic/plugin-add-page: plugins/@merthmagic/plugin-add-page build start
@merthmagic/plugin-add-page: build plugin client
@merthmagic/plugin-add-page: build plugin server source
@merthmagic/plugin-add-page: delete server files
@merthmagic/plugin-add-page: build plugin server dependencies
@merthmagic/plugin-add-page: These packages @nocobase/server will be exclude. For more information, please refer to: https://docs.nocobase.com/development/deps.
@merthmagic/plugin-add-page: write external version
@merthmagic/plugin-add-page: build declaration
(node:50729) [DEP0180] DeprecationWarning: fs.Stats constructor is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
@merthmagic/plugin-add-page: tar package
✨ Done in 14.22s.
打包完成后,在项目根目录的storage/tar
目录下,可以找到打包后的.tgz
文件,在生产环境的插件管理页面上传即可安装启用.