资讯专栏INFORMATION COLUMN

React原理探索- @providesModule 模块系统

My_Oh_My / 3168人阅读

摘要:原理探索模块系统是什么抛出组件化的概念后,对于开发者而言,为了提高代码的可读性与结构性,通过文件目录结构去阐述组件嵌套关系无疑是一个很好的办法,但是目录级别的加深,同时让的文件路径让人头疼。

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([])

如何实现@providesModule

fbjs-script/gulp:

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

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92423.html

相关文章

  • React Native组件开发指南

    摘要:的组件开发一直处在一个比较尴尬的处境。目录包含了当前组件的源码,是组件开发最主要的目录。许多的开发者对于依然持怀疑态度。 React Native的组件开发一直处在一个比较尴尬的处境。在官方未给予相关示例与脚手架的情况下,社区中依然诞生了许许多多的React Native组件。因为缺少示例与规范,很多组件库仅含有一个index.js文件。这种基础的目录结构也导致了一些显而易见的问题,例...

    yuanxin 评论0 收藏0
  • ReactNative-HMR原理探索

    摘要:原理探索前言在开始本文前,先简单说下我们在开发项目中,本地的服务究竟扮演的是什么样的角色。这无疑是阉割了一大部分功能综上,如果仅仅用于切图,可能不会有那么多的问题 ReactNative-HMR原理探索 前言 在开始本文前,先简单说下我们在开发RN项目中,本地的node服务究竟扮演的是什么样的角色。在我们的RN APP中有配置本地开发的地方,只要我们输入我们本地的IP和端口号8081就...

    GT 评论0 收藏0
  • 初窥基于 react-art 库的 React Native SVG

    摘要:语法更近似于移动端。当参数为两个时,等同于,绘制光滑二次贝塞尔曲线。有些精通的同学这时候可能就要问我了,不对啊,二次贝塞尔曲线和光滑三次贝塞尔曲线的参数都是个,你这里没有光滑三次啊因为开发的同学留坑没写了呀微笑。和则是用于指定旋转的原点。 技术背景 在移动应用的开发过程中,绘制基本的二维图形或动画是必不可少的。然而,考虑到Android和iOS均有一套各自的API方案,因此采用一种更普...

    xiaowugui666 评论0 收藏0
  • SegmentFault 技术周刊 Vol.4 - 这份 Android 有点甜

    摘要:阅读本期周刊,你将快速入门,开启甜蜜之旅。然则的原理负责发送以及处理消息,创建消息队列并不断从队列中取出消息交给,则用于保存消息。 showImg(/img/bVCN99?w=900&h=385); 2016 年 8 月,Android 7.0 Nougat(牛轧糖)正式发布,那么问题来了,你 Marshmallow 了么(¬ -̮ ¬) Cupcake、Donut、Gingerbre...

    jay_tian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<