前端工程化思考与实践
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端工程化思考与实践相关的知识,希望对你有一定的参考价值。
4. 前端工程化开发实践
由于Nodejs 、npm的环境搭建往上很多,这里就不过多介绍它们了。
这里我们将更多介绍FIS3、RequireJS 、r.js。
4.1 模块化开发:
4.1.1 开发目录结构
左图为开发目录结构,
右图中新增js 目录、fis-conf.js文件,js 目录用来存放require.js的页面级入口文件
4.1.2 html文件的模块化处理
任何页面都可以拆分为若干组件,在开发环境下,可以迅速定位组件位置,修改组件
FIS3为我们提供了方便的资源嵌入功能http://fis.baidu.com/fis3/docs/user-dev/inline.html
简单来说,我们可以如同模板开发一样去写HTML页面,例如:
这个首页页面本身的样式和代码极少,页面内容都是由” ?__inline”功能从其他页面引入了,
如:banner.html
当文件编译时,FIS3会自动帮我们把这些地方替换为文件中的HTML代码:
编译后的index.html:
可以看到,FIS3帮我们将banner.html中的代码完成写入了index.html。
这里我们完成了简单的页面代码模块化分离,但是这远远还不够,因为我们的页面还需要包括CSS文件,JS文件,以及一系列的图片文件等等。那么这些东西该这么完成模块化分离,然后再打包呢。对于CSS我们就需要用到LESS的,js则需要Requirejs的帮助。
4.1.3 JS文件的模块化处理了
这里我们需要使用到Requirejs,前面提到过,它是AMD模式的一个实现。由于js语言的历史原因,它在很长一段时间都算不上一个严谨的言语,不过经过多年来的不断努力,人们提出了许多增强它,规范它的方案,这些规范的目的都是为了 javascript 的模块化开发,特别是在浏览器端的。目前这些规范的实现都能达成浏览器端模块化开发的目的。
Requirejs 首先需要一个requirejs.config的配置,该配置的目的在于确定文件间的依赖关系,设定各个文件的别名,设定文件的加载顺序等等。
上面是一个简单的配置,baseUrl定义了一个相对文件所在目录的相对路径,paths设置了相关文件的别名,shim规定文件间的依赖关系,比如baseUI模块依赖jquery模块,因此,baseUI需要在jquery加载完后加载。http://www.requirejs.cn/ 详细配置选项查看这里。
对于requirejs.config 定义的位置,我尝试过三种方式:
u 每个入口文件中都定义一次
u 统一到config.js中去定义,在加载时优先require这个文件,然后在回调函数里面在写页面的依赖
这样做到时解决了冗余的问题,但是require的嵌套显然不太符合作者的初衷.
u 统一到config.js中去定义,然后加require.js和config.js打包到一起,在引用入口文件前就同步调用了。
这样做相当于全局定义了require.config并且在页面中同步调用,一定是会在入口文件前,解决了之前的问题
注意require.config中shim只用做两个功能,一个是表明依赖顺序关系,一个是加载不符合AMD规范的js文件。不要用作模块加载。
接下来就是入口文件和模块文件的编写,入口文件我认为应该是每个一个,这样能保证不会加载多余的文件进来。当然,在特殊情况下,可以不同页面引用同一个,灵活应用。
对于模块文件,我推荐的书写方式如下,在对象中定义方法,并将对象作为接口暴露,提供给其他模块使用
特别提示一点,无论是入口文件,还是模块文件,只要是需要使用的依赖就要写到依赖数组中,不要想着a依赖过b,我现在只要写依赖a那边b也自动依赖了,这样是违反requirejs的初衷的。
4.1.4 css文件的模块化处理
目前来说,有两种方式来对css文件做模块化处理
u 利用LESS的@import引入模块
u 利用FIS3的“声明依赖”功能引入模块
两者区别在于@import会在LESS文件编译阶段将引用的LESS文件加入该文件中,而@require是在文件打包阶段将各个css文件合并到一起。
1.1.5 图片的处理
FIS3的fis-spriter-csssprites插件即可帮助我们生成页面级别的雪碧图
4.2 自动构建和优化
4.2.1 FIS3 介绍
u FIS3 是基于文件对象进行构建的。
u FIS3有自己的内置语法,实现了“内容嵌入”,“定位资源”,“声明依赖”三个功能。
u FIS3 编译的整个流程都是通过配置文件fis-conf.js来控制的。
u FIS3 定义了一种类似 CSS 的配置方式。固化了构建流程,以期让工程构建变得简单。
u FIS3 提供了文件指纹的功能,通过分析文件大小,在文件名中添加MD5码,来解决文件更新时的浏览器缓存问题。
以上是我对FIS3一点理解,详细的教程请移步FIS3网站查看。
FIS3教程:http://fis.baidu.com/fis3/docs/beginning/intro.html
强烈建议跟着教程走一遍,对FIS3有一点了解后再继续往下看
目前使用到的最重要的几个功能:
u FIS3编译功能,通过配置文件fis-conf.js我们可以轻松的告诉FIS3该如何去处理我们的前端文件,具体语法和使用方法请查看教程
在这个HTML文件中我们引用了一个CSS文件,一个LESS文件,同步引用了html5.js,require.js以及config.js,此外我们还通过Requirejs异步引入了一个模块名为index_main的js模块。
那么根据上面fis-conf.js中的配置,我们的文件将会构建成什么样子呢。
首先,我们的配置命中了当前目录及其子目录下的所有.less文件,并且调用了插件fis-parser-less插件将.less文件转换为.css文件后输出。
然后我们在文件打包阶段调用了fis-postpackager-loader插件,用过allInOne这个配置,将页面中同步引用的CSS文件、JS文件分别打包。这里我们同步引用的js文件有html5.js,require.js以及config.js。
但是仔细看,在我们HTML代码中有个<!--ignore-->的注释,这里就是为了告诉FIS3,打包时请忽略这个文件,因此FIS3打包会跳过html5.js,然后打包require.js、config.js。并将其输出为 libs/require_conf.js文件。(由于html5.js需要dom加载前调用,所以不打包它)
对于CSS文件,我们在html文件中引入了一个reset.css,同时我们通过前面一步编译出了一个index.css,所以这里FIS3会把这两个文件打包,然后输出到index.html_aio.css
文件中,配置中的${filepath}就代表当前文件路径
u FIS3给我们提供了一个本地的简易Nodejs服务器,使用命令行 fis3 server start就可以启动。并且该服务一直存在后台,不关机/重启 或者 主动停止服务,该服务不会关闭,另外使用命令行fis3 server open可以打开服务器所在文件夹,给我们前端开发提供了一个非常方便的服务器环境。一般来说我们可以通过127.0.0.1:3000来访问这个本地服务器。
u FIS3的有强大的监视自动刷新功能,当你的文件夹下任何文件发生变动时,FIS3会自动刷新页面并且,重新编译文件。这个功能需要fis3 release –wL来激活。
4.2.2 使用r.js
在使用FIS3的过程中,发现异步的JS文件的打包,FIS3的库目前支持还不足,所以我决定暂时使用r.js去替代。
当我在用FIS3打包整个项目之前,我会先用r.js对requirejs的依赖进行打包。如果FIS3一样,我们需要编写一个配置文件来告诉他改如何打包,配置文件命名为build.js
以上是一个简单的build.js配置,更多配置可以参考http://www.chenliqiang.cn/node/22
前面提到过require.config中最好不要通过shim依赖模块,这是因为这会造成打包后多次拉取文件,因此全部放在require的依赖数组中处理。
这里配置完后,我们通过 node r.js –o build.js 进行打包,生成的新文件夹temp-build
4.2.3 使用FIS3
使用完r.js,我们开始使用FIS3构建整个项目
在这个配置文件中,我们设定了两套构建规则,如同CSS语言中的媒体查询一样。我们这里使用media来配置第二套构建规则。
在命令行中输入fis3 release可以开始执行构建
如果我要执行第二套方案只需要写为fis3 release temp 即可
上图中的-d命令代表修改输出目录到../temptest,FIS3构建时还有其他参数可以选择,具体可以参考FIS3的文档。
完成构建后我们可以看到,我们页面的请求数减少了,并且文件都带上了MD5指纹
4.2.4 使用过程中遇到的问题
由于我们使用了文件指纹,所以每个文件的文件名中间会插入一个表示文件大小的MD5码。
比如index.js会变成index_d82af77.js,根据FIS3“定位资源”的规则,构建时FIS3会自动替换掉html中的script、link、style、video、audio、embed等标签的src或href属性中的值,但是使用Requirejs时在data-main中的异步引入的文件和在config.js中配置的路径就没有那么好运了。
解决方法:
u前面有提到全局配置require.config,事先就将data-main中文件路径用模块名替代。这样能解决data-main中路径无法替换的问题。
u这里可以使用FIS3提供的资源定位能力,在config.js中使用__uri()函数解决该问题
5. 结语
这篇文章写于去年4月,由于没有注册博客园的账号,因此现在才发布过来。一年多的时间前端工程领域的变化很大,我们团队也经历了FIS、grunt到现在webpack的变化,我也希望通过这篇基础文章 ,抛砖引玉,让大牛们更多来分享下你们的前端工程化经验。
以上是关于前端工程化思考与实践的主要内容,如果未能解决你的问题,请参考以下文章