zoukankan      html  css  js  c++  java
  • 构建seajs业务模块之grunt VS spm build

    在最开始,我并不知道grunt可以构建CMD模块.(以下spm指代spm build)

    当时正困惑于如何用spm方便的构建业务模块,后来看到@twinstony (感谢@twinstony的分享)使用grunt-cmd-xxx插件构建了CMD模块,跟着demo自己做了测试,的确可以构建,但是有一个问题:

    grunt 方式不能把依赖的外部css(比如非项目中的jquery插件css)打包进来,而spm可以.

    其原因是,spm会根据别名配置依次(./sea-mpdules -> ~/.spm/cache -> -> 源)查找并下载依赖,最后将依赖的css依赖打包进来(通过seajs.imporStyle).

    而grunt并没有做这件事情,也许可以通过另一个grunt插件完成.

     

    另,include这个参数是针对js模块的,对于css 而言则是"all"

     

    还有一个不是问题的问题:

    用grunt方式构建,参数配置项太多了,有时候找问题不太好找.或者说是过于灵活了,有时使开发者们无所适从.

    而spm把很多东西都封装好了,只需配置简单几个参数即可,符合seajs简单一致的设计原则.

    其实spm底层也是调用了grunt-cmd-transport以及其他模块,但把一些繁杂的配置帮我们处理好了

     

    之前对于spm的困惑是:

    1.打包出的模块id只能是family/version/name么?  --通常业务模块并不需要这类命名

    2.打包出的模块路径只能是直接输出到dist目录下? --不能像grunt那样,构建出来的目录结构与源文件的目录结构一致么?

    3.输出目录不能指定么,只能是dist么? --如果可以指定,就可以直接省略掉部署环节(本地部署)

     

     

    经过摸索与咨询,得出一个可行的解决方案,感谢@popomore 的指点

    示例代码下载链接:

     https://github.com/stoneChen/seajs-backbone-test/tree/master

    (以下所有spm命令均在sea-modules的上一层目录下,即js下执行,package.json设置在这里)

    A.所有模块部署在项目中.

     

    以下以一个简单的示例(需要对backbone有一定了解)演示.

     

    上图是目录结构.

    sea-modules是spm默认的模块安装目录名.

    为了开发方便,不必每次查看效果都要spm build一番,在开发阶段不使用spm打包代码,除源上的已成熟的组件外(可通过spm install安装都本地),均使用匿名模块查看页面效果.

     

     

     

    上图是我把seajs结合backbone做的一个demo.

    等所有功能开发完毕后,现在页面引入模块文件是这样的

    seajs.use('start.js');

     

    接着,进入打包阶段.

     

    {
    
        "family": "test",
    
        "version": "0.0.1",
    
        "name": "spmTest",
    
        "spm": {
    
            "idleading": "_output/",
    
            "source": "sea-modules",
    
            "output": [
    
                "start.js",
    
                "app/gettingStart.js",
    
                "app/index.js",
    
                "app/userlist.js",
    
                "collection/C_userlist.js",
    
                "model/M_gettingStart.js",
    
                "model/M_index.js",
    
                "model/M_user.js",
    
                "view/V_gettingStart.js",
    
                "view/V_index.js",
    
                "view/V_user.js",
    
                "view/V_userlist.js"
    
            ],
    
            "alias": {
    
                "$": "jquery/jquery/1.7.2/jquery",
    
                "$-debug": "jquery/jquery/1.7.2/jquery-debug",
    
                "jquery": "jquery/jquery/1.7.2/jquery",
    
                "jquery-debug": "jquery/jquery/1.7.2/jquery-debug",
    
                "select2": "jquery/select2/3.4.5/select2-zh-cn",
    
                "select2-css": "jquery/select2/3.4.5/select2.css",
    
                "select2-css-debug":"jquery/select2/3.4.5/select2-debug.css",
    
                "underscore": "gallery/underscore/1.5.2/underscore",
    
                "backbone": "gallery/backbone/1.1.0/backbone"
    
            }
    
        }
    
    }

     

    以上为package.json配置.

    然后终端执行

    spm build -O sea-modules/_output

     

    如上图,然后_output目录就会被创建,相应目录结构的模块就会依次生成好.

     

    然后改变页面上引入模块的路径,只需添加一个前缀即可:

     

    seajs.use('_output/start.js');  //开发阶段是seajs.use('start.js');

     

    之前开发好的功能,现在一样能够跑通,而且执行效率会更高.

     

     

    下面,讲一下其中的注意点

     

    package.json重点是idleading,source,output的配置

     

     

    "idleading": "_output/",
    
            "source": "sea-modules",
    
            "output": [
    
                "start.js",
    
                "app/gettingStart.js",
    
                "app/index.js",
    
                "app/userlist.js",
    
                "collection/C_userlist.js",
    
                "model/M_gettingStart.js",
    
                "model/M_index.js",
    
                "model/M_user.js",
    
                "view/V_gettingStart.js",
    
                "view/V_index.js",
    
                "view/V_user.js",
    
                "view/V_userlist.js"
    
            ],

     

    1.idleading如果不配置,那么生成出来的id就是family/version/name这种形式,这个值怎么配,需要与source,output配合,最终达到的效果就是最终加载这个模块的路径(require或use的参数)与生成的id值要一致,至于为什么,请参考https://github.com/seajs/seajs/issues/930

     

    2.source指定从当前目录下的哪个目录"查找"需要被构建的模块,这个官方文档有说明

     

    3.output指定具体要被构建的模块,这里很重要,数组里的每个路径怎么写,生成出来的目录结构就是怎么样的.我曾经试过,将他们写成

     

    "output": [
    
                "start.js",
    
                "app/*.js",
    
                "collection/*.js",
    
                "model/*.js",
    
                "view/*.js"
    
            ],

    但是前面提到那个css打包问题又出现了,而且模板文件也不打包了,好像是合并操作都失效了的感觉.这个就不知为何了,曾经提过issue,说是不支持这种写法.

    4.执行build命令时指定 -O 的值,指定输出目录, 这个除了这种方式,不知道怎么在配置文件中解决,也提过issue,貌似需要自己实现.

    5.还有一个奇怪的警告:

     

    为啥会去找sea-debug?(后补:transport任务会转换source下所有文件,而sea-debug当然不是cmd模块,但是压缩版的sea.js也不是啊,怎么不警告?)

    还有一点,下面那个152 files,貌似是对souce下的所有文件都进行transport了,但目标并不是全部,也就是说,实际上output的配置在transport后才起作用,是不是有些不太合理?

     

     

     

    这样打包好后,结合seajs-debug,seajs-debug用于测试环境,线上调试,以及map控制时间戳,就能很好的管理所有模块了

     

    ps:关于seajs的默认base,还有这种情况在:

     

     

    本demo中即属于这种情况.

     

    构建输出目录在sea-modules/_output下

    访问backbobe-test.html查看最终效果

     

    个人建议将工程代码在webstorm(@7.0+)中打开,webstorm会自动启动一个web服务,或者其他能够启动web服务的方式.

     

    seajs-backbone作为根目录

    B.业务模块部署在项目中,其他模块包括seajs本身及其插件部署在静态资源服务器见附件,构建时,只需将idleading做适当转换即可,总之要保证require或use时的路径和id一致

     

    构建输出目录在sea-modules/_output2下

    访问backbobe-test-outer.html查看最终效果

     

    这种情况下需要启动两个web服务,一个webstorm的,一个静态资源服务器的,个人建议使用nodejs的anywhere启动.

     

    接下来附上几幅效果图

    A1.开发阶段:

     

     

    A2.构建好后:

     

     

    A3.构建好后,使用seajs-debug调试:

     

     

     

    B1.公用模块外部部署,开发阶段:

     

    B2.公用模块外部部署,构建好后:

     

    B3.公用模块外部部署,构建好后调试:

     

     

     

     

    代码下载地址:

     https://github.com/stoneChen/seajs-backbone-test/tree/master

     

    欢迎大家指出不正确或不合理的地方~

     

  • 相关阅读:
    pip 最新版 发布(Python包安装和管理工具)
    Python使用cookie 免密登录了解一下
    夯实根基,必知必会的 Python 基础知识
    10个关于文件操作的小功能,都很实用~
    总结一些网站加密和混淆技术
    接口加密如何测试?
    艰难的这年,程序员的未来在哪里?
    警惕“职场PUA”!
    Python面试题及答案汇总
    Python实例练手项目汇总(附源码)
  • 原文地址:https://www.cnblogs.com/webstone/p/3650081.html
Copyright © 2011-2022 走看看