@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的声明一目了然,但是使用上也繁琐很多

最新文章

  1. SimpleDateFormat使用详解——日期、字符串应用
  2. leetcode题目清单
  3. POJ 3974 回文串-Manacher
  4. Codeforces Round #356 (Div. 2)
  5. 为Asp.net MVC中的RenderSection设置默认内容
  6. 【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题
  7. SQLSERVER 16进制与10进制转换
  8. Codeforces Round #249 (Div. 2)B(贪心法)
  9. 做XH2.54杜邦线材料-导线
  10. HDOJ2027统计元音
  11. Python/Keras如何将给定的数据集打乱
  12. Python作业day2购物车
  13. Android UI ActionBar功能-在 Action Bar 上添加按钮
  14. js倒计时函数和(js禁用和恢复a标签的操作)
  15. opencv2.4.9卸载安装
  16. JavaScript 实现textarea限制输入字数, 输入框字数实时统计更新,输入框实时字数计算移动端bug解决
  17. JavaScript中的 this全面解析
  18. 建立标准编码规则(二)-DiagnosticAnalyzer 增加诊断分析代码
  19. forever start app.js 启动node时,服务访问一次后第二次就不能访问了
  20. File类文件的常见操作

热门文章

  1. BZOJ1008: [HNOI2008]越狱-快速幂+取模
  2. Linux /bin, /sbin, /usr/bin, /usr/sbin 区别
  3. 为什么vertical-align不起作用
  4. angular2 Http和websocket
  5. [学习OpenCV攻略][011][显示图片]
  6. 用于 C♯ 图像识别的轮廓分析技术
  7. 【自制工具类】struts返回json数据包装格式类
  8. element-ui中upload组件如何传递文件及其他参数
  9. dede被注入后台提示用户名不存在解决方法
  10. SQLITE3 使用总结(3~5)(转)