前端构建

后端有构建工具,比如Java的ant、maven,前端也有构建工具,比如现在非常流行的grunt。
前端构建,是在项目部署上线前,将js css html 图片合并压缩的过程,使用模块化开发时,又多了个规范化过程。

Seajs是非常好用,好用的代价是SPM构建打包起来很麻烦,文档不全,没好的实例。

demo地址 https://github.com/sprying/ys7
一、项目需求
我们要做成什么?
充分利用缓存,并减少请求数。

方案一:提炼出相同功能的组件,并存独立文件(dialog.js),随着业务的复杂化,组件越来越多,导致一次url访问请求数很多。特别是用户第一次进入页面时,要加载所有的资源,要等几十个资源请求load后,才发ajax请求。虽然组件配合缓存可能会减少页面的流量,但与繁多的请求相比,这种性能上提升几乎为0。(现在使用的)

方案二:一个页面一个js,这是另外个极端,不能充分利用浏览器缓存。

方案三:
均衡方案,开发时还是每个的功能,一个Js。但是上线时,合并一些组件到页面Js中,将请求数降低到理想值,同时还引入些公用Js、以利用缓存。

于是要考虑将组件划分成两类:要合并的Js,不要合并的Js。不要合并的Js,一种是通过script标签来的,每个页面都要用;另一种是通过Seajs动态加载。具体划分如下:

1)按照使用调用情况分:必加载组件、绝大地方都使用的组件、只有几个页面使用到的js、一个页面对应的js
2)按照业务分:基础、标准组件(比如弹出窗,backbone跟业务无关的)、业务组件、页面Js。

综合考虑,我们将结构分成如下,并采用业务命名区分

基础模块:所有的页面都需要,弄成一个请求,script标签引入。采用合并或者combo请求,比如jquery json2
标准模块:外面引入的插件,自己写的插件,比如backbone,dialog
业务模块:少数页面用到的业务Js,比如wifi
页面模块:页面对应的Js,比如add2.jsp对应的是add.js的入口。

当请求数还是偏多,协调标准模块和业务模块。

二、打包几个关键流程
Seajs是采用Cmd规范,很简约,跟nodeJs采用的Amd很像。打包的第一步是从简约变复杂。

打包的第一步

Seajs一个文件一个模块,我们最常见的写法define(function(require,exports){})

通过cmd规范的transport插件,变成define(id,[dependences],function(require,exports,module){})

打包的第二步,合并依赖模块,有三种配置,一种是self,不合并;一种relactive(默认),合并相对路径的依赖;一种all,合并所有依赖

打包的第三步,合并好后压缩。

这只是构建一个前端项目最原始的几个步骤。在项目里面,要考虑css、图片、组件层次问题,还要详细配置。

三、其它要考虑的
1)版本控制,版本控制当然为了充分利用浏览器缓存,可将js css 设置成一年或者更久。

a、合并后Js文件名+MD5,在seaConfig.js配置别名(配置由grunt自动生成)
b、基础组件,通过1.1.0类似的来实现版本控制
c、至于seaConfig.js不设置缓存,或者直接写人html中

2)构建时可以合并Js,发起请求时也可以combo合并文件;对于页面必须的,非模块化Js,可采用combo请求,服务器端可以配置combo插件。

3)如何简单切换开发模式和线上模式
在Jsp中配置模式,Jsp->html后

三、实际打包
1)其实到现在,最关键的是?打包工具怎么知道哪些require要合并,哪些不用?想到有两种方法,
一种是通过配置文件来管理,一种是通过制定开发规范。我们有这种需求,难道其它使用Seajs的人没有?
果不其然,grunt-cmd-concat出现了,专门解决这个问题。它是通过规范,插件里面对不同规范作不同的处理。
require(‘‘)相对路径,会将依赖合并,require(‘dialog/1.2.0/dialog‘),类似这种的不会合并。

2)SPM2默认会将依赖的css文件合并到js,最终插到页面style标签中。这时css里面涉及url的路径要注意,之前用的相对路径会有问题,要用绝对路径。阿里涉及图片的直接用一个静态服务器用绝对路径,当然没这方面顾虑。
可是项目主管说,每个组件必须有自己的imgs目录。那只能使css不合并到js中,要做如下工作:
a、页面模块和业务组件的css要合并成一个,
b、图片都放到一个文件夹下
合并前
-------------------------------
--app/
--------shareDetail/
---------------------- shareDetail.js
---------------------- share.css
----------------------imgs/
--------------------------------------unJoin.png
--components/
--------wifi/
---------------------- wifi.js
---------------------- wifi.css
----------------------imgs/
--------------------------------------wifi_connect.png
shareDetail.js里面引入require(‘./share.css‘),
wifi.js里面引入require(‘./wifi.css‘),

合并后
-------------------------------
--app/
--------shareDetail/
---------------------- shareDetail.js
---------------------- share.css
---------------------- imgs/
--------------------------------------unJoin.png
--------------------------------------wifi_connect.png
shareDetail.js里面引入require(‘./share.css‘),
wifi.js里面引入require(‘./share.css‘)

Css、imgs合并,要分析出require相对路径的业务组件名,比如wifi,然后将wifi/imgs合并到相应的shareDetail/imgs;
这里我写了个grunt-cmd-concatFiles和grunt-cmd-concatCss

3)流程
规范化(transport)Js,合并(cmd-concat)Js依赖,压缩(uglify)Js,重命名(md5)Js,生成配置文件
依据依赖关系合并(concatCss)Css,压缩(cssmin)Css
依据依赖关系合并(concatFiles)图像文件夹,压缩(imagemin)图像

4)关键配置
a)
        ......
        transport : {
            options : {
                ......
                paths:[‘src‘]
            },
        ........

paths:[‘src‘] 运行transport时,要保证require的文件能找到,相对路径、绝对路径很明了
类似require(‘modules/dialog/0.0.1/dialog‘),实际路径是paths + ,这里的paths值跟seaConfig.js里的base相同。

b)
        ......
        transport : { 
            options : {
                ......
                paths:[‘src‘] 
            },
            app : { 
                options : {
                    idleading : ‘apps/‘
                },
                ........

idleading : ‘apps/‘ 打包后的文件放在新位置后,define的路径要变化,插件的idleading参数可配置define的路径。如果你transport后文件没有执行,很可能idleading设置有误。

c)
开发环境与生产环境。开发环境下跑的所有Js和css甚至图片都是未处理的;生产环境下都是合并压缩后的Js、css。
seajs里面的require可能有三种类型,绝对路径、相对路径、name。
在打包情况下的结果:
绝对路径在打包前后的都不会变化,目前没这种场景,所以没有使用绝对路径场景。
相对路径,最终路径 = 外层Js的路径 + 相对路径,最外层Js就是seajs.use(‘../../static/shareDetail/shareDetail.js‘)
类似require(‘modules/dialog/0.0.1/dialog‘)路径,最终路径 = seajs.data.base + name; name路径在打包前后不能变化,打包前后如有变动,就要变seajs.data.base

四、具体命令
安装nodeJs环境

安装grunt构建工具
npm install grunt
npm install -g grunt-cli

安装SPM及其打包插件build
npm install spm -g
spm plugin install build
npm install spm-build -g

期间按照它的Demo,发现有许多问题

构建要做的事

如果突然发现要用什么grunt插件,
npm install grunt --save-dev

五、调试
使用时,有疑问,网上文档缺乏,周围没人知道这块,download的demo可能因插件老旧而不能正常使用。
这时,一方面输入打包命令时 加--verbose,打印出详细的过程,
另一方面迫切希望能调试下源码。
一开始,我也是人肉log(grunt.log.writeln)调试。后来发现了也可以使用node调试。

启动调试过程
先安装插件
npm install -g node-inspector

打开命令行,启动调试端口
node-inspector

打开另一个命令行窗口
node --debug-brk $(which grunt) task
node --debug-brk C:\Users\fangyingchun\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt concat:app
node --debug-brk C:\Users\fangyingchun\AppData\Roaming\npm\node_modules\spm-build\bin\spm-build

最后打开chrome,输入网址 
http://127.0.0.1:8080/debug?port=5858,进行调试

六、相关网址
https://github.com/seajs/seajs
http://nodejs.org/api/
http://gruntjs.com/
http://docs.spmjs.org/doc/
https://github.com/spmjs

freemark
spm depoy
前端服务部署与文件发布
ast

在js里面不能出现a-- 而要用a=a-1来代替(原因,这个打包工具将它看成注释)。至于自增和自减的逻辑,自己去学习吧
How can I run a grunt task from within a grunt task?
http://stackoverflow.com/questions/15284556/how-can-i-run-a-grunt-task-from-within-a-grunt-task

开发规则
页面组件中的css不能调用其它组件的图片
引入依赖的基础组件使用别名
模块化开发,引入依赖模块时,不要使用绝对路径
在src目录中的Js都要是未压缩的,压缩交给构建工具统一处理

前端构建

时间: 2024-10-28 20:37:01

前端构建的相关文章

webpack前端构建工具学习总结(四)之自动化生成项目中的html页面

接续上文:webpack前端构建工具学习总结(三)之webpack.config.js配置文件 1.安装html-webpack-plugin插件,输入命令:npm install html-webpack-plugin --save-dev 2.在webpack.config.js文件中,引入html-webpack-plugin插件 3.输入命令:npm run webpack,编译打包 可以看到在dist/js目录下新生成了一个index.html文件,并且引入了新编译生成的两个js,但此

前端构建工具gulpjs的使用介绍及技巧

gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速度更快.如果你还没有使用过前端构建工具,或者觉得gruntjs太难用的话,那就尝试一下gulp吧. 本文导航: gulp的安装 开始使用gulp gulp的API介绍 一些常用的gulp插件 1.gulp的安装 首先确保你已经正确安装了nodejs环境.然后以全局方式安装gulp: npm inst

记学习前端构建工具gulp的过程,略心酸

初学前端的时候就听过友人说,前端不好学,很多软件都是要自己下载安装插件的,当时是很不以为然的,不就是下载几个软件外加安装插件吗?!怎么会很难呢!后面才发现自己真的错了. 今天刚好准备好好看看前端构建工具gulp的使用,于是乎就各种上网查资料.刚开始的时候有点摸不着头脑,这个东西不是一个软件,拿来就用,需要自己配置环境,自己根据需求安装package,完全是自己DIY的一个工具. 下面就把整个安装过程,记录下来,方便以后查看吧. 先明确几个概念:1.gulp是基于node.js环境下工作的:2.命

前端构建工具gulpjs的使用介绍及技巧(转载)

本文转载自无双 ,原文地址 http://www.cnblogs.com/2050/p/4198792.html. 感谢原博主的辛苦总结. gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速度更快.如果你还没有使用过前端构建工具,或者觉得gruntjs太难用的话,那就尝试一下gulp吧. 本文导航: gulp的安装 开始使用gulp gulp的AP

前端构建工具gulpjs

gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速度更快. 1.安装 首先确保你已经正确安装了nodejs环境.然后以全局方式安装gulp: npm install -g gulp 全局安装gulp后,还需要在每个要使用gulp的项目中都单独安装一次.把目录切换到你的项目文件夹中,然后在命令行中执行: npm install gulp 如果想在安装

前端构建:Source Maps详解

一.前言 当使用CoffeeScript.ClojureScript编写前端脚本时,当使用Less.Sacc编写样式规则时,是否觉得调试时无法准确找到源码位置呢?当使用jquery.min.js等经压缩后的工具库时,是否觉得连调试的门都不不知道在哪呢? 针对上述问题,google为我们提供了Source Maps这一解决方案,以下内容为对Source Maps的学习记录,以便日后查阅. 由于篇幅较长,特设目录一坨! 二.示例 三.Source Maps方案详解 1. 方案结构 2. 支持的浏览器

前端构建工具之gulp的安装和配置

在选择构建工具时,看到更多人推荐gulp,从此入了gulp的坑- 一.安装node环境 百度谷歌一下就有了,在终端中分别输入 node -v 和 npm -v,若显示node和npm的版本号则说明node环境装好了. 二.安装gulp linux下安装全局环境: sudo npm install -g gulp 或cd进入项目目录下安装gulp到项目本地: npm install gulp --save-dev --save-dev的意思是将安装的gulp版本信息写入package.json,更

前端构建工具gulp.js的使用介绍及技巧

一.gulp的安装 1.首先确保已经安装了node.js的环境,然后以全局的方式安装gulp 全局安装gulp--->>>npm install -g gulp 2.全局安装后,切换到gulp项目中在单独安装一次,将目录切换到gulp项目中去 局域安装gulp--->>>npm install gulp 3.安装依赖,即在安装的时候把gulp写进项目package.json文件的依赖中 npm install --save-dev gulp 二.开始使用gulp 1.和

Gulp.js----比Grunt更易用的前端构建工具

Grunt一直是前端构建工具,然而他也不是毫无缺陷的,gulp的作者 Eric Schoffstall 在他介绍 gulp.js 的 presentation 中总结了 Grunt 的几点不足之处: 插件很难遵守单一职责.因为 Grunt 的 API 设计缺憾,使得许多插件不得不负责一些和其主要任务无关的事情.比如说要对处理后的文件进行更名操作,你可能使用的是 uglify 插件,也有可能使用的是 concat 插件(取决于工作流的最后一个环节是谁). 用插件做一些本来不需要插件来做的事情.因为

前端构建和模块化工具-coolie

[前言] 如果你之前用过前端模块化工具:seajs,requirejs, 用过前端构建工具grunt.gulp, 并且感到了一些不方便和痛苦,那么你可以试试coolie [coolie] 本文不是一篇介绍coolie的文章,而是偏向新手上手coolie的常见问题解答, coolie相关: 社区文章:http://frontenddev.org/column/introduce-coolie/ git-book:http://coolie.ydr.me/index.html [知识储备] 如果你没