包构建及服务端渲染模板生成配置
=====


base.config.js
-----
> 构建基本的webpack配置，配置了引用别名及相关loaders

##### 引用别名：

| 路径 | 别名 | 文件夹解释 |
| --- | --- | --- |
| path/src/modules | @Modules  | [编辑器quill的模块文件夹，提供编辑器的一系列扩展能力](./modules.md) |
| path/src/themes  | @Themes   | [编辑器的主题配置，主要控制编辑器工具栏的表现](./themes.md) |
| path/src/formats | @Formats  | [编辑器的一系列带有自定义格式化信息的内容节点](./formats.md) |
| path/src/styles  | @Styles   | [编辑器的样式文件，包括核心样式，及各个主题的样式文件](./styles.md) |
| path/src/assets  | @Assets   | [icon等静态文件](./assets.md) |
| path/src/ui      | @UI       | [工具栏辅助的UI文件，比如一些pickers和tips](./ui.md) |
| path/src/components | @Components | [自定义格式化信息的渲染组件（注：与框架无关、通过原生js、vue、react都可以正常渲染）](./components.md) |
| path/src/utils      | @Utils       | [编辑器辅助函数](./utils.md) |
| path/src/matchers      | @Matchers       | [编辑器粘贴模块辅助的matchers](./matchers.md) |




buildHelpers.js
-----
> 构建辅助函数

##### blotsEntriesGenerator

执行函数，生成自定义格式化信息内容节点的服务端渲染的入口文件、输出路径配置。

遍历components文件夹下一级目录下的server.entry.js作为入口文件，并在dist/commonjs2/的同名目录下输出。


##### coreEntriesGenerator

执行函数，以src/core下的所有js文件作为入口文件，并在dist/umd的同名目录下输出。


GenerateBlotTemplatePlugin.js
-----
> 自定义格式化信息节点内容的服务端渲染模板生成插件

确保在VueSSRServerPlugin之后使用该插件。该插件主要为java服务端渲染时所需的html的生成服务。其在初始化使用时传入的配置与formats文件夹下的所有自定义节点以及components下自定义节点的渲染组件存在着耦合。

举例来讲：

我们需要给编辑器增加图片自定义展示的功能。一般会有以下几个步骤。

* 第一步：在formats文件夹下新增一个用于展示图片的自定义节点

```
// ImageBlot.js

// 引入组件的渲染函数
import renderer from '@Components/image/client.entry.js'
class ImageBlot extends BlockEmbed {
    static create(value) {
        // 创建自定义节点的domNode
        const node = super.create()
        // 调用组件的渲染函数
        renderer(node, value)
        // 将渲染好的dom返回给quill
        return node
    }
}
ImageBlot.className = 'hdf-image'
ImageBlot.tagName = 'DIV'
ImageBlot.name = 'image'
```

* 第二步：在components下新增图片的渲染函数

```
// createComponent.js

import Vue from 'vue'
import Image from './Image.vue'

export default (props) => {
    const Constructor = Vue.extend(Image)
    const component = new Constructor({
        propsData: { ...props },
        data: {
            // 初始化vue组件的data
        }
    })
    return { component }
}
```

* 第三步：新增客户端渲染入口文件

```
// client.entry.js

import createComponent from './createComponent';

export default (dom, ctx) => {
  const { component } = createComponent(ctx);
  component.$mount();
  dom.appendChild(component.$el);
};

```

* 第四步： 新增服务端渲染入口文件

```
// server.entry.js

import createComponent from './createComponent';

export default (ctx) => {
  const { component } = createComponent(ctx);
  return component;
};

```
我们注意到：服务端渲染生成的模板，需要有一些初始化的props，并且其外层需要包裹上一层类名为Blot.className，标签为Blot.tagName的dom元素才能与客户端渲染时的输出匹配。

所以使用该插件时需要传递两个参数：
* props(每个VueSSR模板生成时的初始props)
* containerClassName(组件的包裹容器类名)

```
plugins: [
    new VueSSRServerPlugin(),
    new GenerateBlotTemplatePlugin({
        props: {
            image: {
                url: 'url#{[attachmentId]}',
                attachmentId: '#{[attachmentId]}'
            }
        },
        containerClassName: {
            image: 'hdf-image'
        }
    })
]

```

备注： 初始化的props值完全是为了java服务端渲染时的正则匹配服务的，他们在组装html时，读取的数据形如

```
{
    content: [
        { insert: { image: { attachemntId: 1, width: 2, ... }}}
    ]，
    attchmentMap: {
        1: { url: 'xxxx'，... }
    }
}

```

url等信息是在attachmentMap上存储的，所以需要attachmentId作为标识做第一次匹配，然后再以#号前面的字段做二次匹配组装数据

备注：包裹容器的标签名建议使用DIV，就不在作为配置参数传入


devServer.config.js
-----
>demo文件夹下示例页面的开发服务配置

blot.server.config.js
-----
>自定义组件服务端渲染模板生成配置

prd.config.js
-----
>core文件下编辑器模块及详情页激活代码输出配置



















