1. 程式人生 > >React入門教程第三課--gulp編譯優化

React入門教程第三課--gulp編譯優化

上節課中我提到了,在gulpfile中編寫task編譯js和sass的task。

然後在專案中使用時發現,當專案內容越寫越多時,編譯速度會越來越久。

看了一下編譯過程。上次gulpfile中的定義是當監聽檔案改變時就執行編譯全部js檔案。

查閱資料--gulp編譯加速

看了下教程沒怎麼明白,按照連結點選去看了他的原始碼,一個文件裡面寫了看起來很像加速的東西,但是我並不知道怎麼加到自己的專案中。

然後該教程中提到了watchify,於是就查了gulpwatchify,第一條資訊是gulp中文網的

使用 watchify 加速 browserify 編譯

連結地址:http://www.gulpjs.com.cn/docs/recipes/fast-browserify-builds-with-watchify/ 原文內容:

當一個 

browserify 專案開始變大的時候,編譯打包的時間也會慢慢變得長起來。雖然開始的時候可能只需花 1 秒,然後當你的專案需要建立在一些流行的大型專案的基礎上時,它很有可能就變成 30 秒了。

這就是為什麼 substack 寫了 watchify 的原因,一個持續監視檔案的改動,並且 只重新打包必要的檔案 的 browserify 打包工具。用這種方法,第一次打包的時候可能會還是會花 30 秒,但是後續的編譯打包工作將一直保持在 100 毫秒以下 —— 這是一個極大的提升。

watchify 並沒有一個相應的 gulp 外掛,並且也不需要有:你可以使用 vinyl-source-stream

 來把你的用於打包的 stream 連線到 gulp 管道中。

頁面提供的原始碼寫的很好,我在裡面增加了註釋說明。

'use strict';

var watchify = require('watchify');
var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var gutil = require('gulp-util');
var sourcemaps = require('gulp-sourcemaps');
var assign = require('lodash.assign');  //這個模組是用來連線物件的比如var a = {a_p:1}  var b = {b_p:2} var c = assign{{},a,b}  則物件c實際上是{a_p:1,b_p:2}
//專案中使用object-assign代替,用習慣了而已,沒有為什麼要換
// 在這裡新增自定義 browserify 選項
var customOpts = {
  entries: ['./src/index.js'],//<span style="font-family: Arial, Helvetica, sans-serif;">browserify </span><span style="font-family: Arial, Helvetica, sans-serif;">主入口</span>
  debug: true
};
var opts = assign({}, watchify.args, customOpts);//把watchify的屬性和browserify的屬性連線起來 assign的用法看上面註釋
var b = watchify(browserify(opts));定義一個使用watchify監聽的browserify事件(<span style="font-family: Arial, Helvetica, sans-serif;">或者說物件</span><span style="font-family: Arial, Helvetica, sans-serif;">)。</span>

// 在這裡加入變換操作
// 比如: b.transform(coffeeify);

gulp.task('js', bundle); // 這樣你就可以執行 `gulp js` 來編譯檔案了
b.on('update', bundle); // 當任何依賴發生改變的時候,執行打包工具
b.on('log', gutil.log); // 輸出編譯日誌到終端

function bundle() {
  return b.bundle()
    // 如果有錯誤發生,記錄這些錯誤
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('bundle.js'))
    // 可選項,如果你不需要快取檔案內容,就刪除
    .pipe(buffer())
    // 可選項,如果你不需要 sourcemaps,就刪除
    .pipe(sourcemaps.init({loadMaps: true})) // 從 browserify 檔案載入 map
       // 在這裡將變換操作加入管道
    .pipe(sourcemaps.write('./')) // 寫入 .map 檔案
    .pipe(gulp.dest('./dist'));
}

以上程式碼均來自gulp中文網。 現在我來談談怎麼在專案中使用它。 新增三個模組
var watchify = require('watchify');
var gutil = require('gulp-util');
var assign = require('object-assign');
我們修改幾個跟我們專案先關的內容。 1、修改task名字
gulp.task('watchSource', bundle);
2、修改browserify配置
// 在這裡新增自定義 browserify 選項
var customOpts = {
    entries: ['./source/app.js'],
    debug: true
};
3、加入變換操作,react專案中需要加入presets,現在的專案加了會報錯。本次demo中沒加,後續用到的時候,再新增進去。
b.transform(babelify,{presets:["react"]});
4、修改build函式
function bundle() {
    return b.bundle()
// 如果有錯誤發生,記錄這些錯誤,按照教程寫的bind並不能用
.on('error', gutil.log)
        // 刪掉了沒有用到的buffer和sourcemaps等內容
        // 增加壓縮程式碼uglify,在下方的pipe,當需要壓縮程式碼是取消下方的註釋
        .pipe(source('oni.js'))
//需要壓縮就開啟
        //.pipe(streamify(uglify()))
.pipe(gulp.dest('./build'));
}
執行 $ cd OniReact $ gulp 可以看到當前編譯需要1.6秒左右,修改之後再編譯需要0.26秒。當專案比較大時這個優化效果是很明顯的。
修改後的gulpfile如下:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var sass = require('gulp-sass');
var plumber = require('gulp-plumber');//事件
var notify = require('gulp-notify');//錯誤
var uglify = require('gulp-uglify');//壓縮
var streamify = require('gulp-streamify');
var webserver = require('gulp-webserver');//服務
var watchify = require('watchify');
var gutil = require('gulp-util');
var assign = require('object-assign');
// 在這裡新增自定義 browserify 選項
var customOpts = {
    entries: ['./source/app.js'],
    debug: true
};
var opts = assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts));
// 在這裡加入變換操作
// 比如: b.transform(coffeeify);
b.transform(babelify);
gulp.task('watchSource', bundle); // 這樣你就可以執行 `gulp watchSource` 來編譯檔案了
b.on('update', bundle); // 當任何依賴發生改變的時候,執行打包工具
b.on('log', gutil.log); // 輸出編譯日誌到終端
function bundle() {
    return b.bundle()
        // 如果有錯誤發生,記錄這些錯誤,按照教程寫的bind並不能用
        .on('error', gutil.log)
        // 刪掉了沒有用到的buffer和sourcemaps等內容
        // 增加壓縮程式碼uglify,在下方的pipe,當需要壓縮程式碼是取消下方的註釋
        .pipe(source('oni.js'))
        //需要壓縮就開啟
        //.pipe(streamify(uglify()))
        .pipe(gulp.dest('./build'));
}
gulp.task('buildCSS', function () {
    gulp.src('./style/app.scss')
        .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
        .pipe(sass())
        .pipe(gulp.dest('./build'))
});
gulp.task('watchStyle', function () {
    gulp.watch('./style/**/*',['buildCSS'])
})
gulp.task('webserver', function () {
    gulp.src('build').pipe(webserver({
        port:8897,
        fallback: 'index.html',
        open:true
        //host:'172.16.9.68' 可設定成本機ip供聯網除錯
    }))
});
gulp.task('default',['watchSource','watchStyle','webserver']);



現在這樣的gulp配置還蠻好用的,編譯快速,監聽錯誤,起一個web伺服器。 但是還存在一個問題,當代碼出現語法錯誤時,列印的日誌內容有點詳細,包含程式碼的位置及其他的一些詳細內容。 我只截取了一部分,紅色框內的內容是我想保留下來的。查了些資料,沒有找到方案,希望知道怎麼弄得朋友可以指導一下。
到此本節課的內容全部講解完畢,關於以上內容有不瞭解的地方,可以通過評論的方式,留言,我會給出參考文獻連結。

專案地址:https://Git.oschina.NET/xiaohuOni/OniReact-Demo

SVN地址:svn://Git.oschina.NET/xiaohuOni/OniReact-Demo

之前的demo都用百度雲盤,後來全部過期了。

題外話:
無,今天不想說話。。。
請大家關注公眾號:ionic__