一开始我们这样写 js
- <script type="text/javascript">
- function a(){
- console.log('a init');
- }
- function b(){
- console.log('b init');
- a();
- }
- </script>
随着功能越来越多,我们开始把 js 分离,使用单独的 js 文件来写,然后使用下面的方式引入 js
- <script src="a.js" type="text/javascript" charset="utf-8"></script>
- <script src="b.js" type="text/javascript" charset="utf-8"></script>
这种方式有几个缺陷:
1,不能体现他们之间的依赖关系
2,文件越多请求越多,请求多会拖慢网页打开速度
3,代码写起来不爽
有没有一种方式既可以愉快的写又可以很好的组织代码呢,那就是模块化编程。
目前有两种 js 编码规范来解决上述问题:AMD(异步模块定义)和 CMD(通用模块定义),
根据这两种规范实现的 js 加载器分别有:
AMD:require.js
CMD:Sea.js
笔者使用的是 require.js。
下面展示一下如何用 require.js 来进行模块化开发,
先看一下目录结构
使用 require.js 怎么来加载呢,首先在网页中引入 require.js 然后在 script 标签中增加一个 自定义属性 data-main="main.js" 页面加载完毕后 require.js 会根据这个属性去找 main.js 然后开始执行,main.js 是入口文件
- <script src="require.js" defer async data-main="main.js" type="text/javascript" charset="utf-8"></script>
下面是入口文件 main.js
- requirejs.config({
- baseUrl: 'js/' //模块文件所在位置
- });
- require(['b'],function(b){
- b.init();
- });
require.js 里有两个方法很重要一个是 require 一个是 define 前者用来引入模块,后者用来定义模块
在 main.js 中用 requirejs.config 配置好模块们所在位置之后就可以使用 require 方法来使用他们了
a.js 和 b.js 是两个模块 由于 require.js 会自动补全所以我们引用的时候不必书写完整的文件名称 a.js,只需要写文件名 a 就行了
a.js
- define(function() {
- return {
- init: function() {
- console.log("a init")
- }
- }
- });
b.js
- define(['a'],
- function(a) {
- return {
- init: function() {
- console.log("b init") a.init();
- }
- }
- });
b 依赖 a 所以在定义 b 的时候 需要在 define 的第一个参数中引入 a ,define 第一个参数是数组类型,如果引入多个模块那么就像这样:define(['a','a1','a2'],function(a,a1,a2){})
执行后
是不是很简单,简简单单几行代码就拥抱了模块化编程是不是很激动
现在激动还为时过早,模块化编程我们是用上了但是还没有解决第二个问题,就是请求数,现在还是一个模块一个 js 文件
现在要做的就是把他们合并,合并成一个 js 文件,
是时候请出第二个主角了, 没错就是 Gulp 。整天在网上看自动化构建 啥是自动化啥是构建呀
用在我们这个例子里就是 自动合并,比如我添加或者修改了模块 Gulp 会自动把新代码合并,是不是很酷 。在 gulp 里这些操作称为任务,通过 gulp 的 watch 方法来监控文件,达到文件一变动,任务就执行的目的,这就是自动化构建。
Gulp 提供了丰富的插件,Gulp 依赖 Node.js 环境所以需要先安装 node.js,以下说的是 windows 上的操作步骤
首先下载 node.js 下载地址:http://nodejs.cn/download/
安装好后进入根目录 按住 shift 点击鼠标右键 打开命令行
使用 node.js 自带的 npm 包管理工具安装 gulp
这里提一下,如果直接装会比较慢,推荐使用淘宝的 npm 镜像:http://npm.taobao.org/
- npm install -g cnpm --registry=https://registry.npm.taobao.org
- //装完之后就可以用cnpm 替代npm 速度飞快
- cnpm i gulp -g
安装 npm 包可以选择是安装到项目里还是安装到全局 ,下面我们安装最重要的一个 npm 模块 gulp-requirejs-optimize 这个模块基于 requre.js 提供的打包工具 https://github.com/requirejs/r.js
- cnpm i gulp-requirejs-optimize -D
- //我们用了简写的命令 上面的命令等同于 cnpm install gulp-requirejs-optimize --save-dev 后面的--save-dev意思是
- 把我们装的这个模块加入到Npm的包配置清单里 这个清单是个配置文件叫做 package.json
如果一个一个装显得有些繁琐, 有没有一键安装,答案是有的。
上面我们提到了 package.json, 没错我们可以利用这个文件实现一个命令安装所有依赖模块
- {
- "name": "",
- "description": "",
- "version": "1.0.0",
- "author": "maxiao",
- "private": true,
- "scripts": {},
- "dependencies": {},
- "devDependencies": {
- "gulp": "^3.9.1",
- "gulp-bom": "^1.0.0",
- "gulp-rename": "^1.2.2",
- "gulp-requirejs": "^1.0.0-rc2",
- "gulp-requirejs-optimize": "^1.2.0",
- "gulp-rev": "^8.0.0",
- "gulp-rev-collector": "^1.2.2",
- "gulp-sequence": "^0.4.6",
- }
- }
我们把这个文件放到根目录下然后在命令行里执行 cnpm install npm 会自动把里面列的所有模块都装上
这里提到的模块是 node.js 里的模块而非我们前端定义的那些模块 ,唯一的区别是一个在 node.js 里执行一个在浏览器端执行 ,如果对 js 的服务端编程感兴趣的话可以去了解一下 node 这里就不多聊了。
当所有 gulp 依赖的模块都安装好之后就可以编写我们的 gulp 任务脚本了 ,没错这个脚本是个 js 文件叫做 gulpfile.js
下面是 gulpfile.js 里的内容,是不是很熟悉
- var gulp = require('gulp'); // 引入组件
- var minifyCSS = require('gulp-minify-css'),
- //css压缩
- uglify = require('gulp-uglify'),
- //js压缩
- requirejsOptimize = require('gulp-requirejs-optimize');
- concat = require('gulp-concat'),
- //文件合并
- rename = require('gulp-rename'),
- //文件更名
- rev = require('gulp-rev'),
- //给文件名添加版本号
- del = require('del'),
- //删除就版本
- bom = require('gulp-bom'),
- //添加bom防止中文乱码
- obfuscate = require('gulp-obfuscate'),
- revCollector = require('gulp-rev-collector'),
- //路径替换
- gulpSequence = require('gulp-sequence'),
- //按顺序执行任务
- ; //提示信息
- var newVersion = function() {
- var uuid = require('node-uuid');
- return uuid.v1().slice(0, 8)
- }
- /***************************************************************************************************************JS*/
- //清理
- gulp.task('clearjs',
- function(cb) {
- return del('dest/livecontent/livecommon/app/*.js', cb);
- });
- gulp.task("requirejs_pipe",
- function() {
- return gulp.src('main.js').pipe(requirejsOptimize(function(file) {
- return {
- name: 'main',
- optimize: 'uglify2',
- //useStrict: true,
- baseUrl: '/',
- };
- })).pipe(rev()).pipe(gulp.dest('dest/')).pipe(rev.manifest({
- merge: true
- })).pipe(gulp.dest(''));
- });
- //更改版本号
- gulp.task('renamejs',
- function() {
- return gulp.src('main.js').pipe(rev()).pipe(gulp.dest('dest/')).pipe(rev.manifest({
- merge: true
- })).pipe(gulp.dest(''));
- });
- //更改引用
- gulp.task('usenewjs',
- function() {
- return gulp.src(['rev-manifest.json', 'index.html']) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
- .pipe(revCollector({
- replaceReved: true
- })).pipe(bom())
- //- 执行文件内css名的替换
- .pipe(gulp.dest('dest/js/'));
- });
- // 默认任务
- gulp.task('default',
- function() {
- gulpSequence('clearjs', 'requirejs_pipe', 'usenewjs')(function(err) {
- if (err) console.log(err)
- })
- // Watch .js files
- gulp.watch(['js/*.js'],
- function() {
- gulpSequence('clearjs', 'requirejs_pipe', 'usenewjs')(function(err) {
- if (err) console.log(err)
- })
- });
- });
写好后在命令行里输入:gulp 然后回车
gulp 就会一直监控 js 目录下的文件变化了,一有改动就会生成新的文件写入到 dest 目录下
里面用到了几个我没提到的模块比如 给合并后的文件加版本号的,控制任务顺序执行的,删除文件,防止文件乱码的,这都是笔者爬坑过程中为了解决问题一个一个找的啊 真良心推荐 每个都会用到
由于篇幅关系我就不一一讲解了,本来只想讲一讲网页加载 js,一下讲了这么多,关于 node.js 和 gulp 可以单独开两个篇幅来介绍了,没办法现在前端就是这么百花齐放。不过终究还是 js 太招人喜欢哈哈。
上面啰嗦这一大段目的就是把 require.js 以及模块合并成一个 js 文件减少 http 请求和文件大小提升网页加载速度。
我们项目中的代码只有 index.html requre.js,main.js,a.js,b.js 。 node.js,npm ,gulp 只是我们的用到的工具。
至此加载篇基本讲完,有一个地方没讲就是 AMD 的 A 这个 A 是异步的意思
下一篇 【玩转 JS 系列之异步篇】将一起讲解
来源: http://www.cnblogs.com/maxiao/p/7404205.html