[
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# Next.js build output\n.next\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and *not* Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">Welcome to H5-Dooring 👋</h1>\n<p>\n  <img alt=\"Version\" src=\"https://img.shields.io/badge/version-1.2-blue.svg?cacheSeconds=2592000\" />\n  <a href=\"https://juejin.im/post/6864410873709592584/\" target=\"_blank\">\n    <img alt=\"Documentation\" src=\"https://img.shields.io/badge/documentation-yes-brightgreen.svg\" />\n  </a>\n  <a href=\"#\" target=\"_blank\">\n    <img alt=\"License: MIT\" src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" />\n  </a>\n</p>\n\n> H5-Dooring是一款功能强大，开源免费的H5可视化页面配置解决方案，致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。技术栈以react为主， 后台采用nodejs开发。\n\n### 🏠 [Homepage](http://h5.dooring.cn/)\n\n### ✨ [Demo](http://h5.dooring.cn/)\n\n\n## 🤝 Contributing\n\nContributions, issues and feature requests are welcome!<br />Feel free to check [issues page](https://github.com/MrXujiang/h5-Dooring/issues). \n\n## Show your support\n\nGive a ⭐️ if this project helped you!\n\n## 技术栈\n* **Vue** 前端主流框架(react,vue,angular)之一,更适合开发灵活度高且复杂的应用\n* **Vuex** 主流的react应用状态管理工具，基于redux\n* **less** css预编译语言，轻松编写结构化分明的css\n* **vue-cli4** 基于vue的前端脚手架\n* **ant-design-vue** 地球人都知道vue组件库\n* **axios** 强大的前端请求库\n* **mand-mobile** 基于vue的移动端ui库，轻松实现美观的H5应用\n* **koa** 基于nodejs的上一代开发框架，轻松实现基于nodejs的后端开发\n* **@koa/router** 基于koa2的服务端路由中间件\n* **ramda** 优秀的函数式js工具库\n\n## 需求分析\n可视化编辑器主要有以下几部分组成：\n* 可拖拽的组件库 draggable components\n* 盛放组件的画布 canvas\n* 组件编辑器 FormEditor\n* 头部工具栏 toolBar\n\n可拖拽组件我们可以用社区比较火的**react-dnd**，**react-draggable**来实现，由于我们的画布是可拖拽可放大缩小的，所以这里需要对画布赋能，具体实现可参考下文。\n\n其次就是H5编辑器部分，这部分是核心功能，后面我们会详细分析。还有就是预览，生成预览链接，保存**json**文件， 保存模版这些功能本质上是对我们**json**文件的操作，可是目前可视化搭建技术的常用手段之一。先来看看这些功能的演示：\n![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/593bdeae932e4e72a5d51249b866e65d~tplv-k3u1fbpfcp-zoom-1.image)\n\n## 基础准备\n我们的**h5页面可视化编辑器**采用**umi**来作为脚手架工具.\n> **umi**是可扩展的企业级前端应用框架,以路由为基础的，同时支持配置式路由和约定式路由，保证路由的功能完备，并以此进行功能扩展。然后配以生命周期完善的插件体系，覆盖从源码到构建产物的每个生命周期，支持各种功能扩展和业务需求.\n\n这样我们不会关注繁琐的工程配置细节, 可以直接在项目中使用 **antd** 和 **less** 这些方案, 并且集成了目前比较流行的**css module**, 可以方便我们在项目里对**css**进行模块化开发. umi创建项目的具体使用流程如下:\n``` js\n// 创建并进入工程目录\nmkdir dooring && cd dooring\n// 创建umi应用\nyarn create @umijs/umi-app\n// 安装依赖\nyarn    // 或者使用npm install\n```\n简单的三步走策略就能轻松搭建我们的项目工程, 是不是省去了很多麻烦? (在使用这些方式之前我们首先确保自己本地的**node** 版本是 10.13 或以上)\n\n在项目创建完之后我们还需要安装可视化方面必备的第三方组件, 笔者调研社区精选组件之后采用了一下方案:\n* **react-dnd** react拖拽组件\n* **react-color** react颜色选择组件,用于H5编辑器的编辑颜色部分\n* **react-draggable** 用于组件或者画布的拖拽移动\n* **react.qrcode** 基于react的二维码生成组件, 能以react组件的方式生成二维码\n\n以上组件在运行项目前大家可以自行安装.\n\n## 介绍\n在最好项目开发准备之后,我们就来开始设计我们的h5页面可视化编辑器－**Dooring**.\n\n### H5编辑器实现\nH5可视化编辑器主要需要4个部分,在文章开头也分析过, 这里用图来巩固一下:\n![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5dd41aec53134d558fe46401a5e58800~tplv-k3u1fbpfcp-zoom-1.image)\n以上是最基本也是最核心的功能展示模型,接下来我们会一一将其拆解并逐个实现.\n#### 实现原理\n我们都知道, 目前比较流行的页面可视化搭建方案可以有如下几种:\n* 在线编辑代码实现\n* 在线编辑json实现\n* 无代码化拖拽实现(底层基于json配置文件)\n\n笔者做了一下优缺点对比图,如下:\n\n| 方案       | 定制化程度 |   缺点 |\n| :--------- | :--: | -----------: |\n| 在线编辑代码     |  最高  | 使用成本高,对非技术人员不友好,效率低 |\n| 在线编辑json   |  较高  | 需要熟悉json,有一定使用成本, 对非技术人员不友好,效率一般 |\n| 无代码化拖拽实现   |  高  | 使用成本低, 操作基本无门槛,效率较高 |\n\n由以上分析来看, 为了开发一个低门槛, 对任何人适用的可视化编辑器, 笔者将采用第三种方案来实现, 目前市面上已有的产品也有很多, 比如说易企秀, 兔展, 百度H5等等. **实现原理其实还是基于json, 我们通过可视化的手段将自己配置的 页面转化为json数据,最后在基于json渲染器来动态生成H5站点**.\n![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6aafb8a67c0844248b6122f8e021dfdb~tplv-k3u1fbpfcp-zoom-1.image)\n\n#### 数据结构设计\n为了提供组件的自定义能力,我们需要定义一套高可用的数据结构, 这样才能实现因组件需求变更而带来的维护性优势.\n\n在开始设计数据结构之前我们先来拆解一下模块:\n![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/de625f318fa247f3a0e3bd5048ed2266~tplv-k3u1fbpfcp-zoom-1.image)\n不同的组件都对应不同的\"编辑区域\".我们需要设计一套统一的标准的配置来约定它, 这样对于表单编辑器的设计也非常有利, 具体拆解如下:\n![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5ff742d89b464849898871d353f64855~tplv-k3u1fbpfcp-zoom-1.image)\n\n经过以上分析之后, 笔者设计了类似下面的数据结构:\n``` js\n\"Text\": {\n    \"editData\": [\n      {\n        \"key\": \"text\",\n        \"name\": \"文字\",\n        \"type\": \"Text\"\n      },\n      {\n        \"key\": \"color\",\n        \"name\": \"标题颜色\",\n        \"type\": \"Color\"\n      },\n      {\n        \"key\": \"fontSize\",\n        \"name\": \"字体大小\",\n        \"type\": \"Number\"\n      },\n      {\n        \"key\": \"align\",\n        \"name\": \"对齐方式\",\n        \"type\": \"Select\",\n        \"range\": [\n          {\n            \"key\": \"left\",\n            \"text\": \"左对齐\"\n          },\n          {\n            \"key\": \"center\",\n            \"text\": \"居中对齐\"\n          },\n          {\n            \"key\": \"right\",\n            \"text\": \"右对齐\"\n          }\n        ]\n      },\n      {\n        \"key\": \"lineHeight\",\n        \"name\": \"行高\",\n        \"type\": \"Number\"\n      }\n    ],\n    \"config\": {\n      \"text\": \"我是文本\",\n      \"color\": \"rgba(60,60,60,1)\",\n      \"fontSize\": 18,\n      \"align\": \"center\",\n      \"lineHeight\": 2\n    }\n}\n```\n通过这种标准化结构设计之后,我们可以很方便的实现我们所需要的编辑页面的功能, 并且后期扩展非常方便, 只需要往editData添加配置即可. 至于动态表单编辑器的实现,方案有很多, 笔者之前也写过相关的文章, 这里就不详细介绍了.\n\n[基于react搭建一个通用的表单管理配置平台（vue同）](https://juejin.im/post/6844904137390292999)\n\n#### 组件库设计\n组件库设计考虑的一个重要的问题就是体积和渲染问题, 一旦组件库变的越来越多, 那意味着页面加载会非常慢,所以我们需要实现异步加载组件和代码分割的能力, umi提供了这样的功能,我们可以基于它提供的api去实现自己的额按需组件.\n``` js\nimport { dynamic } from 'umi';\n\nexport default dynamic({\n  loader: async function() {\n    // 这里的注释 webpackChunkName 可以指导 webpack 将该组件 HugeA 以这个名字单独拆出去\n    const { default: HugeA } = await import(/* webpackChunkName: \"external_A\" */ './HugeA');\n    return HugeA;\n  },\n});\n```\n通过以上的方式来定义包裹我们的每一个组件, 这样就能实现按需加载了, 但是最好的建议是不需要每个组件都按需加载和拆包,对于**标题**, **通知栏**,**页头**,**页脚**这些组件, 我们完全可以把它放在一个组里,这样不但对不会影响加载速度, 还能减少一定的http请求.\n\n笔者这里简单举一个组件实现的例子，方便大家理解：\n``` js\nconst Header = memo((props) => {\n  const { \n    bgColor,\n    logo,\n    logoText,\n    fontSize,\n    color\n  } = props\n  return <header className={styles.header} style={{backgroundColor: bgColor}}>\n      <div className={styles.logo}>\n        <img src={logo && logo[0].url} alt={logoText} />\n      </div>\n      <div className={styles.title} style={{fontSize, color}}>{ logoText }</div>\n  </header>\n})\n```\n上面的Header组件的props属性完全是由我们之前设计的json结构来定义的，在用户编辑的过程中将收据收集并传给Header组件。最后一步是将这些组件动态传给**dynamic**组件， 这块在上文也介绍过了，大家可以根据自己的实现来做动态化渲染。\n\n### 实现预览功能\n预览功能这块比较简单, 我们只需要将用户生成的json数据丢进H5渲染器中即可, 这里我们需要做一个渲染页面单独用来预览组件. 先来看看几个预览效果:\n<img src=\"https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/582e67cb0a874bee947efb05af622a55~tplv-k3u1fbpfcp-zoom-1.image\" alt=\"h5-editor\" width=\"375px\" />\n<img src=\"https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7c50d89f770f4ae5b4c5c4ec9f0052c1~tplv-k3u1fbpfcp-zoom-1.image\" alt=\"h5-editor\" width=\"375px\" />\n前面的渲染器原理已经介绍了, 这里就不一一介绍了,感兴趣的可以交流讨论.\n\n### 实现在线下载功能\n在线下载这块我们需要用到一个开源库: **file-saver**, 专门解决前端下载文件困难的窘境. 具体使用举例:\n``` js\nvar FileSaver = require('file-saver');\nvar blob = new Blob([\"Hello, world!\"], {type: \"text/plain;charset=utf-8\"});\nFileSaver.saveAs(blob, \"hello world.txt\");\n```\n以上代码可以实现将传入的数据下载为txt文件, 如果是Blob, 是不是还能在线下载图片, html呢? 答案是肯定的, 所以我们的下载任务采用该方案来实现.\n\n### 后端部分实现\n后端部分由于涉及的知识点比较多, 不是本文考虑的重点, 所以这里大致提几个点, 大家可以用完全不同的技术来实现后台服务, 比如说**PHP**, **Java**, **Python**或者**Egg**. 笔者这里采用的是**koa**. 主要实现功能如下:\n* 保存模板\n* 真机原理的数据源存储\n* 用户相关功能\n* H5图床和静态文件托管\n\n具体代码可以参考笔者的另一篇全栈开发文章\n\n[基于nodeJS从0到1实现一个CMS全栈项目](https://juejin.im/post/6844903952761225230)\n\n模式基本一致.\n\n## 已完成功能\n* 1. 组件库拖拽和显示\n* 2. 组件库动态编辑\n* 3. H5页面预览功能\n* 4. 保存H5页面配置文件\n* 5. 保存为模版\n* 6. 移动端跨端适配\n* 7. 媒体组件\n* 8. 在线下载网站代码功能\n* 9. 添加typescript支持\n* 10. 表单设计器/自定义表单组件\n\n## 正在完成功能\n* 添加模版库模块\n* 丰富组件库组件，添加可视化组件\n* 添加配置交互功能\n* 组件细分和代码优化\n* 单元测试\n\n## Install(安装)\n1. 下载代码\n```sh\ngit clone https://github.com/MrXujiang/h5-Dooring.git\n```\n2. 进入项目目录\n```sh\ncd ./h5-Dooring\n```\n\n3. 安装依赖包\n```sh\nyarn install\n```\n\n## Usage\n启动应用\n```sh\nyarn run start\n```\n\n\n## 持续升级\n正在升级1.3版本，敬请期待...\n\n## 技术反馈和交流\n<img src=\"http://io.nainor.com/uploads/WechatIMG107_1748aa204e7.jpeg\" width=180 />\n\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset'\n  ],\n  plugins: [\n    [\"import\", { \"libraryName\": \"ant-design-vue\", \"libraryDirectory\": \"es\", \"style\": \"css\" }, \"ant-design-vue\"], // `style: true` 会加载 less 文件\n    [\"import\", { \"libraryName\": \"mand-mobile\", \"libraryDirectory\": \"lib\" }, \"mand-mobile\"]\n  ]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"peipei\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"serve\": \"vue-cli-service serve\",\n    \"build\": \"vue-cli-service build\",\n    \"lint\": \"vue-cli-service lint\"\n  },\n  \"dependencies\": {\n    \"ant-design-vue\": \"^1.6.5\",\n    \"core-js\": \"^3.6.5\",\n    \"mand-mobile\": \"^2.5.13\",\n    \"vue\": \"^2.6.11\"\n  },\n  \"devDependencies\": {\n    \"@vue/cli-plugin-babel\": \"~4.5.0\",\n    \"@vue/cli-plugin-eslint\": \"~4.5.0\",\n    \"@vue/cli-service\": \"~4.5.0\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"babel-plugin-import\": \"^1.13.0\",\n    \"eslint\": \"^6.7.2\",\n    \"eslint-plugin-vue\": \"^6.2.2\",\n    \"less\": \"^3.12.2\",\n    \"less-loader\": \"^7.0.1\",\n    \"vue-template-compiler\": \"^2.6.11\"\n  },\n  \"eslintConfig\": {\n    \"root\": true,\n    \"env\": {\n      \"node\": true\n    },\n    \"extends\": [\n      \"plugin:vue/essential\",\n      \"eslint:recommended\"\n    ],\n    \"parserOptions\": {\n      \"parser\": \"babel-eslint\"\n    },\n    \"rules\": {}\n  },\n  \"browserslist\": [\n    \"> 1%\",\n    \"last 2 versions\",\n    \"not dead\"\n  ]\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n    <link rel=\"icon\" href=\"<%= BASE_URL %>favicon.ico\">\n    <title><%= htmlWebpackPlugin.options.title %></title>\n  </head>\n  <body>\n    <noscript>\n      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>\n    </noscript>\n    <div id=\"app\"></div>\n    <!-- built files will be auto injected -->\n  </body>\n</html>\n"
  },
  {
    "path": "src/App.vue",
    "content": "<template>\n  <div id=\"app\">\n    <img alt=\"Vue logo\" src=\"data:image/png;base64,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\">\n    <HelloWorld msg=\"Welcome to Your H5-Dooring\"/>\n  </div>\n</template>\n\n<script>\nimport HelloWorld from './components/HelloWorld.vue'\n\nexport default {\n  name: 'App',\n  components: {\n    HelloWorld\n  }\n}\n</script>\n\n<style>\n#app {\n  font-family: Avenir, Helvetica, Arial, sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  text-align: center;\n  color: #2c3e50;\n  margin-top: 60px;\n}\n</style>\n"
  },
  {
    "path": "src/components/HelloWorld.vue",
    "content": "<template>\n<div class=\"hello\">\n    <h1>{{ msg }}</h1>\n    <a-select mode=\"tags\" style=\"width: 100%\" placeholder=\"请输入包含关键词回车确认\" @change=\"handleChange\" v-model=\"selectedVals\" labelInValue :options=\"selectedArr\">\n\n    </a-select>\n    <div class=\"selectWrap\">\n        <span :class=\"['selectedItem', i === curSelectedItem ? 'selected' : '']\" v-for=\"(item, i) in tpl\" :key=\"i\" @click=\"handleSelected(i)\"> {{ item.l }} </span>\n        <span class=\"addBtn\" @click=\"handleAdd\">添加</span>\n    </div>\n    <div style=\"width: 120px; margin-top: 20px;\">\n        <md-button @click=\"basicDialog.open = true\">基本</md-button>\n    </div>\n    <md-dialog title=\"窗口标题\" :closable=\"true\" v-model=\"basicDialog.open\" :btns=\"basicDialog.btns\">\n        人生的刺，就在这里，留恋着不肯快走的，偏是你所不留恋的东西。\n    </md-dialog>\n</div>\n</template>\n\n<script>\nimport {\n    Dialog,\n    Button,\n    Toast\n} from 'mand-mobile'\nexport default {\n    name: 'Helloworld',\n    props: {\n        msg: String\n    },\n    components: {\n        [Dialog.name]: Dialog,\n        [Button.name]: Button,\n    },\n    data() {\n        return {\n            tpl: [{\n                    v: '&',\n                    l: '且'\n                }, {\n                    v: '||',\n                    l: '或'\n                }, {\n                    v: '(',\n                    l: '('\n                }, {\n                    v: ')',\n                    l: ')'\n                }, {\n                    v: '>',\n                    l: '大于'\n                }, {\n                    v: '<',\n                    l: '小于'\n                },\n\n            ],\n            selectedVals: [],\n            selectedArr: [],\n            curSelectedItem: -1,\n            basicDialog: {\n                open: false,\n                btns: [{\n                    text: '确认操作',\n                    handler: this.onBasicConfirm,\n                }, ],\n            }\n        }\n    },\n    methods: {\n        handleChange(v) {\n            console.log(`selected ${v}`);\n        },\n        handleSelected(index) {\n            this.curSelectedItem = index;\n            console.log(index);\n        },\n        handleAdd() {\n            if (this.curSelectedItem > -1) {\n                let curSelectedVal = this.tpl[this.curSelectedItem],\n                    {\n                        l,\n                        v\n                    } = curSelectedVal,\n                    selectedArrLen = this.selectedArr.length,\n                    selectedValsLen = this.selectedVals.length;\n                this.selectedVals.push({\n                    label: l,\n                    value: v,\n                    key: selectedValsLen\n                })\n                this.selectedArr.push({\n                    label: l,\n                    value: v,\n                    key: selectedArrLen\n                })\n                this.curSelectedItem = -1\n            }\n            console.log(this.selectedArr)\n        },\n        onBasicConfirm() {\n            Toast({\n                content: '你点击了确认',\n            })\n            this.basicDialog.open = false\n        }\n    }\n}\n</script>\n\n<!-- Add \"scoped\" attribute to limit CSS to this component only -->\n\n<style scoped>\n.hello {\n    width: 480px;\n    margin: 0 auto;\n}\n\n.selectWrap {\n    display: flex;\n    margin-top: 16px;\n}\n\n.selectedItem,\n.addBtn {\n    display: inline-block;\n    width: 4.2em;\n    text-align: center;\n    margin-right: 12px;\n    padding: 2px 6px;\n    border: 1px solid #ccc;\n    border-radius: 2px;\n    cursor: pointer;\n}\n\n.selectedItem:hover {\n    border-color: #06c;\n}\n\n.selected,\n.addBtn {\n    color: #fff;\n    background-color: #06c;\n}\n</style>\n"
  },
  {
    "path": "src/main.js",
    "content": "import Vue from 'vue'\nimport App from './App.vue'\n\nimport { Select } from 'ant-design-vue';\n\nVue.use(Select);\n\nVue.config.productionTip = false\n\nnew Vue({\n  render: h => h(App),\n}).$mount('#app')\n"
  },
  {
    "path": "vue.config.js",
    "content": "module.exports = {\n    chainWebpack: config => {\n      // 修改url loader默认配置\n      config.module\n        .rule('images')\n          .use('url-loader')\n            .loader('url-loader')\n            .tap(options => Object.assign(options, { limit: 10240 }))\n      // 其他基于环境的webpack配置\n      if (process.env.NODE_ENV === 'production') {\n        // 为生产环境修改配置...\n      } else {\n        // 为开发环境修改配置...\n      }\n    },\n    css: {\n        loaderOptions: {\n          // 给 less-loader 传递 Less.js 相关选项\n          less:{\n            globalVars: {\n              primary: '#06c'\n            }\n          }\n        }\n    },\n    // 优化生产构建\n    parallel: require('os').cpus().length > 2\n  }"
  }
]