在一个小公司最大的益处是什么都要搞,PC/公众号/小程序,前台,后盾,中台,react,vue、UI都接触,产品需要一直,我的项目越做越多,人还是那几个。对于前端的标准化,工程化的要求越来越高。
aotoo-hub
作为一套通用型前端脚手架,无技术栈依赖,聚焦于多人合作及工程化。能够帮忙开发者疾速产出我的项目,喜爱折腾的能够钻研下。
aotoo-hub
是一套前端/NODE 端一体化设计的全栈脚手架,前端应用webpack4编译,node端应用koa2提供服务。hub可独立运行作为前端编译工具,也可配合node端部署线上服务
独立运行时,仅作为前端编译、输入动态资源工具,hub采纳webpack对前端的资源进行编译,开发模式下由webpack-dev-server提供热更新反对,生产环境下仅产出压缩后的代码
交融运行时,node(koa2,koa-router)将接管webpack-dev-server提供后端服务,此时可实现SSR服务,API服务,可用于部署,提供线上服务
一些特点
- 提供简略的命令行工具
- 编译环境反对多我的项目,共享编译资源及node_module
- 反对为React/Vue/Jq/原生js/小程序等我的项目提供编译环境
- 标准的前端、node端目录构造
- 反对动静款式(sass/stylus)
- 反对多环境,命令行切换测试,生产等环境
- 反对node端(koa2)
脚手架源码构造
hub工作空间 ├── build ├── aotoo.config.js ├── index.js ├── package.json ├── postcss.config.js └── src # vue 我的项目演示 └─ vueSample ├── configs # node环境配置文件,默认蕴含default.js ├── dist # 动态资源输入目录 ├── js # 前端业务js目录(前端) │── venders # 第三方库文件目录+自定义公共库(前端) ... └── server # node端的源码目录 │── pages # node端的业务目录 └── plugins # 自定义插件目录 # react 我的项目演示 └─ reactSample ├── configs # node环境配置文件,默认蕴含default.js ├── dist # 动态资源输入目录 ├── js # 前端业务js目录(前端) │── venders # 第三方库文件目录+自定义公共库(前端) ... └── server # node端的源码目录 │── pages # node端的业务目录 └── plugins # 自定义插件目录 # 小程序我的项目演示 └─ xcxSample ... ... # 文档我的项目演示 └─ mdSample ... ...
GITHUB
更多阐明
hub脚手架开发的一些思路
前端我的项目架构比后端我的项目架构更具备挑战性,为啥呢?个别后端架构(大部分中小我的项目)稳固在一个环境,语言,我的项目下,可能几年更新一次,而前端要应答多端输入,我的项目繁冗,多种框架,简单组件等等状况,框架的更新还特地沉闷,常常有学不动想放弃的感觉。
脚手架作为一个重要前端工具,特地须要有对立的,标准化的思维。好的脚手架可能能让开发,测试、运维的工作变得很爽。咱们须要脚手架能束缚、标准工程项目构造;有对立的编译环境;与我的项目去耦合;不便进行多人合作;还应该要简略,开箱即用,开发者只需关注业务,在生成的我的项目构造的根底上进行开发即可
与我的项目解耦
为什么须要将架构与我的项目去耦合,试想下,当一个公司存在n个我的项目时,架构师更新、保护不同我的项目,不同框架的脚手架,造成我的项目不稳固的危险,同时减少了架构师、开发人员、测试人员、运维人员,经营人员的工夫老本,沟通老本。
技术栈无关
公司我的项目类型很多,轻量,且须要疾速迭代上线的我的项目,个别咱们用vue;比较复杂,由多人合作共同完成的我的项目。个别咱们用react;小程序也是前端的热门方向,还有老旧基于jq我的项目,因而脚手架须要可能反对编译多种前端框架
这个不是很难,在webpack中增加各种框架所需的配置就能够实现,hub目前反对React、Vue、Angular、Jquery、小程序等技术栈。
多我的项目反对
架构与我的项目去耦合,即可单个我的项目独立编译运行,又能够同时运行。所有我的项目共享hub工作空间的编译环境,共享工作空间的node_module。我的项目自有dist目录,启动时有调配惟一服务端口。如下图所示
工作空间 ├── build └── src └─ vueSample └─ dist └─ reactSample └─ dist └─ mdSample └─ dist └─ xcxSample └─ dist
命令行工具
命令行须要简洁高效,可能实现环境初始化、我的项目初始化、开发模式、生产模式,环境切换,能够传递参数,反对node、pm2部署
aotoo dev # 编译开发环境文件,并关上webpack-dev-server服务aotoo dev --config test # 编译测试环境文件,并关上webpack-dev-server服务aotoo build # 编译生产环境文件node index.js # 启动我的项目,可用于dockerpm2 start index.js # 应用pm2部署我的项目
配置化
命令行、配置文件相辅相成,一个都不能少,配置可能简化命令行操作,比方须要同时启动多我的项目,设置某我的项目的环境等。
下例是hub我的项目的具体配置项
{ // 项目名称 name: 'mdSample', // 指定我的项目版本 version: 1.0.8, // 是否启动我的项目,默认false // 启动时,可简化命令行输出项目名称 startup: true, // 是否启动node server,默认false,由webpack-dev-server提供服务 // 如在组件开发过程中,敞开node服务,晋升性能和效率 server: false, // 省略前端编译,默认false,须要设置server=true // 只启动node端,开发模式晋升效率,生产模式可间接部署 onlynode: false, // 我的项目源码目录 src: path.join(ROOT, 'src/mdSample'), // 指定我的项目端口,不指定则调配随机端口 port: 8400, options: { // 我的项目灰度环境,如测试,预公布,生产等 // 倡议应用命令行 --config test,抉择环境配置 // scenes: 'default' }},
版本治理
环境与我的项目隔离
隔离是为了更专一,各司其职,架构师更新环境,开发人员更新业务,互不烦扰,编译环境与我的项目去耦合。应用git可能很不便的实现这一构想,如下图
工作空间 # ==> 设置环境git,疏忽src/* ├── build └── src └─ vueSample # ==> 设置我的项目git
在使得命令行工具能够反对在我的项目源码目录中执行,开发人员应用vscode仅仅关上vueSample目录就能够心无旁骛的开始开发工作。
# 在hub工作空间目录下 aotoo dev vueSample # 运行开发环境# 在我的项目vueSample目录下cd src/vueSampleaotoo dev vueSample # 在我的项目源码目录中也能够启动开发环境
我的项目版本
我的项目版本基于配置文件的version,我的项目的动态资源会被全副编译至dist/${version}
目录,多个版本就会存在多个目录,不便回滚,备份等等保险操作,如下图
├─ dist # 输入目录(前端) │─ 1.0.1 # 版本目录,根据配置中的version字段 └─ 1.0.8 └─ dev # 开发目录 │── js/index.js │── html/index.html ...
多环境
test1环境,test2环境,test3环境...,脚手架通过命令行参数指定我的项目以后运行时环境配置,也能够设置配置文件来切换。
当初很多公司都用到了apollo这样的云配置核心,这对于开发者来说十分不不便,有两种计划能够思考,一是应用命令行传递不同参数,使我的项目调用云配置或者本地配置;二是在我的项目初始化时,在配置文件中创立办法去主动抓取云配置。
aotoo dev --config test1
标准我的项目目录
设计正当、标准、灵便的模板对于我的项目构造的合理性十分有益处,因为咱们都围绕模板来建设目录,产出资源,而任何资源最终都被用在模板上。
模板的动态资源
<html> <head> <link href="common.css" /> <link href="[filename].css" /> </head> <body> <div id="root"><%- root %></id> <script src="vendors.js" /> <script src="common.js" /> <script src="[filename].js" /> </body</html>
- common.js 拆散的公共JS代码,由webpack编译时提取,注入
- vendors.js 第三方框架库及通用库,对应js/vendors目录
- common.css 公共CSS,对应css/common.[css|scss|styl]文件
- [ filename ].js 业务JS,对应业务目录/文件名称如 user.js
- [ filename ].css 业务CSS,对应业务目录/文件名称如 user.css
- hub应用ejs解析模板,由node 或 webpack-dev-server解析模板
如上例模板较为标准,能够很容易输入标准的我的项目目录构造,大抵有如下
project ├── html └── index.html ├── css └── index.css └── js └── index.js
在hub我的项目中,大部分状况下咱们能够省略html目录和css目录(无额定需要),目录构造能够精简如下
project └── js └── index.js
作为hub我的项目,它能够失常运行,hub在编译时会主动为该我的项目生成模板、款式、node等等。
仿小程序目录构造
hub我的项目的目录构造也能够项小程序或者Vue这样设置,如下例
project └── js └── user ├── index.js # 输入业务JS => user.js ├── index.css # 输入业务CSS => user.css └── index.html # 输入业务模板 => user.html
对于webpack的entry
后面刚说了模板很重要,但却抉择了基于JS索引生成webpack的entry,这里有一个假如前提,即每一个模板页面必然蕴含一个业务JS。
基于JS索引构建的entry对于webpack来说有人造的亲和性,能够应用webpack-html-plugins主动生成其对应的模板。
作为编译入口,咱们能够为webpack的entry赋予了更多的职能,为entry的每一个trunk编译其动态资源、生成node端路由、生成node端api等等。
reactSample
hub的演示我的项目reactSample目录构造非常简单,形成如下
reactSample ├── configs/default.js # 环境配置,实际上也是编译时生成的 └── js/index/index.js
该我的项目所需的资源文件在编译时主动生成,款式在运行时由JS注入,生产环境提供node服务,开发环境提供dev-server服务。服务端提供模板渲染、镜像路由,镜像API等服务。而这些只是一个命令node index.js
就ok了
多页和单页
终极目标当然是实现MPA-SPA混合模式,即多-单页模式,H5须要SPA,PC须要MPA+SPA。MPA很简略,node端输入的页面都是独立的页面,有模板就行,是人造的MPA模式。
hub工作空间 ├── mdSample ├─ dir1 # => page1.html ├─ dir2 # => page2.html └─ dir3 # => page3.html
hub也可能很容易的为react,vue提供MPA-SPA模式,这是hub脚手架自带的buf
Node中间层
引入node端能够解决
- 跨域
- 独立部署
- 自定义API
- mock服务
- seo
路由
镜像路由
通过webpack的entry构建的node路由,称之为镜像路由,镜像路由能够提供页面渲染服务和API数据接口服务
镜像路由示意构造
reactSample └── js └── user/index.js # 前端 └── server └── pages/user/index.js # node端# 拜访镜像路由 http://www.abc.com/user# 申请API数据路由 ajax.post('/user', {...}).then(res) # node端controler文件 server/pages/user/index.js
咱们晓得koa2是典型的MVC后端模型,view对应模板,model对应数据层(由业务驱动,大部分是ajax数据)。将entry的trunk与koa-router绑定,就形成与前端的镜像路由关系(一一对应),同时输入其controler文件用来解决GET/POST/PUT/DELETE等事务
自定义路由
有些路由与页面没有关系,比方上传,API接口就属于这一类非凡的路由,所以咱们还须要通过plugins来手动创立自定义的路由
插件
插件用来创立自定义路由与创立功能模块,自定义路由如上所述。
功能模块的典型利用是数据库申请。controler层个别都须要发动数据库申请,插件将功能模块绑定到koa的context上。留神这个过程是一个预处理过程,而controler层的运行则属于运行时过程,因而只有controler层有须要就能够从koa的上下文中取得数据处理模块用来发动数据库申请
小程序反对
对于小程序我的项目,咱们要管制webpack输入,不要让它做多余的事件,最终输入代码由微信小程序开发工具来解决
依照1:1对等输入小程序源码,仅利用webpack解决一下小程序的一些小毛病,比方markdown,动静款式,html等等。(输入不会产生webpack的冗余代码),反对热更新
应用webpack参加小程序编译,咱们能够应用loader/plugins实现一些想法,比方写个loader,将微信小程序转译成其余小程序,只是对照表有点麻烦,思路应该是可行的
兼容老旧我的项目
我也是个前端老人了,前端切图仔的岁月依稀在眼前,前端后端的交融开发模式(java渲染模板)痛点在于你要搭一个java环境,你须要晓得模板中的每一个ID,你对模板庞杂的构造了若指掌。
在脚手架编译的同时,将所有资源收集起来并整顿一份资源文件(mapfile.json),蕴含JS/HTML/CSS/IMAGE等信息。将mapfile.json交给java大佬,将动态资源文件目录(dist)交给运维大哥,申请java大佬写一份脚本主动匹配动态资源。
自带的演示我的项目
我的项目蕴含(REACT/VUE/小程序/MD 文档零碎)等 4 套 DEMO 演示我的项目,每个我的项目即是独立我的项目,又可能通过node端实现资源互通。不便疾速上手各套环境。
Vue 演示 DEMO
vueSample,基于vue2.0 的空我的项目,蕴含vue-router简略我的项目演示
vue的演示我的项目没有上vue3.0,因为开发时vue3.0周边库还没有稳固,打算让它再飞一会,你也能够自行引入,更多阐明
REACT 演示 DEMO
reactSample,一个空我的项目,蕴含REACT16 的简略演示。
小程序演示 DEMO
xcxSample,是原生微信小程序开发,反对云开发,该我的项目蕴含咱们开发的小程序库queryUI库及相干组件,清空相干援用就是一个残缺的小程序官网示例代码。更多阐明
- 动静款式反对
- webpack的各种插件反对
- 原生微信小程序
- 动静模板构建
- template less
- 反对钩子办法
- 内置反对 MARKDOWN 富文本
- 内置反对 HTML 富文本
- 由aotoo库构建
MD文档零碎
这里重点讲一下文档零碎,文档零碎是一套hub环境的残缺演示,蕴含前端编译,路由,NODE 端镜像路由、插件,MPA/SPA利用,命令行的应用等等,更多阐明
- 全栈零碎
- 栏目首页由 node.js 做服务端渲染 (SSR),浏览器端复用后渲染 (CSR & SPA)
- 栏目项是多页利用(MPA)切换页面;菜单项是单页利用(SPA)切换路由
- 自定义同构办法,Fether/requireMarkdown等,Fetcher前端axios构建,node端got构建
- 仿小程序的前端路由,构建时能够依据路由切割代码,按需加载 js 文件,反对SSR
- 仿小程序生命周期,让page代码、component代码有更清晰的性能划分
- template less,尽可能的少写模板,将模板逻辑交由JS实现(aotoo库的外围性能)
- 反对 markdown
- 反对 SEO,外部主动解决在浏览器端复用服务端渲染的 html 和数据,无缝过渡
- 多场景化,测试,生产一应俱全
- aotoo库构建(react的封装库,react组件jquery化)(阐明)
目录构造
aotoo-hub
装置实现后的目录构造
hub工作空间 ├── build ├── aotoo.config.js ├── index.js ├── package.json ├── postcss.config.js └── src # vue 我的项目演示 └─ vueSample ├── configs # node环境配置文件,默认蕴含default.js ├── dist # 动态资源输入目录 ├── js # 前端业务js目录(前端) │── venders # 第三方库文件目录+自定义公共库(前端) ... └── server # node端的源码目录 │── pages # node端的业务目录 └── plugins # 自定义插件目录 # react 我的项目演示 └─ reactSample ├── configs # node环境配置文件,默认蕴含default.js ├── dist # 动态资源输入目录 ├── js # 前端业务js目录(前端) │── venders # 第三方库文件目录+自定义公共库(前端) ... └── server # node端的源码目录 │── pages # node端的业务目录 └── plugins # 自定义插件目录 # 小程序我的项目演示 └─ xcxSample ... ... # 文档我的项目演示 └─ mdSample ... ...
阐明
aotoo.config.js
我的项目配置文件,蕴含我的项目版本,我的项目类型,我的项目源码目录等各种配置
apps: [ { name: 'reactSample', // 项目名称 version: '1.0.1', // 我的项目版本,每个我的项目有本人的版本 startup: true, // 是否默认启动 server: false, // 是否提供node端服务,默认为`dev-server`提供服务 type: 'web', // 我的项目类型, 'mp'为小程序 src: path.join(ROOT, 'src/reactSample'), // 源码目录 micro: false, // 是否微服务模式(开发中,未欠缺) options: { // 我的项目扩大参数 scenes: 'default',// 默认我的项目环境,将生成环境配置文件 cloud: false, // 小程序我的项目是否启动云端 }, port: 8500 // 我的项目端口 }, { name: 'vueSample', ... }, { name: 'xcxSample', ... } ],}
configs目录
该目录寄存环境配置,编译器会依据命令行所给出的环境参数生成相干的配置,比方测试环境(test=>test.js)
aotoo dev --config test
dist目录
该目录寄存前端编译文件,蕴含版本目录,开发目录,生产目录
├─ dist # 输入目录(前端) │─ 1.0.1 # 版本目录,根据配置中的version字段 └─ 1.0.8 └─ dev # 开发目录 │── js/index.js │── html/index.html ... └── mapfile.json # 动态资源镜像文件 └─ pro # 生产目录 │── js/index_[hash].js # 生产文件会带上hash ... └── mapfile.json # 动态资源镜像文件
js目录
该目录寄存前端JS源码,公共JS源码,业务JS源码
├─ js │─ vendors # 公共JS └─ index # 前端业务目录 │─ index.js # 业务 => dist/.../index.js │─ index.scss # 款式 => dist/.../index.css └─ index.html # 模板 => dist/.../index.html └─ shop # 前端业务目录 │─ index.js # 业务 => dist/.../shop.js │─ index.scss # 款式 => dist/.../shop.css └─ index.html # 模板 => dist/.../shop.html
编译思路
编译器遍历业务JS文件并生成其配套资源(html/css/node)
dll打包(vendors目录)
这里dll打包指代打包vendors.js
和common.js
,须要留神的是,vendors是一套独立的webpack打包过程,与业务JS打包不在一个过程,将生成dist/.../vendors.js
文件,common.js
来自业务JS的拆散代码(webpack的split)。其中vendors.js
文件不反对热更新
业务打包
业务打包以JS文件作为webpack的entry,通过loader模块同时生成其相干动态资源,如上例的shop目录
js/vendors目录
该目录寄存通用代码或者框架库,比方在vendors/index.js
中引入react或者vue,须要留神,该目录的内容会被利用到node端
(如果启用了server服务),所以肯定要留神两端的兼容性写法
server目录
当你在配置中设置server参数为true时,编译器将会主动生成server目录,并将后端服务由webpack-dev-server
转向由node端提供的服务
镜像路由server/pages
当你在配置中设置server参数为true时,编译器会遍历entry(业务JS),并镜像生成其node端的controler文件,如上例shop
server └─ pages └─ shop └─ index.js
controler文件默认提供渲染服务、GET、POST接口服务
node端插件server/plugins
该目录须要手动生成,插件反对自定义路由,反对自定义功能模块
命令行工具
aotoo-cli
是aotoo-hub的命令行开发工具库,装置、编译都须要通过此工具来操作更多阐明
零碎环境
- mac osx
- linux
- 不反对
windows,但 win10 的 linux 子系统能够 - node >= 12
INSTALL
npm install -g aotoo-cliaotoo -V # 查看是否装置胜利
USAGE
装置一个新的hub空间
init <dir>
# 新建xxx我的项目$ aotoo init xxx
新建web类我的项目
create <dir>
主动创立pc/h5/公众号等web我的项目并启动我的项目
# 新建我的项目$ cd xxx$ aotoo create projectName
将会在xxx/src目录下,创立我的项目目录projectName
,依照提醒输Y
,回车持续
实现装置后,批改aotoo.config.js
,补充我的项目形容
新建小程序我的项目
create <dir>
实用于创立小程序我的项目
# 新建我的项目$ cd xxx$ aotoo create minip_name
将会在xxx/src目录下,创立我的项目目录minip_name
,提醒请输出n
实现装置后,关上aotoo.config.js
,补充我的项目形容,重新启动我的项目
启动自带我的项目
装置实现后,hub的src目录下蕴含4个演示我的项目,通过以下命令能够别离启动
启动文档我的项目
# 文档我的项目属于默认我的项目,能够间接启动$ aotoo dev
启动VUE我的项目
$ aotoo dev vueSample
启动REACT我的项目
$ aotoo dev reactSample
启动小程序我的项目
编译实现后须要应用小程序开发工具关上终端黄色字体批示的目录
$ aotoo dev xcxSample
工作模式
dev [name]
开发模式编译,并启动服务,前端反对热更新
# 启动aotoo.config中apps中的启动我的项目$ aotoo dev# 启动指定我的项目$ aotoo dev project_name
dev-clean [name]
开发模式编译,革除common/vendors等dll文件,从新生成,并启动服务
$ aotoo dev-clean# 启动指定我的项目,并革除该我的项目common的缓存$ aotoo dev-clean project_name
dev-build [name]
开发模式编译,革除common/vendors等dll文件,从新生成,不启动服务
$ aotoo dev-build# 编译指定我的项目$ aotoo dev-build project_name
生产模式
build [name]
生产模式,纯编译输入,不启动服务
$ aotoo build# 编译指定我的项目$ aotoo build project_name
build-clean [name]
生产模式,革除common/vendors等dll文件,并从新生成,不启动服务
$ aotoo build-clean# 编译指定我的项目$ aotoo build-clean project_name
部署
部署之前,须要先以生产模式编译
aotoo build-clean project_name
start [name]
生产模式,启动node服务
$ aotoo start# 编译指定我的项目$ aotoo start project_name
node启动
# 编译我的项目,生产模式$ node index.js# 启动测试环境$ node index.js --config test# 进入源码server目录启动 $ cd src/project_name/server$ node index.js
pm2启动
# 编译我的项目,生产模式$ aotoo build-clean project_name# 启动测试环境$ pm2 start index.js -- --config test
EXTEND PARAM 扩大参数
--config <name>
指定环境配置文件,配合node端一起应用
# 开发模式,启动测试环境aotoo dev --config test# 生产模式,启动测试环境 aotoo build --config test
--name <name>
启动指定我的项目,该参数可多我的项目同时启动
# 同时启动 xxx 及 yyy的我的项目$ aotoo dev --name vueDemo --name reactDemo
GITHUB
更多阐明