- 2023.02.14 -- v3.1.21 render添加参数req.header
- 2022.10.27 -- v3.1.20 修改 ejs-inline-template 逻辑,支持 include 模板时跳过
<script type="text/ejs-template"></script>
内部编译 - 2022.09.02 -- v3.1.19 添加条件逻辑判断是否
resize image
- 2022.09.02 -- v3.1.18 修复高版本
npm
找不到node_modules/gulp/bin/gulp
问题。兼容 高版本npm,下载npm包会打平目录结构 - 2020.09.25 -- v3.1.17 兼容 GQL
- 2019.02.19 -- v3.1.16 修复部分 BUGt s
- 2019.01.03 -- v3.1.15 补充 YUE 数据
- 2017.11.03 -- v3.1.12 新加inline task, 用法见下面
- 2017.11.02 -- v3.1.11 修复刷新问题,在tasks/plugins/gulp-changed-deps中加入nunjunks的include关键词
- 2017.08.21 -- v3.1.10 将mock中日志着色以及fix render报错
- 2017.08.18 -- v3.1.9 cli-tables模块遗漏补回
- 2017.08.18 -- v3.1.8 优化本地mock功能, 可以在js中利用req, res, next进行逻辑判断, 从而实现模拟错误,模拟延时等功能
- 2017.07.17 优化yworkflow cli功能,优化gulp模块调用,增加--build方法
- 2017.07.13 优化yworkflow cli日志,恢复日志彩色显示
- 2017.07.12 将runSequence任务变成串行,并行存在着任务执行冲突
- 2017.07.10 新增yworkflow,用于本地快速起yworkflow本地开发
- 2017.06.28 增加Css任务cssUrlToAbsolute开关,默认关闭
- 2017.06.25 增加build任务, 供yworkcli独立调用
- 2017.06.20 增加router任务:支持将路由文件夹合并成单一路由文件
- 2017.06.01 增加快速启动yworkflow的脚本,支持历史项目选择
- 2017.05.17 支持本地开发json注释
- 2017.05.16 路由配置params参数正则过滤:例
/:bookId(\\d+)
转?bookId=$1
- 2017.05.16 增加路由
.ejs
静态资源路由反向代理
过去前端团队业务多以重构为主,传统静态页面开发的模式进行本地开发,好处是目录结构简单,容易理解,直接手写css和js,坏处也不言而喻,脱离了线上场景,无法掌握路由设计,无法正确管理页面的业务渲染逻辑,无法模拟ajax请求。
过去这一年来,我们的项目开发逐渐规范化和流程化,根据实际需求,结合前后端分离Node架构Yuenode,开发出这一套基于gulp
和express
的本地脚手架工具。
利用NodeJs模拟服务器环境,在本地介入业务逻辑,把过去交给「开发」的套模板的工作,放到前端来做,提高前后端联调效率。
注意:由于国内网络问题,建议使用国内npm仓库源或者代理安装npm模块。推荐可以使用
Mac用户终结解决方案可以使用命令行代理Shadowsocks + proxychains4,有效解决依赖下载速度问题。
-
Windows用户请使用(3.0版本不再对Windows进行支持,但是你依旧可以在windows下使用Yworkflow3.0进行本地开发,可能会遇到路径相关的问题,无法使用Yworkcli)。cmder
或者git bash
等终端,原生的CMD
太弱了缺失许多linux命令,可能会导致一些任务处理失败。
由于精灵图生成、压缩需要调用系统图形模块ImageMagick和 GraphicsMagick,请事先安装好相应的图像模块。
强烈建议Mac用户使用brew来安装
brew update && brew upgrade
brew install imagemagick
brew install graphicsmagick
* [Yworkflow](https://github.com/yued-fe/Yworkflow) :本地开发基础架构
* [Yworkcli](https://github.com/yued-fe/yworkcli) :自动化静态资源版本化、模板combo工具
* [Ymini](https://github.com/foru17/ymini) :压缩css和静态资源的脚本工具
-
自动化构建
- CSS
- Sass编译
- 资源相对路径转绝对路径
- sourcemap
- Javascript:
- ESlint语法检测
- require 补全提前声明
- HTML
- 默认ejs模板
- nunjucks转ejs
- 精灵图
- svg转精灵图
- 中文webfont
- font-spider
- 图像处理
- CSS
-
本地开发
- 模拟框架机逻辑,浏览器直接HTTP模拟调试
- 自定义业务路由
- 服务自动监听文件变化:实时编译css和js
-
资源压缩
- 参考Ymini说明文档
npm install -g yworkflow Yworkcli del-cli
Yworkflow3针对过去老版本必须紧跟项目文件夹、有过多强依赖,做了完全抽离。你可以安装Yworkflow3到你机器的任意位置,通过yworkflow
的形式,启动任务。
项目的一切配置,均通过.yconfig
文件配置,增加项目的定制化和适用性。
具体的配置,可以分别参考起点M站qidian-m和小说阅读网PCreadnovel_pc_proj
var path = require('path');
var rootCWD = '..';
var defaultConfig = {
'name': 'qidian-m',
'author': 'luolei@yuewen.com',
'gtimgname': 'qdm', // 对应 qidian.gtimg.com/{name} 路径
'node_site': 'yworkflow', // 与后端约定的业务node别名
'env': 'local',
'master_host': 'm.qidian.com',// 设置主host,如果没有指定域名,则默认解析为该host,支持ip直接访问
'debug': true,
'proxy_force': true, // 开启代理开关,接口指向服务端数据
'proxy_server': 'http://prem.qidian.com', // 接口服务地址
'port': 8888,
// 代理模式使用到的域名:下列所有域名在代理模式下均走Yworkflow router逻辑
'hosts': [
'm.qidian.com', // 配置该项目的业务域名,针对这里配置的所有域名进行路由代理
],
// 由于实际业务上可能采用不同的域名,进行域名映射
// 对于设置alias的域名统一转换成value
'alias': {
'mobile.qidian.com':'m.qidian.com'
},
// 目前所有业务都是同域反向代理,这里进行一个强约定
// 可将所有的ajax路由在这里列出
'ajax': [
'/ajax', // 默认保留,请勿删除
'/apiajax',
'/meajax',
'/majax'
],
'graphql': ['/graphql'],
//本地文件映射
'paths': {
'json': 'src/server/json', // 设置本地开发配置的 json路径
'public_json': 'src/server/custom', // 注入公共数据 例如 data.user等
'views': '.cache/views', // 设置本地ejs模板的读取路径
'static_root': '.cache/static', // 指定开发时的资源入口
'ejs_rewrite_router':'/ejs',// 针对旧有的 /ejs 反向代理做特殊处理指向 /qd 静态资源路由规则,默认路由为 /ejs
// 'static':'src/static', // 静态资源路径可以直接指定一个通用路由
'static': { // 也可以分别指派
'/qdm': '.cache/qdm',
'/lbf': 'http://devqidian.gtimg.com/lbf', // 支持直接将某一个域名代理到线上路径
'/jssdk': '.cache/qd_jssdk',
'/lbf': '.cache/lbf',
'/qreport':'http://qdp.qidian.com/qreport' // 上报代理到线上资源
} // 本地静态资源路径
},
// 提供自动上传到 ftp 服务功能
'ftp': {
'host': '192.168.1.1',
'user': '',
'password': ''
},
// server 配置相关是与框架机耦合的配置,这里请注意与运维约定相关参数
'server': {
'path': 'src/server/config', // 提供给框架机环境的配置入口路径
'server_conf_file': 'server', // 框架机配置文件名,默认server.js
'routermap_file': 'routes', // 动态路由配置文件
'static_routemap_file': 'static_routermap', // 静态化路由配置文件
'custome_handle_file': '', // 建议与 node_site 同名以便维护
'extends_loader_file': 'extends/loader', // 自定义中间件入口
},
'root': {
'cwd': '',
'src': 'src',
'dest': '.cache'
},
// 本地编译相关task
'tasks': {
// 支持将本地路由文件夹的路由打包成单一路由文件
'router':{
'srcEntry':'src/node-config/dynamic_routermap',// 本地路由文件夹入口
'dest':'src/node-config/dynamic_routermap.js',// 最终生成的单一路由文件
'exclude':['STATIC.js','PROXY.js']// 需要排除的本地路由
},
'html': {
'src': 'src/server/views',
'dest': '.cache/views',
'prettify':true, // 格式化html代码
'multiple': true,
'nunjucks': {
}
},
// 静态化路径
'render': {
'render_routermap_file': 'src/node-config/RENDER.js', // 该路由表设置的所有路由均会对应生成html实体文件
'dest': '_html', // 静态化文件生成路径
'minimize':true, // 生成压缩html
},
// CSS编译相关
'css': {
'src': './src/static/css',
'dest': './.cache/qdm/css',
'cssUrlToAbsolute':false,// css中相对路径转绝对路径,默认关闭
'autoprefix': true, // autoprefix开关
'sourcemap': './.map', // sourcemap开关
'extensions': ['css', 'scss']
},
// JS编译相关
'js': {
'src': './src/static/js',
'dest': '.cache/qdm/js',
'sourcemap': './map',
'eslint': {
ignorePath: path.resolve(__filename,'../', '.eslintignore'), // gulp-eslint 忽略配置,路径与 gulpfile.js 文件位置有关联
},
'lbfTransport': { // 自动补齐模块ID和依赖
publicPath: 'qdm/js',
},
'eslintFormatter': path.join('node_modules/eslint-friendly-formatter'), // gulp-eslint 格式化配置,路径与 gulpfile.js 文件位置有关
},
'img': {
'src': './src/static/img',
'dest': './.cache/qdm/img',
'optimize': './src/static/images/events', // 优化图片处理
'extensions': ['jpg', 'png', 'svg', 'gif', 'ico'], // 处理文件后缀
},
// ICON相关任务配置
// 会自动遍历 src设置文件夹的目录,生成精灵图
'icon': {
'src': './src/static/icon',
'dest': './.cache/qdm/icon',
'multiple': true, // 是否分批处理,即以子目录为单位,在多页面需要分开处理时会用到
'img': { // 图片合并相关配置
'1xDir': '.1x', // 1倍图存放地址,以 "." 开头是隐藏文件,为了表示此文件是生成的,不是源文件
'imageResize': { // gulp-image-resize(将2倍图源文件压缩成1倍图) 插件配置
'width': '50%',
'upscale': true,
},
'spritesmith': { // gulp.spritesmith(生成雪碧图) 插件配置
'imgName': 'sprite.png',
'cssName': 'sprite.css',
'padding': 4,
'retinaSrcFilter': '!' + path.resolve(__filename,'../', '**/.1x/*'), // 2倍图过滤条件,路径与 gulpfile.js 文件位置有关联
'retinaImgName': 'sprite@2x.png',
},
},
'svg': { // SVG合并相关配置
'svgmin': { // gulp-svgmin(压缩svg) 插件配置
'plugins': [
{ 'removeAttrs': { 'attrs': '(fill|fill-rule)' } },
{ 'removeTitle': true },
],
},
'svgstore': { 'inlineSvg': true }, // gulp-svgstore(合并svg) 插件配置
'svgTransport': {}, // gulp-svg-transport(svg转js) 插件配置
'rename': 'sprite.js', // gulp-rename(重命名合并后svg转js文件名字) 插件配置
},
},
// 配置自动生成中文字体得入口页面
'font': {
'src': './src/static/font',
'dest': './.cache/qdm/font',
'extensions': ['css', 'eot', 'svg', 'ttf', 'woff', 'woff2'], // 处理文件后缀
'fontSpider': {}, // gulp-font-spider(压缩字体) 插件配置
},
// 其他静态资源
'static': {
'src': './src/static',
'dest': './.cache',
'extensions': ['css', 'scss'],
'copyDirect': {
// 直接复制资源到指定位置
'./src/server/views/*.*': './.cache/views',
}
}
}
};
module.exports = defaultConfig;
- 进入 {Yworkflow3路径}项目跟路径,例:
cd /Users/yuewen-luolei/Yuewen/Tencent/Yworkflow3
- 执行启动脚本
yworkflow --path {file}.ycofnig
- 打开浏览器,即可通过
.yconfig
中配置的域名和端口号,进行开发
线上业务是无port的概念,为方便本地调试,Yworkflow3支持代理模式。以Chrome浏览器为例。
1.安装Proxy SwitchyOmega插件。 2.设置情景模式,端口号为具体项目端口号即可
3.浏览器切换到自定义的情景模式,这个时候就可以通过80端口访问本地页面,模拟线上环境。(此时接口依旧根据配置读取本地json或者测试服务器)
注意:
- 不支持https代理,场景有限,滞后支持。
- 如果在代理模式通过IP访问,默认理解host为
.yconfig
文件中配置的master_host
。 - 仅代理
hosts
中配置的域名,其他域名,均指向原始资源URL。
例:
小阅的配置如下
'master_host': 'www.readnovel.com',
'proxy_force': true, // 是否开启强制代理
'proxy_server': 'http://oawww.readnovel.com', // 接口服务地址
'port': 8008,
'hosts': [
'www.readnovel.com'
],
- 非代理模式下,小阅访问
localwww.readnovel.com:8008
即可访问页面。 - 代理模式下,小阅访问
localwww.readnovel.com
,www.readnovel.com
,10.97.180.114
(局域网或者公网IP)均可访问页面 - 代理模式下,小阅访问资源
http://qidian.qpic.cn/qdbimg/349573/c_5334091103442901/90
,访问的是依旧原始资源
静态资源版本化和自动生成模板统一使用Yworkcli工具,该工具解决静态资源和模板映射的自动化生成。
1.安装npm install -g Yworkcli del-cli
2.配置文件
{
"static":{
"path":".cahce/qdm", //生成的项目资源路径
"gtimgName":"qdm", //对应的gtimg地址资源路径
"output":"_prelease/qdm" //本地输出的编译后路径
},
"views":{
"path":"src/views", //匹配的模板文件路径
"output":"_previews/views"//最终生成的目录文件路劲
},
"configs":{
"path":"src/node-config",//框架机config路径
"output":"_previews/node-config"//框架集config发布路径
},
"combo": {
"force": true,//是否开启combo
"gtimgTag":"<%= staticConf.domains.static %>",// 静态资源环境配置
"gtimgNamePrepend":"qd", // 在combo组合前增加文件名
"uri":"<%= staticConf.domains.static %>/c/=",//combo的线上URL接口
"logicCondition": "envType == \"pro\" || envType == \"oa\"" //开启combo的条件,注意需要转义双引号
},
}
3.发布,进入项目路径cd /Users/yuewen-luolei/Yuewen/Tencent/qidian-m && yworkcli --publish --log './ywork.log'
4.可以通过 --loag {相对路径}
来配置日志路径,可以查看ywork.log
查看任务情况
- 安装
npm install ymini -g
- 压缩JS资源
ymini --js --path {PATH || FILENAME} #压缩指定文件夹下的所有'.js'文件
- 压缩CSS资源:
ymini --css --path {PATH || FILENAME} #压缩指定文件夹下的所有'.css'文件
支持在本地json文件中注释。
除了在mock文件夹加入json数据之外, 支持加入js的mock文件. 并且js具有更高的优先级(即同目录下有a.js和a.json, a.js具有更高的优先级).
a.js:
if(req.url === 'aaaaaa') {
setTimeout(function () {
next(null, {
code: 0,
data: {}
});
}, 1000);
} else {
var err = new Error();
err.code = 500;
// 抛出500 error
next(err);
}
因为inline css 或 js 到html的时候,需要替换一些地址,这个配置在replace里面.
"inline": {
"baseDir": "./.cache", //本地生成的文件夹
"replace": [{
"src": "need-to-replace-css-file-path",
"dest": "need-to-export-css-file-dir",
"patterns": {
"/ovserseam/": "......" //文件中需要被替换的内容
}
}],
"htmlPath": "path-to-need-inline-css-html-file",
"htmlDest": "need-to-export-html-file-dir"
}