Dawn 取「黎明、破晓」之意,原为「阿里云·业务运营团队」内部的前端构建和工程化工具,现已完全开源。它通过 pipeline
和 middleware
将开发过程抽象为相对固定的阶段和有限的操作,简化并统一了开发人员的日常构建与开发相关的工作。
官方文档
入口
开发过程中,经常会用到如下一些命令,dn
也可以替换为dawn
。
dn init
dn dev
dn build
在dawn
项目的package.json
中,可以看到如下一些配置信息。属性bin
则是执行命令的入口。
{
"name": "dawn",
"version": "1.9.0",
"description": "dawn cli",
"main": "./lib/index.js",
"bin": {
"dn": "./bin/cli.js",
"dawn": "./bin/cli.js"
}
}
cli和cli-core
在cli.js
中执行require('./cli-core').ready();
在cli-core.js
中,使用cmdline
库将涉及的命令和执行动作action
进行初始化配置。当触发某个命令,对应的action
回调函数执行,就会初始化Context
,调用context.run()
方法执行后续一系列任务。
cmdline
.root.command([
'dev', 'add', 'test', 'build', 'publish', 'start', 'run',
'd', 'a', 't', 'b', 'p', 's', 'r'
])// 配置与action有关的命令
.option(['-e', '--env'], 'string') // 命令后面的可选项
.action(async function (cmd, env, $1) {
if (cmd == 'r' || cmd == 'run') {
cmd = $1 || 'dev';
}
cmd = ALIAS[cmd] || cmd;
this.set('command', cmd);
process.env.DN_CMD = cmd || '';
process.env.DN_ENV = env || '';
process.env.NODE_ENV = env || process.env.NODE_ENV || '';
try {
let context = new Context(this, { cmd, env });
await context.run();
cmdline.onDone(context);
} catch (err) {
cmdline.onFail(err);
}
}, false)
Context
- 负责实例化一个全局对象,配置相关的属性信息。
- 安装依赖包,
_installProjectDeps
; - 检测
.dawn
目录下配置文件,configIsExists
; - 解析pipeline中命令对应的任务及任务参数,
loadPipeline
; - 按顺序调用中间件,
_execQueue
; - 加载中间件,
load
;
安装依赖——_installProjectDeps
触发mod
,exec
模块当中的方法执行。
如果.dawn
目录、node_modules
目录和package.json
文件都存在,则执行安装依赖操作:npm i --registry=https://registry.npmjs.com/
依次调用中间件——_execQueue
在中间件 middwares
队列中获取头元素,通过load
方法加载到对应的中间件函数 handler
,调用 handler
方法,同时将 next
传递到此 handler
中。方便调用下一个中间件的调用。
async _execQueue(middlewares, args, onFail) {
const middleware = middlewares.shift();
if (!middleware) return;
// 加载中间件
const handler = await this.load(middleware);、
const next = (args) => {
console.log(next.__result)
if (next.__result) return next.__result;
next.__result = this._execQueue(middlewares, args, onFail)
.catch(err => onFail(err));
return next.__result;
};
return handler.call(this, next, this, args);
}
加载中间件——load
/**
* opts就是loadPipeline解析出来的每个任务参数
*/
async load(opts) {
if (utils.isFunction(opts)) return opts;
if (!opts || !opts.name) {
throw new Error('Invalid pipeline config');
}
opts = this._parseOpts(opts);
const modFactory = opts.location ?
require(path.resolve(this.cwd, opts.location)) :
await middleware.require(opts.name, this.cwd); // 核心代码
if (!utils.isFunction(modFactory)) {
throw new Error(`Invalid middleware '${opts.name}'`);
}
return modFactory.call(this, opts, this);
}
加载中间件,会调用middleware
模块的require
方法,通过opts.name和中间件前缀dn-middleware
拼接出中间件完整的name
, 再拼接上node_modules
,生成绝对路径,通过node
的require
方法导入。最终导入的就是中间件的函数。赋值给modFactory
调用;
中间件前缀则是在 package.json
的 configs
中配置好的。
{
"configs": {
"server": "https://alibaba.github.io/dawn",
"registry": "https://registry.npm.taobao.org",
"npm": "npm",
"cache": 3600000,
"middlewarePrefix": "dn-middleware",
"templatePrefix": "dn-template"
},
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!