zoukankan      html  css  js  c++  java
  • 转:seajs的spm使用摸索

    ~~~spm是基于nodejs的,打开nodejs命令行工具,npm install spm -g 进行spm的安装,过程很漫长 github上的官网不能访问

    seajs自带的spm打包工具相关文档略少,在粗读了一点源代码之后,我摸索出了spm使用上的一些要点,记录为此文

    压缩JS文件

    只需要执行这个命令即可

    spm build xxx.js
    

    这时候你将得到一个压缩过的__build/xxx.js文件

    合并JS文件

    如果希望将JS文件中require的其他模块都合并到这个文件中,我们可以加上--combine参数
    另外记得这时候必须传递--app_url参数,用于生成module的id,如

    spm build xxx.js --combine --app_url http://x.com
    

    你将与上面一样得到一个__build/xxx.js文件,但是这个js中require的模块也都合并在这个文件中了

    合并JS文件的规则

    一般说来,前端优化时,并非链接数越少越好,对于通用JS类库,由于在多个页面中都会被引用,单独加载可以利用到浏览器缓存

    spm在合并时,也考虑到了这种情况,因此它遵循这样一个规则,即只合并require的“相对标识”的模块,而不合并require的“顶级标识”的模块
    对“相对标识”和“顶级标识”不了解的参见http://seajs.com/docs/zh-cn/module-identifier.html

    为什么是这样一条规则呢?因为seajs的作者推荐使用这样一条规则来require模块:
    “推荐使用 require('xxx') 这种方式引用通用类库,使用 require('./xx') 或 require('../path/to/yy') 引用业务模块”

    所以,spm在合并时,不会合并通用类库的模块,而判断是否是通用类库的依据就是“相对标识”与“顶级标识”,因此这也要求我们在书写代码时,需要遵守以上的规则

    强制合并通用类库

    某些特殊情况下,我们希望将通用类库也合并进来,当然最简单的办法就是在代码中使用“相对标识”来require通用类库,不过这个办法实在太蠢
    而且spm也有相应的处理方案,我们需要添加--combine_all参数,但是这时候我们还必须传递--base_path参数,指定通用类库所在的文件夹,也就是seajs的base路径
    命令参考如下

    spm build xxx.js --combine_all --app_url http://x.com --base_path ./lib/

    输出文件路径

    默认情况下,spm会把文件输出到当前文件同级的__build子文件夹下,在以上几点的例子里面已经看到了
    spm也支持用--out_path参数自定义路径,而且如果有同名文件的话会自动覆盖,这点在部署时候做自动化替换很有用
    命令参考如下

    spm build xxx.js --combine --app_url http://x.com --out_path .
    

    以上命令会将当前的xxx.js替换为合并后的

    app_path参数

    以上的讨论,都是假设JS文件位于“根”下面,也就是说
    假设js在文件系统的目录为D:projectxxx.js,而未来部署后,访问路径为http://x.com/xxx.js
    那么进入D:project目录,执行spm build xxx.js --combine --app_url http://x.com命令,这时候build出的文件是没有问题的

    下面考虑一下复杂的情况:
    假设js在文件系统中位于D:projectjavascriptxxx.js,而部署后,访问路径为http://x.com/javascript/xxx.js
    那么如果我们进入D:projectjavascript目录,执行上述同样命令,这时候build出的文件是有问题的,哪里有问题呢?打开build出的文件一看就知道了
    一般这时候文件中define的id语句是这样的

    define("http://x.com/xxx.js", //省略
    

    明显这是有问题,我们期望编译出的id应该是http://x.com/javascript/xxx.js,假设路径再深一点,如果存在两个同名而目录不同的js,就会存在define id重复了
    那么如何解决呢?我发现spm还提供一个--app_path参数,尝试执行以下命令,将项目的“根”路径做为--app_path参数

    cd D:project
    spm build javascriptxxx.js --combine --app_url http://x.com --app_path D:project --out_path .
    

    这时候因为out_path为. 所以xxx.js已经被替换掉了,打开发现define id正确无误,是http://x.com/javascript/xxx.js
    这是因为当传递了--app_path参数时,spm会计算要合并的js文件的路径与这个路径的相对路径,举例来说,就是计算出D:projectjavascriptxxx.js与D:project的相对路径,也就是javascriptxxx.js,然后将这个路径再与--app_url参数连接,作为define的id

    注意:但是这里有个问题,如果不指定--out_path时,spm会出错,因为这时候--out_path默认为D:projectjavascript_buildjavascript,而似乎spm只能新建_build文件夹,对于下级文件夹不会再新建,所以会报错

    使用build-config.js

    如果不希望在敲命令时候传那么多乱七八糟的参数,可以将这些参数写在build-config.js里面,如下

    module.exports = {
        "base_path": "../",
        "app_url": "http://x.com",
        "app_path": "http://www.cnblogs.com/"
    };
    

    当你在某个目录下执行spm build命令时,spm会自动寻找当前目录下有没有build-config.js文件,如果有则将内容解析为参数
    当然如果你不喜欢这个名字,你还可以在执行spm命令时,用--config指定build配置文件

    loader_config参数

    如果你在某个js文件中,使用了seajs.config做了alias的配置,则打包时,需要传递--loader_config参数,将文件传给spm

  • 相关阅读:
    Android连载7-动语添加碎片
    JavaScript连载6-转化为Number和Boolean类型、运算符
    Java连载111-timer定时器、反射机制概述
    用conda创建虚拟环境的一些常用命令
    Java内存分析
    Java语言中的Class类
    线程协作
    LeetCode刷题笔记第26题
    LeetCode刷题笔记第20题(括号匹配)
    LeetCode刷提笔记第1332题
  • 原文地址:https://www.cnblogs.com/stephenykk/p/3683160.html
Copyright © 2011-2022 走看看