使用gulp實時編譯sass/sass
阿新 • • 發佈:2019-02-12
背景
在我們新開始的專案中,我們打算使用scss來作為我們的樣式書寫語言。同時,所有的sass/scss檔案經過編譯轉化成css檔案後要存放到跟scss/sass檔案相同的目錄下。整個前端團隊已經有實時的程式碼編譯構建工具,那麼我們只需要書寫自己的實時scss/sass構建工具,生成對應的css檔案後,團隊的實時構建工具也會觸發編譯,做打包構建處理。
第三方包選型
基於gulp的sass/scss編譯工具有:基於node-sass的gulp-sass以及基於Ruby的gulp-ruby-sass。但是為了免得再安裝Ruby以及一些特定的原因(gulp-ruby-sass與gulp-sass),我選擇了使用gulp-sass。執行方式及執行效果
程式碼
最終的程式碼在下面。需要注意的是,你要在第19行自己指定需要編譯的scss/sass檔案所在的目錄以及這些目錄下不需要編譯的子目錄,該目錄下全部需要編譯就不指定陣列第二項。var watchFilesPath = ‘*.{sass,sass}';
完整的程式碼:
這樣你就可以愉快的書寫scc/sass程式碼了。var path = require('path'); var logSymbols = require('log-symbols'); var gulp = require('gulp'); var sass = require('gulp-sass'); var autoprefixer = require('gulp-autoprefixer'); var notify = require('gulp-notify'); var stripCssComments = require('gulp-strip-css-comments'); var plumber = require('gulp-plumber'); var gutil = require('gulp-util'); var cssbeautify = require('cssbeautify'); var mapStream = require('map-stream'); var colors = require('colors'); var minimatch = require('minimatch'); var execSync = require('child_process').execSync; var projectPath = execSync('git rev-parse --show-toplevel').toString().trim().replace(/\\n/g); // 指定要編譯的目錄 var watchFilesPath = ['**/{pc,mobile}/**/*.{scss,sass}', '!**/mobile/hotcss/**']; // 編譯成功通知開關 var successNotify = true; // 將.scss/.sass檔案實時轉變為.css檔案 gulp.task('styles', function() { return gulp.src(watchFilesPath) .pipe(plumber({ errorHandler: reportError })) .pipe(mapStream(function(file, cb) { logPath(file); cb(null, file); })) .pipe(sass()) // 去掉css註釋 .pipe(stripCssComments()) // auto prefix .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) // css格式化、美化(因為有f2ehint,故在此不再做語法等的檢查與修復) .pipe(mapStream(function(file, cb) { // 新增css程式碼的格式化 var cssContent = file.contents.toString(); if (/\.(css|sass|scss)/.test(path.extname(file.path))) { file.contents = new Buffer(cssbeautify(cssContent, { indent: ' ', openbrace: 'end-of-line', autosemicolon: true })); } cb(null, file); })) // 將編譯後的.css檔案存放在.scss檔案所在目錄下 .pipe(gulp.dest(function(file) { return './'; })) // 編譯成功後的提示(頻繁提示會有點煩人,可將successNotify設定為:false關閉掉) .pipe(notify(function(file) { return successNotify && 'scss/sass編譯成功!'; })); }); gulp.task('watch', function() { // Watch .scss files gulp.watch(watchFilesPath, ['styles']); }); // 監聽任務時先執行一次編譯 gulp.task('default', function() { gulp.start('styles', 'watch'); }); /** ########### helpers ########### */ function logPath(file) { console.log(logSymbols.info + ' 正在編譯:' + file.path.gray); } function reportError(error) { var lineNumber = (error.lineNumber) ? 'LINE ' + error.lineNumber + ' -- ' : ''; notify({ title: '編譯失敗 [' + error.plugin + ']', message: lineNumber + '具體錯誤請看控制檯!', sound: 'Sosumi' // See: https://github.com/mikaelbr/node-notifier#all-notification-options-with-their-defaults }).write(error); gutil.beep(); // Pretty error reporting var report = ''; var chalk = gutil.colors.white.bgRed; report += chalk('TASK:') + ' [' + error.plugin + ']\n'; report += chalk('PROB:') + ' ' + error.message + '\n'; if (error.lineNumber) { report += chalk('LINE:') + ' ' + error.lineNumber + '\n'; } if (error.fileName) { report += chalk('FILE:') + ' ' + error.fileName + '\n'; } console.error(report); // Prevent the 'watch' task from stopping this.emit('end'); }