星期三, 10月 01, 2014

[Gulp] html 裡 include 的是 css 檔案,為什麼我們修改 scss 檔案,能夠即時修改輸出結果?而且在 watch 模式下還是把輸出檔案暫存在 .tmp 目錄下??

主要是跟 styles, watch, connect 這幾個 task 有關:

在 styles task 裡,我們先設定要針對哪些 scss 檔案作轉換處理;然後輸出到 .tmp/styles 目錄下
// scss files
var scss_files = [
  // 'app/styles/main.scss',
  'app/styles/**/*.scss',
  // smartadmin common_assets
  'COMMON_ASSETS/SASS_FILES/scss/bootstrap.scss',
  'COMMON_ASSETS/SASS_FILES/scss/smartadmin-production.scss',
  'COMMON_ASSETS/SASS_FILES/scss/library/fontawesome/font-awesome.scss',
  'COMMON_ASSETS/SASS_FILES/scss/smartadmin-skins.scss',
  'COMMON_ASSETS/SASS_FILES/scss/smartadmin-skins.scss'
];
gulp.task('styles', function () {
  return gulp.src(scss_files)
    .pipe($.rubySass({
        style: 'expanded',
        precision: 10
    }))
    .pipe($.autoprefixer('last 1 version'))
    .pipe(gulp.dest('.tmp/styles'))
    .pipe($.size());
});

在 watch task 自動載入下,指定要監看哪些檔案,並做出哪些相對應動作(這裡是利用 dependency 聯動 task 的方式)
gulp.task('watch', ['connect', 'serve'], function () {
    var server = $.livereload();
    // watch for changes
    gulp.watch([
        'app/*.html',
        '.tmp/styles/**/*.css',
        'app/scripts/**/*.js',
        'app/images/**/*'
    ]).on('change', function (file) {
        server.changed(file.path);
    });
    gulp.watch('app/styles/**/*.scss', ['styles']);
    gulp.watch('app/scripts/**/*.js', ['scripts']);
    gulp.watch('app/images/**/*', ['images']);
    gulp.watch('bower.json', ['wiredep']);
});

那放在 .tmp/styles 的檔案,如何能讓 html 連結到?html 裡頭寫的是 <link rel="stylesheet" type="text/css" media="screen" href="styles/main.css">?

這是因為 watch 的 dependency 裡有 connect task。在啟動 server 時,利用 connect.static 來指定「靜態文件服務器的路徑」,也就是 html 裡用到的所有相對路徑的根目錄。這裡預設了兩個靜態文件目錄,一個是 app,另外一個是 .tmp。所以如果我們需要找到 styles/main.css,系統會先去找 app/styles/main.css 是否存在,如果沒有,才會去找 .tmp/styles/main.css。
gulp.task('connect', function () {
    var connect = require('connect');
    var app = connect()
        .use(require('connect-livereload')({ port: 35729 }))
        .use(connect.static('app'))
        .use(connect.static('.tmp'))
        .use(connect.directory('app'));
    require('http').createServer(app)
        .listen(9000)
        .on('listening', function () {
            console.log('Started connect web server on http://localhost:9000');
        });
});