gulp 簡介
gulp 類似一種任務管理工具,把一些任務自動化,像是:壓縮圖片、移動檔案、compile css、轉換 JavaScript、minify js or css
- webpack 也可以當成 gulp 的任務之一
先貼上最後 gulpfile.js 的內容
const { src, dest, series, parallel } = require('gulp');
const babel = require('gulp-babel');
const sass = require('gulp-sass');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const cleanCSS = require('gulp-clean-css');
sass.compiler = require('node-sass');
function compileJS() {
return src('src/*.js')
.pipe(babel())
.pipe(dest('dist'))
.pipe(uglify())
.pipe(rename({ extname: '.min.js' }))
.pipe(dest('dist'))
}
function compileCSS() {
return src('src/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(dest('css'))
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(rename({ extname: '.min.css' }))
.pipe(dest('css'))
}
exports.compileJS = compileJS
exports.compileCSS = compileCSS
exports.default = parallel(compileCSS, compileJS)
說明
const { src, dest, series, parallel } = require('gulp'); // 引入待會需要使用的 gulp 內建語法
const babel = require('gulp-babel'); // 引入 Babel
const sass = require('gulp-sass'); // 引入 sass
const uglify = require('gulp-uglify'); // 引入 JS 壓縮程式
const rename = require('gulp-rename'); // 引入重新命名程式
const cleanCSS = require('gulp-clean-css'); // 引入 CSS 壓縮程式
sass.compiler = require('node-sass'); // 引入 sass 編譯程式
function compileJS() { // 編譯 JS 檔
return src('src/*.js') // 取得 src 這個資料夾底下的所有 .js 檔
.pipe(babel()) // 將這些檔案都進行 babel 轉換
.pipe(dest('dist')) // 處理完放到 dist 這個資料夾底下
.pipe(uglify()) // 再將剛剛 babel 處理後的檔案做壓縮
.pipe(rename({ extname: '.min.js' })) // 為了區分壓縮及未壓縮的檔案,將有壓縮過的檔案都換上 .min.js 這個副檔名
.pipe(dest('dist')) // 把這些 .min.js 檔案放到 dist 這個資料夾底下
}
function compileCSS() { // 編譯 CSS 檔
return src('src/*.scss') // 取得 src 這個資料夾底下的所有 .scss 檔
.pipe(sass().on('error', sass.logError)) // 將這些檔案都進行 sass 轉換
.pipe(dest('css')) // 處理完放到 css 這個資料夾底下
.pipe(cleanCSS({compatibility: 'ie8'})) // 再將剛剛 sass 處理後的檔案做壓縮
.pipe(rename({ extname: '.min.css' })) // 為了區分壓縮及未壓縮的檔案,將有壓縮過的檔案都換上 .min.css 這個副檔名
.pipe(dest('css')) // 把這些 .min.css 檔案放到 css 這個資料夾底下
}
exports.compileJS = compileJS // 在 CLI 下 npx gulp compileJS 可單獨執行 compileJS() 程序
exports.compileCSS = compileCSS // 在 CLI 下 npx gulp compileCSS 可單獨執行 compileCSS() 程序
exports.default = series(compileCSS, compileJS) // 在 CLI 下 npx gulp 會先執行 compileJS() 程序,再執行 compileCSS() 程序
exports.default = parallel(compileCSS, compileJS) // 在 CLI 下 npx gulp 會「同時」執行 compileJS() 及 compileCSS() 程序
事前安裝
必須先按照下列流程安裝套件才可以執行上面的 gulp
- 將 node, npm, npx 先安裝完成
SCSS 的部分:
npm install -g sass
: 安裝 sass
Babel 的部分:
npm init
:產生 package.jsonnpm install --save-dev @babel/core @babel/cli
:安裝 Babel- 打開 package.json,在 "scripts": { } 底下加上
"build": "babel src -d lib"
- 在根目錄新增一個
.babelrc
檔案,裡面寫上{ "presets": ["@babel/preset-env"] }
gulp 的部分:
npm install --global gulp-cli
:安裝 gulp- 在根目錄新增一個
gulpfile.js
檔案 npm install --save-dev gulp-babel
:安裝 gulp-babelnpm install node-sass gulp-sass --save-dev
:安裝 gulp-sassnpm install --save-dev gulp-uglify
:安裝 gulp-uglifynpm install --save-dev gulp-rename
:安裝 gulp-renamenpm install gulp-clean-css --save-dev
:安裝 gulp-clean-css
好用範例
const gulp = require('gulp');
const { src, dest } = require('gulp');
const pug = require('gulp-pug');
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const uncss = require('postcss-uncss');
const autoprefixer = require('autoprefixer');
const minifyCSS = require('gulp-csso');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');
const connect = require('gulp-connect');
const imageMin = require('gulp-imagemin');
const del = require('del')
const browserify = require("browserify");
const babelify = require("babelify");
const source = require("vinyl-source-stream");
const glob = require('glob');
const es = require('event-stream');
const uglify = require('gulp-uglify');
const buffer = require('vinyl-buffer');
const svgSprite = require('gulp-svg-sprite');
const merge = require('merge-stream');
const gulpif = require('gulp-if');
const fontmin = require('gulp-fontmin-woff2');
// run minfont.js to get this string
const fontText = '\uf028\uf164\uf57d\uf1c0\uf7d9\uf233\uf201\uf3ed\uf126\uf51c\uf06e\uf0c9\uf35d\uf077\uf00c\uf2bd\uf061\uf063\uf062\uf073\uf550\uf14a\uf35a\uf0c5\uf30b\uf09b\uf082\uf23a\uf41b\uf3b8\uf13b\uf38b\uf268\uf457'
const env = process.env.NODE_ENV;
console.log('--- current mode: ', env);
const base = {
src: 'src',
dest: 'docs',
}
const paths = {
css: {
src: `${base.src}/scss/*.scss`,
dest: `${base.dest}/css`,
},
js: {
src: `${base.src}/js/**/*.js`,
dest: `${base.dest}/js`,
},
html: {
src: `${base.src}/html/*.pug`,
dest: base.dest,
},
image: {
src: `${base.src}/image/*.+(jpg|jpeg|gif|png|svg)`,
dest: `${base.dest}/image`,
}
};
function clean() {
return del([
`${base.dest}/*`,
`!${base.dest}/.git`,
`!${base.dest}/.gitignore`,
`!${base.dest}/robots.txt`,
]);
}
const js = (done) => {
glob('./src/js/bundle/*.js', function (err, files) {
if (err) done(err);
files.push('src/js/index.js');
var tasks = files.map(function (entry) {
return browserify({
entries: [entry],
debug: env === 'development',
transform: [babelify.configure(),]
})
.bundle()
.pipe(source(entry.match(/[^\\/]+$/)[0]))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify())
.pipe(gulpif(env === 'development', sourcemaps.write()))
.pipe(rename({
extname: '.bundle.js'
}))
.pipe(gulp.dest(paths.js.dest));
});
es.merge(tasks).on('end', done)
.pipe(connect.reload());
})
}
function html() {
return src(paths.html.src)
.pipe(pug())
.pipe(dest(base.dest))
.pipe(connect.reload())
}
function sprite() {
const config = {
shape: {
dimension: {
maxWidth: 300,
maxHeight: 300,
},
spacing: {
padding: 2,
},
},
mode: {
view: {
bust: false,
example: true,
layout: 'vertical',
sprite: 'sprite.svg',
render: {
scss: { dest: '_sprite.scss' }
}
},
}
};
return src('src/image/sprite/*.svg')
.pipe(svgSprite(config))
.pipe(gulp.dest('src/scss/sprite'));
}
function css() {
const processors = [
autoprefixer({ overrideBrowserslist: ['last 2 version'] }),
];
if (env === 'production') {
processors.push(
uncss({
html: ['docs/*.html'],
})
)
}
const css = gulp.src(paths.css.src)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(postcss(processors))
.pipe(minifyCSS())
.pipe(gulpif(env === 'development', sourcemaps.write()))
.pipe(rename({
basename: 'main',
suffix: '.min'
}))
.pipe(dest(paths.css.dest))
.pipe(connect.reload())
const copySprite = gulp.src('src/scss/sprite/view/*.svg')
.pipe(gulp.dest('docs/css/'))
return merge(css, copySprite);
}
function font() {
return src(`${base.src}/webfonts/*.ttf`)
.pipe(fontmin({
text: fontText,
}))
.pipe(dest(`${base.dest}/webfonts`))
}
function img() {
return src(paths.image.src)
.pipe(imageMin())
.pipe(dest(paths.image.dest))
.pipe(connect.reload())
}
function beforeEnd() {
return src(`${base.src}/statics/*`)
.pipe(dest(`${base.dest}`))
}
function watch(done) {
if (env !== 'production') {
gulp.watch(`${base.src}/scss/**/*`, css);
gulp.watch(`${base.src}/html/**/*`, html);
gulp.watch(`${base.src}/js/**/*`, js);
gulp.watch(`${base.src}/image/*`, img);
gulp.watch(`${base.src}/image/*`, gulp.series(sprite, css));
}
done();
}
function server(done) {
if (env !== 'production') {
var options = {
root: 'docs',
port: 8080,
livereload: true,
};
connect.server(options);
}
done();
};
const resource = gulp.series(js, gulp.parallel(html, css, img, font))
const build = gulp.series(clean, sprite, resource, beforeEnd, gulp.parallel(watch, server))
exports.clean = clean;
exports.default = build;
exports.js = js;
exports.css = css
exports.img = img
exports.beforeEnd = beforeEnd
exports.sprite = gulp.series(sprite, css);