React原理探索- @providesModule 模块系统
React原理探索- @providesModule 模块系统@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([]) 如何实现@providesModulefbjs-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的声明一目了然,但是使用上也繁琐很多 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 服务启动初始化相关配置 如XML、properties、log等文件
- XML和Schema命名空间详解
- 常用的正则表达式
- ruby-on-rails – Mac OSX Ruby on Rails安装问题 – 找不到
- c# – 在byte []中查找byte []的速度和在string中查找字符串
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践
- ajax标准格式参考
- Cocos2dx3.2编写常用UI组件(一)新手指导框GuideLayer
- objective-c – 核心数据 – 反向删除规则…我应该应用哪一
- c# – mvc PartialView with Dialog Partial View显示html