玩轉JS系列之代碼加載篇


一開始我們這樣寫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目錄下

里面用到了幾個我沒提到的模塊比如 給合並后的文件加版本號的,控制任務順序執行的,刪除文件,防止文件亂碼的,這都是筆者爬坑過程中為了解決問題一個一個找的啊 真良心推薦 每個都會用到

我們項目中的代碼只有index.html requre.js,main.js,a.js,b.js  。 node.js,npm ,gulp只是我們的用到的工具。

es6的到來前端工具百花齊放,學好js再使用他們就會感覺很順手事半功倍

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM