UMI 源码解析 核心代码解析

在/umi/lib/forkedDev.js中有这么几行核心代码,还引入了好几个文件,好复杂,现在一一解析一下

var _ServiceWithBuiltIn = require("./ServiceWithBuiltIn");

var _getCwd = _interopRequireDefault(require("./utils/getCwd"));

var _getPkg = _interopRequireDefault(require("./utils/getPkg"));

const service = new _ServiceWithBuiltIn.Service({
    cwd: (0, _getCwd.default)(),
    pkg: (0, _getPkg.default)(process.cwd())
});
yield service.run({
    name: 'dev',
    args
});

目录

_getCwd   /umi/utils/getCwd.js

_getPkg   /umi/utils/getPkg.js

_ServiceWithBuiltIn   /umi/lib/ServiceWithBuiltIn.js


_getCwd   /umi/utils/getCwd.js

文件内部核心代码如下:

var _default = () => {
  //获取umi 项目的根路径。
  let cwd = process.cwd();

  if (process.env.APP_ROOT) {
    // avoid repeat cwd path
    if (!(0, _path().isAbsolute)(process.env.APP_ROOT)) {
      return (0, _path().join)(cwd, process.env.APP_ROOT);
    }

    return process.env.APP_ROOT;
  }

  return cwd;
};
exports.default = _default;

主要功能就是利用获取node命令执行的路径,获取项目的绝对路径,但里面那个APP_ROOT的变量判断不是很懂

_getPkg   /umi/utils/getPkg.js

文件内部核心代码如下:

var _default = dir => {
  try {
    return require((0, _path().join)((0, _getCwd.default)(), 'package.json'));
  } catch (error) {
    try {
      return require((0, _path().join)(dir, 'package.json'));
    } catch (error) {
      return null;
    }
  }
};

exports.default = _default;

主要功能就是根据绝对路径拼接获得package.json文件的路径

_ServiceWithBuiltIn   /umi/lib/ServiceWithBuiltIn.js

class Service extends _core().Service {
  constructor(opts) {
    process.env.UMI_VERSION = require('../package').version;
    process.env.UMI_DIR = (0, _path().dirname)(require.resolve('../package'));
    super(_objectSpread(_objectSpread({}, opts), {}, {
      presets: [require.resolve('@umijs/preset-built-in'), ...(opts.presets || [])],
      plugins: [require.resolve('./plugins/umiAlias'), ...(opts.plugins || [])]
    }));
  }
}

这个Service 继承了 CoreService,对其进行了加强。 

process.env.UMI_VERSION 
process.env.UMI_DIR //path模块的学习

 进行全局环境变量的配置

然后我们发现他企图通过父类的构造函数来初始化,但对这个传参利用_objectSpread进行了比较复杂的处理,我们先一一分析一下这个参数是怎么做到的。

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

super(_objectSpread(_objectSpread({}, opts), {}, {
      presets: [require.resolve('@umijs/preset-built-in'), ...(opts.presets || [])],
      plugins: [require.resolve('./plugins/umiAlias'), ...(opts.plugins || [])]
    }));

在这里我先介绍一下es6里面的几个新的方法,我之前也没见过

Object.getOwnPropertySymbols:获取以Symbol为对象的属性名数组(Obj.keys()获取不到)
Object.getOwnPropertyDescriptor:一个参数:此方法返回规定对象的所有属性,包括getter、seter,允许我们在创建副本的对象并复制所有属性克隆他;两个参数:如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor,包含value,writerable..),否则返回 undefined(enumerable:当且仅当指定对象的属性可以被枚举出时,为true。)、
可枚举性:若为false,在利用 for..in.. Objkect.keys JSON.stringfy时不会显示该属性

在这里对比一下自带的几个获取属性键值的函数

Object.keys():返回属性key,但不包括不可枚举的属性、Symbol对象的属性
Reflect.ownKeys():返回所有属性输出
Object.getOwnPropertySymbols:返回所有Symbol对象的属性

ownKeys:获取该对象的所有拥有的key(视情况去除不可枚举的symbol对象的key)
利用Object.keys获取键值,如果Object.getOwnPropertySymbols函数存在的话,就将Sybmol对象的键值也获取进来。如果设置仅需要可枚举属性的话,会对Sybmol键值进行过滤(利用Object.getOwnPropertyDescriptor判断是否是可枚举属性)。将获取到的键值组合并返回

_defineProperty:设置obj[key]=value

 

然后对这个CoreService追溯,在@umijs/core/Service/Service.js中,进一步解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值