• [PyJs系列介绍]二、缘起和核心概念


    续上,这一篇来深入到PyJs内部,讲一讲它是怎么运作的。

    首先说一下PyJs的诞生记。

    关于coding,我一只有坚持两个原则:

    1. 不写重复的,无意义的代码--DRY

    2. 编码不能有过多的约束。

    在开发百度连接JavaScript SDK的过程中,会面临一个问题:代码要保持一定的规范性以便更多的服务能方便的接入到整个SDK里面来。一开始的做法会加入很多命名空间来规划服务,同时要求代码必须遵循一定的风格。这样无疑违背了自己第二个原则,而且各服务的开放接口千奇百怪,控制起来也很头疼。

    这时就想到了commonjs。使用commonjs的话,其他服务的内部代码其实可以风格迥异,只要对于需要开放的对象或方法,加上一个exports.xxx=xxx即可。这样约束不多,也很好的保证了API的简洁性,同时也有安全沙箱,多个服务之间的代码不会项目冲突。

    于是搜遍天下commonjs的实现,比较著名的RequireJs和国内的SeaJs。这两种以各自的方式实现了浏览器端的commonJS,但是最致命的问题是没有解决依赖链导致文件串行加载的问题。同时百度开放平台有提供js combo服务,但是在这两者的架构下显然无法实现。另外一个问题,这两者又违反了我第一个原则。两者均需要给自己的模块手动写上一些公共的模板。如SeaJs会有如下的模板需要每个文件中都加入:

    define(function(require, exports, module) {
      my code goes here...

    });

    对于我是很难接受的。

    正好最近也在学python,参考yui3的源码和编译过程,于是突发奇想做了PyJs。

    PyJs的使用依赖于下面几个概念:

    Python 本地服务器

    这也是选择python来做这个事情的一个重要原因。

    开发的时候,需要本地启动一个服务器,如下:

    python pyjs.py runserver 

    我们在做commonjs的require module的时候,会通过本地服务器去寻找需要的module。我们编写模块只需要遵循commonjs最简单的规范即可,如下:

     var add = require('math').add;

    exports.increment = function(val) {
        return add(val, 1);
    };


    服务器找到这个文件之后,会把它与lib/modules.js里面的模板进行一个拼合,lib/modules/js文件如下:

    define( "##package##" , function(require , exports , module){
        
    ##file##

    } );

    其中的##package##会替换成require的模块名,也是文件名,##file##会替换为模块内容,生成之后的内容如下:

    define( "increment" , function(require , exports , module){
        
    var add = require('math').add;
    exports.increment = function(val) {
        return add(val, 1);
    };

    } );

    这样不需要我们人工去定义模块和加公共模板,即实现了一个完整的模块定义。

    本地服务器同时也是一个静态文件服务器,所以我们可以直接写测试用的html,css等,直接调用。

    pyjs.js

    在lib目录下有pyjs.js。这是全局方法声明的核心文件,定义了require,exports等方法和对象。本地调试的时候都请加入这个文件。

    由于js本身不需要处理很复杂的预解析过程,这个文件很小,源码的代码行数就才200来行,体积与requirejs和seajs的种子文件相比优势是很大的。

    PyJsDir

    本地服务器中有说道module的寻找,但python服务器本身就可以作为一个静态资源服务器,服务器是怎么区分是一个静态资源还是一个module呢,这里就需要PyJsDir的定义了。

    默认的PyJsDir是在根目录的src文件夹下, 可以在manifest.json中配置(稍后介绍)。服务器寻找一个请求的基本流程如下:

     

    所有的模块都要部署在pyjsdir下。

    manifest.json 

    这是整个pyjs的核心配置文件,与服务有关的配置都写在这个文件下。使用标准JSON格式。

    Require与dependence

    对所有的模块,使用require函数统一进入。

    本地调试时候的require,是只用同步ajax去传输文件的,这样我们在本地可以直接用require('b').xxx这样的方式写。但对于编译后需要发布的文件,将使用完全不同的方式加载:有combo服务的将使用combo服务加载文件;没有combo服务的将同时请求所有的依赖文件再按序执行。同时我们会有预编译机制,把一个模块的所有依赖(dependence)全部取出来,来实现上面两种模式。下一篇将详细描述。 

    so ,我们在本地调试的时候,只需要启动一个服务器,写一个静态页面把lib/pyjs.js引入,在pyjsdir下面使用commonjs语法编写module,在页面中require相应的module即可。是不是毫无压力 XD

    PS: PyJS有适用环境。比较适合没有模板,只有静态页面,特别是页面中js逻辑比较复杂的项目适用。模板类的就最好别使用了,也不是目标用户。。。专注,专注。。。 

  • 相关阅读:
    NFS4.1规范研究:session
    散列冲突与作为特征值的散列
    使用Select的3个注意事项
    3个学习Socket编程的简单例子:TCP Server/Client, Select
    Gdb调试多进程程序
    Usage of pmake
    诡异的bug: tcsh陷入死循环
    【转】PowerDesigner 物理数据模型(PDM) 说明
    大批量文件处理的7条建议
    OLE DB、ODBC 和 Oracle 连接池 (ADO.NET)
  • 原文地址:https://www.cnblogs.com/demix/p/2154181.html
Copyright © 2020-2023  润新知