Sea.js模块打包工具spm

2024-01-29 06:08
文章标签 工具 模块 js 打包 spm sea

本文主要是介绍Sea.js模块打包工具spm,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

平台:Windows 7

版本:1.7.7


简介

Sea.js实现了对JS代码的模块化组织,大大提高了前端开发效率。然而在实际项目中,大量的细分模块却导致大量的脚本请求,拖慢了页面加载速度,也给服务器造成不小的压力。针对这一情况,spm(static package manager)因运而生,专门用于打包、压缩Sea.js模块以及CSS文件。

Sea.js遵循CMD(Common Module Definition)模块定义规范,一个文件一个模块,清清爽爽。CMD模块定义形如:

define(function(require, exports, module) {

    //使用require表达对其他CMD模块的依赖

    //使用exports或module.exports或return向外抛出接口

});

spm的打包原理很简单,就是将这一形式(Modules/Wrappings)的CMD模块转换为Modules/Transport形式:

define("id", ["dep-1", "dep-2"], function(require, exports, module) {

    //源码

});

这一过程仅仅是给模块换了个框框,spm需要完成的工作当然不止于此,主要可以概括如下:

1、如上述那样按照Modules/Transport格式在模块定义中加入标识和依赖,并把多个模块合并到一个文件中(包括CSS);

2、将源码中的变量名、函数名等标识符简化为a、b、c这样的单字母,并删除空格、缩进、换行等空白符(所以最终你看到的是一长串拥挤的、可读性极低的代码);

3、识别无用代码后将其删除,还有其他一些优化措施。

这些步骤在本地完成,都是静态的文本处理,过程并不复杂,如果用起来不满意,完全可以自己实现一个,甚至可以用C语言写。

安装

首先我们需要Node.js,到官网下载安装即可,完后记得把安装路径(如C:\Program Files\nodejs)加到环境变量Path里,在cmd中运行node -v查看版本以确定是否安装成功:

30022-36245791556ee03e.png

接着使用Node.js的包管理工具npm(node package manager)安装spm。spm版本已更新到3.9,但是从第3版开始转向了CommonJS规范,在打包前需要扒掉所有模块的define封装,项目中几十个乃至几百个文件都需要手动处理,实在犯不着。于是我们转投低版本——spm@2.x或spm@1.x,经过多次测试,spm@2.x的各个版本在安装或使用过程中总出现莫名其妙的报错,也许是与Windows兼容不佳(具体未能考证),只好拿spm@1.x将就将就——当然,spm@1.x已经可以满足所需。

安装spm前,如果Node.js装在了C盘,最好通过以下两行命令先修改一下npm的全局路径,否则spm的相关文件可能会无法正常写入磁盘:

npm config set prefix "D:\nodejs\node_global"

npm config set cache "D:\nodejs\node_cache"

(这里以D盘的一个路径为例,当然你得先新建好这两个文件夹。)

将spm@1.x安装到全局路径:

npm install spm@1.x -g

30022-cf9e5c631f238c04.png
安装过程(很不友好,目测就开发者自己看得懂)

完成后,在刚才设置的node_global文件夹下可以看到spm的相关文件,其中spm.cmd就是主程序,将D:\nodejs\node_global添加到环境变量Path,执行spm查看版本和可用指令:

30022-4b6db5b6d0e09790.png
我们需要使用的就是第一个build指令

如未能顺利安装或安装后使用有问题可以执行如下命令卸载spm,而后尝试重装(其他版本):

npm uninstall spm -g

使用示例

编写一个简单的示例,功能模块demo(位于modules目录下)包含a.js、b.js、c.js三个CMD模块,b和c放在subModules文件夹下,a作为入口调用b,b调用c:

30022-8646b28991413184.png
30022-cf8f6412e8381c3f.png
30022-3b0eee53c04dbd7e.png

通过seajs.use()在页面中调用a模块:

seajs.use(['modules/demo/a'], function(a) {

    a();

});

30022-80d03451068bc0cc.png

下面我们使用spm将a、b、c进行打包。首先需要一个工作目录,比如D:\spmworkspace,将整个功能模块(本例中就是demo文件夹)放在这里,而后需要一个package.json文件,用于编辑spm build的配置信息:

30022-545b475e2add8a79.png
package.json的配置项有很多,这里只用到了一些主要的

"root":功能模块的根目录名,这取决于它在整个项目中处于哪个位置。

"name":功能模块的名称。默认情况下,打包后的Modules/Transport模块标识是对"root"、"name"和CMD模块文件名的拼接,如在本例中模块a的id就是modules/name/a。

"src":源文件夹(要求与package.json在同级目录下),存放需要打包的JS文件们。

"to":目标文件夹,用于存放打包后生成的文件。该文件夹会自动生成,也与package.json在同级目录下。

"output":配置文件合并规则,这里配置的"a.js"要求在demo文件夹下必须存在相应的a.js文件。

配置好后,在cmd中来到工作目录D:\spmworkspace下,执行spm build:

30022-d336523f047e8dbd.png
不要在意那个血红的[ERROR],它对最终结果并无影响

此时在D:\spmworkspace下就出现了一个dist文件夹,里头包含a.js和a-debug.js两个文件,其中a.js是最终打包结果:

30022-2fa1b48965347561.png
代码被挤到一行里,能简化的都简化了

这是在项目上线时用的,在开发调试时,我们可以使用a-debug.js:

30022-e482d97acb305dab.png
换了define封装,模块合并至一个文件中,此外没有进行任何压缩,因此保有与打包前相同的可读性

部署时直接将a.js替换原本的a.js即可,subModules下的b.js和c.js不再需要,完美运行:

30022-55f829b07d741983.png

可以看到,只加载了压缩后的a.js,文件总体大小和加载时间都大大缩减,在实际项目中打包的CMD模块越多,表现就越好,这就是spm的价值所在。

几点补充

require的路径问题

通常在项目开发中,require主要使用两种形式的路径载入其他CMD模块:

一种是相对路径,以./或../开头,这种形式用于同一功能模块之内JS文件之间的相互引用;

一种是全局base寻址形式,直接以文件或文件夹名打头,形如xxx/xxx,Sea.js会根据SeaConfig.js中配置的base路径来拼接出绝对路径,这种形式用于功能模块之间JS文件的相互引用,比如有个实现通用功能的util模块,其他功能模块中的JS通常会以require(util/utilA)的形式引用。

spm打包是针对单个功能模块的,无法找到以上述第二种路径形式require的文件,因此不会将它们打包进来。确实对于其他功能模块里的东西,也没必要都压缩进来。

如果一定要将它们一齐打包,就需要用到spm提供的C/S模式的源服务。使用spm server指令可以在本地构建一个源服务器,局域网内的开发者可以将打包好的各个功能模块部署上去,通过在C:\Users\Administrator\.spm\config.json中增加源服务器、在package.json中增加"dependencies"配置、"output"中的"."改为"*",在打包时就可以加入在源服务中的其他功能模块。如此倒是提供了协同开发的可能性,但操作起来挺不方便,我也没有进行验证,如有不对之处,还望路过的大神不吝赐教。

多个入口文件的打包

在本文的demo示例中,整个功能模块只有a.js一个入口,它把其他CMD模块都牵扯到了,如果入口文件不止一个,或者说一些文件与另一些文件相互独立怎么办呢?比如在util下,有负责加法的add.js和负责减法的sub.js,它们之间互不引用,package.json可以这样配置:

"output": {

    "add.js": ".",

    "sub.js": "."

}

最终生成两个压缩后的JS,或者将它们强行合并:

"output": {

    "util.js": ["add.js", "sub.js"]

}

图片的相对路径问题

比如在CSS中使用相对路径引用图片,在打包前表现正常,但打包后CSS内容并入JS中,被载入JSP或HTML页面,相对路径将以页面文件位置为基准,此时就需要调整图片文件的位置,在开发时使用绝对路径可避免这一情况。

CSS载入问题

实测表明,只有在入口JS中载入CSS才能正常打包,如果其他CMD模块require了CSS,spm将提示无法找到该CSS文件,这一现象很奇特,目前尚未弄明原因。

开发约束/建议(仅针对1.7.7版)

1、确保所有JS文件符合CMD规范;

2、入口JS文件(可以有多个)应放在功能模块根目录下;

3、避免使用相对路径require其他功能模块里的JS;

4、CSS的require放在入口JS文件中;

5、使用绝对路径引用图片。

学习资料

关于Sea.js

Sea.js文档

使用SeaJS实现模块化JavaScript开发

关于spm

spm@1.x文档

为什么 SeaJS 模块的合并这么麻烦

seajs使用心得

我的前端之旅第一弹--SeaJs基础和spm编译工具运用


2016年2月22日 无锡

这篇关于Sea.js模块打包工具spm的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/655949

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

springboot3打包成war包,用tomcat8启动

1、在pom中,将打包类型改为war <packaging>war</packaging> 2、pom中排除SpringBoot内置的Tomcat容器并添加Tomcat依赖,用于编译和测试,         *依赖时一定设置 scope 为 provided (相当于 tomcat 依赖只在本地运行和测试的时候有效,         打包的时候会排除这个依赖)<scope>provided

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼?市面上那么多工具,常常让人无从选择。今天,想给大家安利一款神器——PixPin,一款真正解放双手的截图工具。 想象一下,你只需要按下快捷键就能轻松完成多种截图任务,还能快速编辑、标注甚至保存多种格式的图片。这款工具能满足这些需求吗? PixPin不仅支持全屏、窗口、区域截图等基础功能,它还可以进行延时截图,让你捕捉到每个关键画面。不仅如此