@providesModule是什么

react抛出组件化的概念后,对于开发者而言,为了提高代码的可读性与结构性,通过文件目录结构去阐述组件嵌套关系无疑是一个很好的办法,但是目录级别的加深,同时让require的文件路径让人头疼。绝大多数公司会使用自己定制的alias工具,在脚手架入口配置文件中给相应的filePath赋予别名,pack时,进行统一替换。

#ykit.config

...
alias:{
'Common':'./src/util/index.js',
'Component':'src/components/index.js'
}
...

当然也可以在文件中写入唯一的标识位,pack时将该标识位与当前声明标识位的filePath建立联系,facebook提供的@providesModule的就是这一策略。使用方法如下:

#a.js
/**
* @providesModule Common
*/ export const isArray = () => {
...
} export const isObject = () => {
...
} #b.js import { isArray } from 'Common' isArray([])

如何实现@providesModule

fbjs-script/gulp:

shared/provides-module.js中提供了这样一段正则,用于匹配文件中是否有类似@providesModule的标识符


module.exports = {
regexp: /\r?\n \* \@providesModule (\S+)(?=\r?\n)/,
};

modules-map.js 中:

transform函数调用如上正则对读入文本进行解析,并将alias的别名与filePath建立映射关系

flush函数将前面拿到的映射表进行处理加上统一前缀,并导入到json文件中



function transform(file, enc, cb) {
if (file.isNull()) {
cb(null, file);
return;
} if (file.isStream()) {
cb(new gutil.PluginError('module-map', 'Streaming not supported'));
return;
} // Get the @providesModule piece of out the file and save that.
var matches = file.contents.toString().match(PM_REGEXP);
if (matches) {
var name = matches[1];
if (moduleMap.hasOwnProperty(name)) {
this.emit(
'error',
new gutil.PluginError(
PLUGIN_NAME,
'Duplicate module found: ' + name + ' at ' + file.path + ' and ' +
moduleMap[name]
)
);
}
moduleMap[name] = file.path;
}
this.push(file);
cb();
} function flush(cb) {
// Keep it ABC order for better diffing.
var map = Object.keys(moduleMap).sort().reduce(function(prev, curr) {
// Rewrite path here since we don't need the full path anymore.
prev[curr] = prefix + path.basename(moduleMap[curr], '.js');
return prev;
}, {});
fs.writeFile(moduleMapFile, JSON.stringify(map, null, 2), 'utf-8', function() {
// avoid calling cb with fs.write callback data
cb();
});
}

最后导出如下json(以fbjs build为例)


{
"BrowserSupportCore": "fbjs/lib/BrowserSupportCore",
"CSSCore": "fbjs/lib/CSSCore",
"CircularBuffer": "fbjs/lib/CircularBuffer",
"DOMMouseMoveTracker": "fbjs/lib/DOMMouseMoveTracker",
"DataTransfer": "fbjs/lib/DataTransfer",
"Deferred": "fbjs/lib/Deferred",
"ErrorUtils": "fbjs/lib/ErrorUtils",
"EventListener": "fbjs/lib/EventListener",
"ExecutionEnvironment": "fbjs/lib/ExecutionEnvironment",
"Heap": "fbjs/lib/Heap",
"IntegerBufferSet": "fbjs/lib/IntegerBufferSet",
"Keys": "fbjs/lib/Keys",
"Locale": "fbjs/lib/Locale",
"Map": "fbjs/lib/Map",
"PhotosMimeType": "fbjs/lib/PhotosMimeType",
"PrefixIntervalTree": "fbjs/lib/PrefixIntervalTree",
"Promise": "fbjs/lib/Promise",
"PromiseMap": "fbjs/lib/PromiseMap",
}

而后该做什么大家也清楚了,要么node脚本去把文件里require 对应别名的进行路径替换,要么通过babel替换,当然,facebook是通过babel玩的

题外话

其实对于alias system目前提供的两种方法,各有利弊。fb提供的方法,使得使用上更加便利,但是由于alias遍地存在,声明冲突也变得家常便饭(当然可以通过统一前缀解决)。传统在脚手架配置文件中声明的方法,虽然能让你对alias的声明一目了然,但是使用上也繁琐很多

React原理探索- @providesModule 模块系统的更多相关文章

  1. 探索Java9 模块系统和反应流

    Java9 新特性 ,Java 模块化,Java 反应流 Reactive,Jigsaw 模块系统 Java平台模块系统(JPMS)是Java9中的特性,它是Jigsaw项目的产物.简而言之,它以更简 ...

  2. vue原理探索--响应式系统

    Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是「响应式系统」. 首先看一下 Object.defi ...

  3. ABP文档笔记 - 模块系统 及 配置中心

    ABP框架 - 模块系统 ABP框架 - 启动配置 Module System Startup Configuration ABP源码分析三:ABP Module ABP源码分析四:Configura ...

  4. webpack前言:前端模块系统的演进

    前端开发和其他开发工作的主要区别,首先是前端是基于多语言.多层次的编码和组织工作,其次前端产品的交付是基于浏览器,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源 ...

  5. Nodejs中的模块系统

    一.模块化的定义 ①具有文件作用域 ②具有通信规则:加载和导出规则 二.CommonJS模块规范 1.nodejs中的模块系统,具有文件作用域,也具有通信规则,使用require方法加载模块,使用ex ...

  6. 极简 Node.js 入门 - 1.2 模块系统

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  7. ABP(现代ASP.NET样板开发框架)系列之4、ABP模块系统

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之4.ABP模块系统 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  8. ABP框架 - 模块系统

    文档目录 本节内容: 简介 模块定义 生命周期方法 PreInitialize(预初始化) Initialize(初始化) PostInitialize(提交初始化) Shutdown(关闭) 模块依 ...

  9. Node.js 教程 04 - 模块系统

    前言: Node.js的模块系统类似于C/C++的文件引用,可以声明对象,也可以定义类 创建对象. 大家这么理解,就简单了. 定义: 为了让Node.js的文件可以相互调用,Node.js提供了一个简 ...

随机推荐

  1. bzoj:1723: [Usaco2009 Feb]The Leprechaun 寻宝

    Description 你难以想象贝茜看到一只妖精在牧场出现时是多么的惊讶.她不是傻瓜,立即猛扑过去,用她那灵活的牛蹄抓住了那只妖精.     “你可以许一个愿望,傻大个儿!”妖精说.     “财富 ...

  2. python面向对象进阶

    前言 上节大话python面向对象对面向对象有了一些了解,这次就不用大话风格了 (ps:真心不好扯啊) isinstance与issubclass isinstance(obj,cls)检查是否obj ...

  3. vue vue-style-loader !css-loader错误

    最近在学习vue框架,使用webpack打包vue项目,在执行npm run start的时候 出现如下错误: This dependency was not found: * !!vue-style ...

  4. p2p项目,自己期望太高了。

    在项目的进行中,主要牵扯到了一些安全方面的考虑,跟money相关的嘛,如果安全不考虑,你就惨了,一期呢,为了防止数据被篡改,主要对数据用dsa进行了签名,二期呢,考虑到das产生的字符串有可能太长,修 ...

  5. win10安装配置jdk的环境变量

    换了个硬盘,用上了win10,发现win10安装好jdk之后,配置环境变量这个相对于win7和xp还是有那么一丢丢区别的,趁着夜色,随笔一记. 1.安装jdk之后,或者也可以用之前安装好的文件夹,先记 ...

  6. h5学习笔记:vuethink 配置

    vuethink 是一款基于PHP TP5和Vuejs 结合的后台框架,设计起来是使用较为前沿.在使用的过程,需要对这款开源的后台做一些调整和面对一些细节的坑.前段时间也因为有项目需求,所以下载了玩了 ...

  7. Eclipse版本

    Eclipse  3.1  IO 木卫一,伊奥                       2005Eclipse  3.2  Callisto 木卫四,卡里斯托        2006Eclipse ...

  8. 洛谷 P1099 树网的核

    P1099 树网的核 题目描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W ...

  9. vue初学者

    先分享一波福利 vue学习视频    链接:https://pan.baidu.com/s/1ggSfE75 密码:7h2a        1.先安装 webpack vue-cli          ...

  10. 一个使用物理引擎的WebGL3D场景

    这是一个类似第三人称射击游戏(TPS)的3D场景,可以通过https://ljzc002.github.io/FPS2/index.html访问.场景运行效果如下图: 场景环境由一个天空盒和一个地面网 ...