diff --git a/docs/reference/plugin/plugins/layout.md b/docs/reference/plugin/plugins/layout.md
index 67609352..84ff6d3f 100644
--- a/docs/reference/plugin/plugins/layout.md
+++ b/docs/reference/plugin/plugins/layout.md
@@ -1,7 +1,7 @@
# @fesjs/plugin-layout
## 介绍
-为了进一步降低研发成本,我们尝试将布局通过 fes 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。
+为了进一步降低研发成本,我们将布局利用 `fes.js` 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。
- 侧边栏菜单数据根据路由中的配置自动生成。
- 布局,提供 `side`、 `top`、`mixin` 三种布局。
- 主题,提供 `light`、`dark` 两种主题。
@@ -19,21 +19,14 @@
```json
{
"dependencies": {
- "@fesjs/fes": "^2.0.0",
- "@fesjs/plugin-layout": "^4.0.0"
+ "@fesjs/fes": "^3.0.0",
+ "@fesjs/plugin-layout": "^5.0.0"
},
}
```
## 布局类型
-配置参数是 `navigation`, 布局有三种类型 `side`、`mixin` 和 `top`, 默认是 `side`:
-```js
-export default {
- layout: {
- navigation: 'side'
- }
-}
-```
+配置参数是 `navigation`, 布局有三种类型 `side`、`mixin` 和 `top`, 默认是 `side`。
### side
@@ -47,8 +40,33 @@ export default {
-### 页面禁用布局
-布局是默认开启的,但是可能某些页面不需要展示布局样式,比如登录页面。我们只需要在页面的`.vue`中添加如下配置:
+### 布局开关
+
+布局默认开启,可以通过一些方式更改。
+
+开关的可选配置有:
+
+- **sidebar**: 左侧区域
+
+- **header**: 头部区域
+
+- **logo**:logo和标题区域。
+
+#### 全局定义
+
+全局定义可以通过配置`switch`实现,在 `app.js` 中配置:
+```js
+import UserCenter from '@/components/UserCenter';
+export const layout = {
+ switch: {
+ header: false
+ }
+};
+
+```
+
+#### 页面定义
+可以通过[定义路由元信息](../../../guide/route.html#扩展路由元信息)配置页面的布局开关,添加如下配置:
```vue
{
@@ -66,17 +84,15 @@ export default {
}
```
-`layout`的可选配置有:
-- **sidebar**: 左侧区域,从v4.0.0开始,之前名称叫`side`
-
-- **header**: 头部区域,从v4.0.0开始,之前名称叫`top`
-
-- **logo**:logo和标题区域。
+#### 地址参数定义
+通过路由的`query`参数定义,比如当访问`http://localhost:8080/#/?layout={%22sidebar%22:%20false,%20%22header%22:%20false}` 时,页面隐藏 `sidebar`和`header`区域。此种方式优先级最高!
-## keep-alive
-从 4.0.7 开始支持配置路由页面缓存:
+
+## 页面缓存
+
+支持配置页面缓存,通过[定义路由元信息](../../../guide/route.html#扩展路由元信息)开启缓存:
```
{
@@ -85,7 +101,10 @@ export default {
```
-## 编译时配置
+## 配置
+
+#### 编译时配置方式
+
在 `.fes.js` 中配置:
```js
export default {
@@ -95,17 +114,7 @@ export default {
// 底部文字
footer: 'Created by MumbleFE',
// 主题light
- theme: 'dark'
- // 是否开启 tabs
- multiTabs: false,
- // 布局类型
- navigation: 'side',
- // 是否固定头部
- fixedHeader: false,
- // 是否固定sidebar
- fixedSideBar: true,
- // sidebar的宽度
- sideWidth: 200,
+ theme: 'dark',
menus: [{
name: 'index'
}, {
@@ -115,14 +124,51 @@ export default {
}, {
name: 'simpleList'
}],
- menuConfig: {
- defaultExpandAll: false,
- expandedKeys: [],
- accordion: false
- }
+
},
```
+#### 运行时配置方式
+
+在 `app.js` 中配置:
+```js
+import UserCenter from '@/components/UserCenter';
+export const layout = {
+ renderHeader: ()=> ,
+ menus: [{
+ name: 'index'
+ }]
+};
+
+```
+在`fes.js`中,运行时配置有定义对象和函数两种方式,当使用函数配置`layout`时,`layoutConfig`是编译时配置结果,`initialState`是 `beforeRender.action`执行后创建的应用初始状态数据。
+。
+```js
+export const layout = (layoutConfig, { initialState }) => ({
+ renderHeader: () => ,
+ menus: () => {
+ const menusRef = ref(layoutConfig.menus);
+ watch(
+ () => initialState.userName,
+ () => {
+ menusRef.value = [
+ {
+ name: 'store',
+ },
+ ];
+ },
+ );
+ return menusRef;
+ },
+});
+```
+
+最终配置结果是运行时配置跟编译时配置合并的结果,运行时配置优先于编译时配置。
+
+实际上运行配置能做的事情更多,推荐用运行时配置方式。
+
+
+
### footer
- **类型**:`String`
@@ -144,14 +190,14 @@ export default {
- **详情**:页面布局类型,可选有 `side`、 `top`、 `mixin`
-### fixedHeader
+### isHeaderFixed
- **类型**:`Boolean`
- **默认值**:`false`
- **详情**:是否固定头部,不跟随页面滚动。
-### fixedSideBar
+### isSidebarFixed
- **类型**:`Boolean`
- **默认值**:`true`
@@ -161,14 +207,14 @@ export default {
### title
- **类型**:`String`
-- **默认值**:`name` in package.json
+- **默认值**:默认为 [编译时配置title](../../../reference/config/#title)
-- **详情**:产品名,会显示在 Logo 旁边。
+- **详情**:产品名。
### logo
- **类型**:`String`
-- **默认值**:默认提供 fes.js 的 Logo
+- **默认值**:默认提供 `fes.js` 的 Logo
- **详情**:Logo的链接
@@ -181,7 +227,7 @@ export default {
- **详情**:是否开启多页。
### menus
-- **类型**:`Array`
+- **类型**:`[] | ()=> Ref<[]>`
- **默认值**:`[]`
@@ -203,13 +249,11 @@ export default {
- **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。
- **icon**: 菜单的图标,只有一级标题展示图标。
- - 图标使用[fes-design icon](https://fes-design-4gvn317r3b6bfe17-1254145788.ap-shanghai.app.tcloudbase.com/zh/components/icon.html),在这里使用组件名称。
-```js
-{
- icon: "AppstoreOutlined"
-}
-```
+
+ - 图标使用[fes-design icon](https://fes-design-4gvn317r3b6bfe17-1254145788.ap-shanghai.app.tcloudbase.com/zh/components/icon.html),编译时配置使用组件名称,我们会自动引入组件。
+
- 图标使用本地或者远程svg图片。
+
```js
{
icon: "/wine-outline.svg"
@@ -218,7 +262,13 @@ export default {
- **children**:子菜单配置。
-### menusConfig
+:::tip
+函数类型仅在运行时可用,可以实现动态变更菜单。
+:::
+
+
+
+### menusProps
- **类型**:`Object`
- **默认值**:`{}`
@@ -231,84 +281,42 @@ export default {
- **accordion**:是否只保持一个子菜单的展开。
-## 运行时配置
-在 `app.js` 中配置:
-```js
-import UserCenter from '@/components/UserCenter';
-export const layout = {
- customHeader:
-};
-```
-
-### menus
-- **类型**:`(defaultMenus: [] )=> Ref | []`
+ ### switch
+- **类型**:`Object`
-- **详情**:运行时修改菜单,入参是默认菜单配置(.fes.js中的menu配置),需要返回一个`Ref`或者数组。
+- **默认值**:`{ logo: true, sidebar: true, header: true }`
-```js
-import { ClusterOutlined } from '@fesjs/fes-design/icon'
-export const layout = layoutConfig => ({
- ...layoutConfig,
- customHeader: ,
- menus: (defaultMenuData) => {
- const menusRef = ref(defaultMenuData);
- watch(() => layoutConfig.initialState.userName, () => {
- menusRef.value = [{
- name: 'store',
- icon:
- }];
- });
- return menusRef;
- }
-});
-
-```
-`layoutConfig.initialState` 是 `beforeRender.action`执行后创建的应用初始状态数据。
-
-如果菜单需要根据某些状态动态改变,则返回`Ref`,否则只需要返回数组。
-
-:::tip
-在运行时配置菜单中的icon,需要传组件本身,而不是组件的名称。
-:::
-
-
-### header
-- **类型**:`String`
+- **详情**:布局的开关:
-- **默认值**:`true`
-
-- **详情**:是否显示 header 区域。
-
-### sidebar
-- **类型**:`String`
+ - **logo**:是否展示logo区域。
-- **默认值**:`true`
+ - **sidebar**:配置默认展开的菜单,需要传子项是菜单路径的数组。
-- **详情**:是否显示 sidebar 区域。
+ - **header**:是否只保持一个子菜单的展开。
-### logo
-- **类型**:`String`
+### sideWidth
+- **类型**:`Number`
-- **默认值**:`true`
+- **默认值**:`200`
-- **详情**:是否显示 logo 区域。
+- **详情**:sidebar的宽度
+
-### customHeader
-- **类型**:Vue Component
+### renderHeader
+- **类型**: `()=> VNodes`
- **默认值**:`null`
-- **详情**:top的区域部分位置提供组件自定义功能。
+- **详情**: 自定义`top`区域部分位置,仅运行时。
+
### unAccessHandler
-- **类型**:`Function`
+- **类型**:`({ to, from, next})=> void`
- **默认值**:`null`
-- **详情**:
-
- 当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。
+- **详情**:仅运行时,当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。
- **参数**
- router:createRouter 创建的路由实例
- to: 准备进入的路由
@@ -334,13 +342,11 @@ export const access = {
```
### noFoundHandler
-- **类型**:函数
+- **类型**:`({ to, from, next})=> void`
-- **默认值**:null
+- **默认值**:`null`
-- **详情**:
-
- 当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。
+- **详情**:仅运行时,当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。
- **参数**
- router:createRouter 创建的路由实例
- to: 准备进入的路由
@@ -360,14 +366,3 @@ export const access = {
};
```
-
-### logoUrl
-- **类型**:`String`
-
-- **默认值**:默认提供 fes.js 的 Logo
-
-- **详情**:Logo的链接。
-
-
-### 其他运行时配置 (> 4.1.0)
-编译时配置的内容同样支持在运行时配置,但是`logo`除外,用`logoUrl`替代。
\ No newline at end of file
diff --git a/packages/fes-plugin-layout/src/index.js b/packages/fes-plugin-layout/src/index.js
index eff1a9f5..09b5935c 100644
--- a/packages/fes-plugin-layout/src/index.js
+++ b/packages/fes-plugin-layout/src/index.js
@@ -24,16 +24,16 @@ export default (api) => {
api.addRuntimePluginKey(() => 'layout');
- const absFilePath = join(namespace, 'index.jsx');
+ const absFilePath = join(namespace, 'views/index.jsx');
+
+ const absConfigFilePath = join(namespace, 'helpers/getConfig.js');
const absRuntimeFilePath = join(namespace, 'runtime.js');
api.onGenerateFiles(async () => {
- const HAS_LOCALE = api.hasPlugins(['@fesjs/plugin-locale']);
-
// .fes配置
const userConfig = {
- title: api.pkg.name,
+ title: api.title,
footer: 'Created by Fes.js',
...(api.config.layout || {}),
};
@@ -52,9 +52,15 @@ export default (api) => {
api.writeTmpFile({
path: absFilePath,
- content: Mustache.render(readFileSync(join(__dirname, 'runtime/index.tpl'), 'utf-8'), {
+ content: Mustache.render(readFileSync(join(__dirname, 'runtime/views/index.tpl'), 'utf-8'), {
+ REPLACE_USER_CONFIG: JSON.stringify(userConfig),
+ }),
+ });
+
+ api.writeTmpFile({
+ path: absConfigFilePath,
+ content: Mustache.render(readFileSync(join(__dirname, 'runtime/helpers/getConfig.tpl'), 'utf-8'), {
REPLACE_USER_CONFIG: JSON.stringify(userConfig),
- HAS_LOCALE,
}),
});
@@ -67,6 +73,13 @@ export default (api) => {
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
+ api.addPluginExports(() => [
+ {
+ specifiers: ['Page'],
+ source: join(namespace, 'index.js'),
+ },
+ ]);
+
// 把BaseLayout插入到路由配置中,作为根路由
api.modifyRoutes((routes) => [
{
diff --git a/packages/fes-plugin-layout/src/node/helper.js b/packages/fes-plugin-layout/src/node/helper.js
index effedb72..67a318b0 100644
--- a/packages/fes-plugin-layout/src/node/helper.js
+++ b/packages/fes-plugin-layout/src/node/helper.js
@@ -1,19 +1,15 @@
-
export function getIconNamesFromMenu(data) {
if (!Array.isArray(data)) {
return [];
}
let icons = [];
- data.forEach((item = { path: '/' }) => {
+ data.forEach((item) => {
if (item.icon) {
const { icon } = item;
// 处理icon
if (icon) {
const urlReg = /^((https?|ftp|file):\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
- if (
- typeof icon === 'string'
- && !(urlReg.test(icon) || icon.includes('.svg'))
- ) {
+ if (typeof icon === 'string' && !(urlReg.test(icon) || icon.includes('.svg'))) {
icons.push(icon);
}
}
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl b/packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl
new file mode 100644
index 00000000..94934d50
--- /dev/null
+++ b/packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl
@@ -0,0 +1,15 @@
+import { plugin, ApplyPluginsType } from '@@/core/coreExports';
+import { initialState } from '@@/initialState';
+
+export default () => {
+ const initConfig = {{{REPLACE_USER_CONFIG}}}
+ const runtimeConfig = plugin.applyPlugins({
+ key: 'layout',
+ type: ApplyPluginsType.modify,
+ initialValue: initConfig,
+ args: {
+ initialState
+ }
+ });
+ return runtimeConfig;
+};
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js b/packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js
deleted file mode 100644
index 1ca1ef5c..00000000
--- a/packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { plugin, ApplyPluginsType } from '@@/core/coreExports';
-import { initialState } from '@@/initialState';
-
-let runtimeConfig;
-
-export default () => {
- if (!runtimeConfig) {
- runtimeConfig = plugin.applyPlugins({
- key: 'layout',
- type: ApplyPluginsType.modify,
- initialValue: {
- initialState,
- sidebar: true,
- header: true,
- logo: true,
- },
- });
- }
- return runtimeConfig;
-};
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js b/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
index 7b14a599..a18b90bd 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
@@ -3,9 +3,7 @@ import { computed, ref } from 'vue';
import { useAccess } from '../../plugin-access/core';
if (!useAccess) {
- throw new Error(
- '[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!'
- );
+ throw new Error('[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!');
}
export const hasAccessByMenuItem = (item) => {
@@ -14,21 +12,26 @@ export const hasAccessByMenuItem = (item) => {
return useAccess(item.path);
}
if (hasChild) {
- return computed(() => item.children.some((child) => {
- const rst = hasAccessByMenuItem(child);
- return rst && rst.value;
- }));
+ return computed(() =>
+ item.children.some((child) => {
+ const rst = hasAccessByMenuItem(child);
+ return rst && rst.value;
+ }),
+ );
}
return ref(true);
};
-export const transform = menus => menus.map((menu) => {
- const hasAccess = hasAccessByMenuItem(menu);
- if (!hasAccess.value) {
- return false;
- }
- if (menu.children) {
- menu.children = transform(menu.children);
- }
- return menu;
-}).filter(Boolean);
+export const transform = (menus) =>
+ menus
+ .map((menu) => {
+ const hasAccess = hasAccessByMenuItem(menu);
+ if (!hasAccess.value) {
+ return false;
+ }
+ if (menu.children) {
+ menu.children = transform(menu.children);
+ }
+ return menu;
+ })
+ .filter(Boolean);
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js b/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
index 4682d7d2..fc2a6693 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
@@ -12,14 +12,14 @@ export const transTitle = (name) => {
return name;
};
-
-export const transform = menus => menus.map((menu) => {
- const copy = {
- ...menu,
- label: transTitle(menu.label)
- };
- if (menu.children) {
- copy.children = transform(menu.children);
- }
- return copy;
-});
+export const transform = (menus) =>
+ menus.map((menu) => {
+ const copy = {
+ ...menu,
+ label: transTitle(menu.label),
+ };
+ if (menu.children) {
+ copy.children = transform(menu.children);
+ }
+ return copy;
+ });
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/utils.js b/packages/fes-plugin-layout/src/runtime/helpers/utils.js
index e8b16aa7..29750c4d 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/utils.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/utils.js
@@ -1,9 +1,8 @@
-export const flatNodes = (nodes = []) => nodes.reduce((res, node) => {
- res.push(node);
- if (node.children) {
- res = res.concat(
- flatNodes(node.children)
- );
- }
- return res;
-}, []);
+export const flatNodes = (nodes = []) =>
+ nodes.reduce((res, node) => {
+ res.push(node);
+ if (node.children) {
+ res = res.concat(flatNodes(node.children));
+ }
+ return res;
+ }, []);
diff --git a/packages/fes-plugin-layout/src/runtime/index.js b/packages/fes-plugin-layout/src/runtime/index.js
new file mode 100644
index 00000000..61271e73
--- /dev/null
+++ b/packages/fes-plugin-layout/src/runtime/index.js
@@ -0,0 +1,3 @@
+import page from './views/page.vue';
+
+export const Page = page;
diff --git a/packages/fes-plugin-layout/src/runtime/index.tpl b/packages/fes-plugin-layout/src/runtime/index.tpl
deleted file mode 100644
index 2ac3c057..00000000
--- a/packages/fes-plugin-layout/src/runtime/index.tpl
+++ /dev/null
@@ -1,79 +0,0 @@
-import { ref, defineComponent, computed } from 'vue';
-import { plugin, ApplyPluginsType, } from '@@/core/coreExports';
-import { getRoutes } from '@@/core/routes/routes'
-import BaseLayout from './views/BaseLayout.vue';
-import getRuntimeConfig from './helpers/getRuntimeConfig';
-import fillMenu from './helpers/fillMenu';
-
-const Layout = defineComponent({
- name: 'Layout',
- setup() {
- const userConfig = {{{REPLACE_USER_CONFIG}}};
- const runtimeConfig = getRuntimeConfig();
- const {
- menus,
- customHeader,
- menuConfig,
- // 非 BaseLayout需要的
- initialState,
- sidebar,
- header,
- logo,
- // 跟logo冲突,换个名字
- logoUrl,
- ...otherConfig
- } = runtimeConfig;
- if (logoUrl) {
- userConfig.logo = logoUrl;
- }
- if (menuConfig && typeof menuConfig === 'object') {
- Object.assign(userConfig.menuConfig, menuConfig);
- }
- Object.keys(otherConfig).forEach((p) => {
- if (otherConfig[p] !== undefined) {
- userConfig[p] = otherConfig[p];
- }
- });
- let menusRef = ref(userConfig.menus);
- // 如果运行时配置了menus,则需要处理
- if (menus && typeof menus === 'function') {
- menusRef = ref(menus(userConfig.menus));
- }
- // 把路由的meta合并到menu配置中
- const filledMenuRef = computed(() => {
- return fillMenu(menusRef.value, getRoutes());
- });
-
- const localeShared = plugin.getShared('locale');
- return () => {
- const slots = {
- customHeader: () => {
- if (runtimeConfig.customHeader) {
- return (
-
- );
- }
- return null;
- },
- locale: () => {
- if (localeShared) {
- return (
-
- );
- }
- return null;
- }
- };
- return (
-
- );
- };
- }
-});
-
-export default Layout;
diff --git a/packages/fes-plugin-layout/src/runtime/runtime.js b/packages/fes-plugin-layout/src/runtime/runtime.js
index f0430aa3..2e087953 100644
--- a/packages/fes-plugin-layout/src/runtime/runtime.js
+++ b/packages/fes-plugin-layout/src/runtime/runtime.js
@@ -2,7 +2,8 @@
import { access as accessApi } from '../plugin-access/core';
import Exception404 from './views/404.vue';
import Exception403 from './views/403.vue';
-import getRuntimeConfig from './helpers/getRuntimeConfig';
+// eslint-disable-next-line import/extensions
+import getConfig from './helpers/getConfig';
if (!accessApi) {
throw new Error('[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!');
@@ -24,40 +25,41 @@ const handle = (type, router) => {
}
};
-export const access = (memo) => ({
- unAccessHandler({ router, to, from, next }) {
- const runtimeConfig = getRuntimeConfig();
- if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
- return runtimeConfig.unAccessHandler({
- router,
- to,
- from,
- next,
- });
- }
- if (to.path === '/404') {
- handle(404, router);
- return next('/404');
- }
- handle(403, router);
- next('/403');
- },
- noFoundHandler({ router, to, from, next }) {
- const runtimeConfig = getRuntimeConfig();
- if (runtimeConfig.noFoundHandler && typeof runtimeConfig.noFoundHandler === 'function') {
- return runtimeConfig.noFoundHandler({
- router,
- to,
- from,
- next,
- });
- }
- if (to.path === '/403') {
+export const access = (memo) => {
+ const runtimeConfig = getConfig();
+ return {
+ unAccessHandler({ router, to, from, next }) {
+ if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
+ return runtimeConfig.unAccessHandler({
+ router,
+ to,
+ from,
+ next,
+ });
+ }
+ if (to.path === '/404') {
+ handle(404, router);
+ return next('/404');
+ }
handle(403, router);
- return next('/403');
- }
- handle(404, router);
- next('/404');
- },
- ...memo,
-});
+ next('/403');
+ },
+ noFoundHandler({ router, to, from, next }) {
+ if (runtimeConfig.noFoundHandler && typeof runtimeConfig.noFoundHandler === 'function') {
+ return runtimeConfig.noFoundHandler({
+ router,
+ to,
+ from,
+ next,
+ });
+ }
+ if (to.path === '/403') {
+ handle(403, router);
+ return next('/403');
+ }
+ handle(404, router);
+ next('/404');
+ },
+ ...memo,
+ };
+};
diff --git a/packages/fes-plugin-layout/src/runtime/views/403.vue b/packages/fes-plugin-layout/src/runtime/views/403.vue
index b094bc16..04501ab3 100644
--- a/packages/fes-plugin-layout/src/runtime/views/403.vue
+++ b/packages/fes-plugin-layout/src/runtime/views/403.vue
@@ -6,15 +6,8 @@
d="M0 129.023v-2.084C0 58.364 55.591 2.774 124.165 2.774h2.085c68.574 0 124.165 55.59 124.165 124.165v2.084c0 68.575-55.59 124.166-124.165 124.166h-2.085C55.591 253.189 0 197.598 0 129.023"
fill="#E4EBF7"
>
-
-
+
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
+
diff --git a/scripts/build.mjs b/scripts/build.mjs
index 58c7e3ee..39eee819 100644
--- a/scripts/build.mjs
+++ b/scripts/build.mjs
@@ -104,13 +104,17 @@ function cleanBeforeCompilerResult(pkgName, log) {
function transformFile(filePath, outputPath, config, log) {
if (/\.[jt]sx?$/.test(path.extname(filePath))) {
- const code = fs.readFileSync(filePath, 'utf-8');
- const shortFilePath = genShortPath(filePath);
- const transformedCode = compiler(code, config);
+ try {
+ const code = fs.readFileSync(filePath, 'utf-8');
+ const shortFilePath = genShortPath(filePath);
+ const transformedCode = compiler(code, config);
- const type = config.target === 'browser' ? ESM_OUTPUT_DIR : NODE_CJS_OUTPUT_DIR;
- log(`Transform to ${type} for ${config.target === 'browser' ? chalk.yellow(shortFilePath) : chalk.blue(shortFilePath)}`);
- fse.outputFileSync(outputPath, transformedCode);
+ const type = config.target === 'browser' ? ESM_OUTPUT_DIR : NODE_CJS_OUTPUT_DIR;
+ log(`Transform to ${type} for ${config.target === 'browser' ? chalk.yellow(shortFilePath) : chalk.blue(shortFilePath)}`);
+ fse.outputFileSync(outputPath, transformedCode);
+ } catch (error) {
+ console.error(error);
+ }
} else {
fse.copySync(filePath, outputPath);
}