Skip to content
This repository has been archived by the owner on Apr 24, 2023. It is now read-only.

Canner Schema Loader

Siou edited this page Mar 15, 2018 · 15 revisions

Why do we need canner-schema-loader

CannerCMS 這個 component 是由 Provider 以及 Generator 兩個 component 所組合而成, Provider 負責處理資料的一切,包括儲存、快取、優化、發布、抓取資料等等,而 Generator 則負責渲染整個 CMS 的 UI。

Provider 中需要 jsonSchema 去做資料處理,在 Generator 中需要 componentTree 去渲染畫面,但 jsonSchema 以及 componentTree 都是由 CannerTypes 語法去產生, 為了簡化開發流程以及避免在執行階段做過多的運算,我們將這些步驟在 webpack 打包過程中做完。參考以下例子:

// webpack.config.js

loaders: [{
  test: 'canner.schema.js',
  loader: '@canner/canner.schema.js'
}]

canner.schema.js

module.exports = {
  info: CannerTypes.object({
    name: CannerTypes.string().title('Name')
  }).title('Info')
}

CMS

import {CMS} from '@canner/react-cms-core';
// we can get a object including the `jsonSchema` and `componentTree`
import {jsonSchema, componentTree} from 'canner.schema.js';

//return part
return <CMS
  {...OtherProps}
  schema={{jsonSchema, componentTree}}
/>

How does it work?

需求

  • developers can choose their components
  • support dynamic import, to let bundle smaller

implement

CannerTypes and ComponentMap

在 CannerTypes 中應該會有一個 default componentMap 例如:

{
  [type: string]: {
    [ui: string]: string 
  }
}

使用 CannerTypes method toJSON()時,如果能在 componentMap 利用 type 以及 ui 裡面找到對應的值,就會將 componentName 設為該值,若沒有,則直接將 ui 設定為該值,例如:

/** componentMap */
{
  string: {
    input: '@canner/antd-string-component-input'
  }
}

/** canner.schema */

CannerTypes.string().ui('input')
// {
//   type: 'string',
//   ui: 'input',
//   componentName: '@canner/antd-string-component-input'
// }
CannerTypes.string().ui('my-own-string-component')
// {
//   type: 'string',
//   ui: 'my-own-string-component',
//   componentName: 'my-own-string-component'
// }
CannerTypes.defineUI('string.input1', 'other-string-component');
CannerTypes.string().ui('input1')
// {
//   type: 'string',
//   ui: 'input1',
//   componentName: 'other-string-component'
// }

choose component

componentTree 要能夠包含 component name 的資訊,在 canner-schema-loader 就可以將 component name 替換成 requre.ensure() 放置在 loader 之中。

// the node of componentTree
{
  componentName: '@canner/antd-string-component-input'
}
// change to 
{
  loader: require.ensure()...
}

dynamic import

Generator 可以從 componentTree 取得每個 component 的 loader 並在 prerender 階段作為 react-roadable component 的 property loader.

// the node of componentTree
{
  loader: require.ensure([])...
}
// prerender in generator
{
  component: Loadable({
    loader: () => node.loader, // pass loader
    loading: LoadingComponnet,
  });
}

原本流程的整合

使用者利用 cli 將 componenTree 上傳到 db restfulQa page 直接拿取這個 componentTree 去 render

限制以及問題

  1. 是否 ui 會用在更多地方?
  • 在 visitors hocs 會利用 ui 判斷是否需要多加 miniApp 以及 是否使用 query link
  • routeMiniApp 判斷 link
  • qa-compiler pareser link
Clone this wiki locally