用gulp来打包我们的项目

2,188 阅读9分钟

前言

虽然说现在webpack已经很强大了,但是gulp也没有完全退出历史舞台,有些时候面试还会问到有没有使用gulp,如果说你碰到过gulp的相关,希望这篇文章对你会有小小的帮助!

平时学习的语雀地址

www.yuque.com/kongdesheng…

gulp是什么?

gulp.js 是一个自动化构建工具,用于自动化Web开发中涉及的耗时和重复性任务,Gulp.js 是基于 Node.js 构建的,利用 Node.js 流的威力,你可以快速构建项目。

gulp的优点

  • 代码优于配置、node最佳实践、精简的API集,gulp让工作前所未有的简单。
  • 基于node强大的流(stream)能力,gulp在构建过程中并不把文件立即写入磁盘,从而提高了构建速度。
  • 遵循严格的准则,确保我们的插件结构简单、运行结果可控。

gulp的缺点

插件bug比较难处理。

准备工作

step1.检查环境配置

我们先来检查一下检查 node、npm 或者 npx 或者 yarn是否正确安装。

image.png

新的node和npm用户可能会遇到权限问题。这些问题EACCESS在安装过程中以错误的形式显示。如果发生这种情况,请参考《npm指南》以修复权限。

step2.安装 gulp 命令行工具

安装命令

npm install --global gulp-cli

step3.创建项目目录

这里我们将创建一个名为kds-gulp项目为例。

step4.初始化package.json

cd到我们的项目目录(kds-gulp)执行以下命令创建package.json文件,我这里使用yarn命令

//使用npm命令也可以
yarn init

step5.安装gulp开发依赖

安装命令

yarn add --save-dev gulp

step6.检查版本

执行命令检查我们是否成功安装插件

gulp -v

step7.建立gulpfile.js文件

gulp也需要一个文件作为它的入口文件,在gulp中这个文件叫做gulpfile.js。

step8.准备项目资源

在项目路径下新建src文件,将我们所需要的开发文件和静态资源放入其中,下面是我所准备的静态资源,之后将对每一种类型的文件如何使用gulp进行自动化操作进行详尽的说明。

大家如果想自己尝试一下的话,按照文件后缀名自己准备资源文件即可。

└── kds-gulp ································· project root
   ├─ public ········································· static folder
   │  └─ favicon.ico ································· static file (unprocessed)
   ├─ src ············································ source folder
   │  ├─ assets ······································ assets folder
   │  │  ├─ fonts ···································· fonts folder
   │  │  │  └─ pages.ttf ····························· font file (imagemin)
   │  │  ├─ images ··································· images folder
   │  │  │  └─ logo.png ······························ image file (imagemin)
   │  │  ├─ scripts ·································· scripts folder
   │  │  │  └─ main.js ······························· script file (babel / uglify)
   │  │  └─ styles ··································· styles folder
   │  │     ├─ _variables.scss ······················· partial sass file (dont output)
   │  │     └─ main.scss ····························· entry scss file (scss / postcss)
   │  ├─ layouts ····································· layouts folder
   │  │  └─ basic.html ······························· layout file (dont output)
   │  ├─ partials ···································· partials folder
   │  │  └─ header.html ······························ partial file (dont output)
   │  ├─ about.html ·································· page file (use layout & partials)
   │  └─ index.html ·································· page file (use layout & partials)
   ├─ .csscomb.json ·································· csscomb config file
   ├─ .editorconfig ·································· editor config file
   ├─ .gitignore ····································· git ignore file
   ├─ .travis.yml ···································· travis ci config file
   ├─ CHANGELOG.md ··································· repo changelog
   ├─ LICENSE ········································ repo license
   ├─ README.md ······································ repo readme
   ├─ gulpfile.js ···································· gulp tasks file
   ├─ package.json ··································· package file
   └─ yarn.lock ······································ yarn lock file

开始上手

我们对资源文件进行处理的逻辑代码需要卸载gulpfile.js中

step1.安装gulp-load-plugins插件

先安装这个模块主要是为了让代码变得简洁,之后我们需要require许多插件,做好提前量,(如果还不知道 gulp-load-plugins有什么作用请去常用插件中寻找)。

安装命令

yarn add gulp-load-plugins --dev

step2.样式编译

查看项目kds-gulp的项目目录,在src/assests/styles存在scss样式文件,但是生产环境无法识别这些样式文件,我们需要把它转换成可识别的css文件。

  • 安装gulp-sass插件。
  • 注意:以_开头的scss文件会被忽略掉,不会被转换。
  • 将转译后的文件输出到temp临时目录,以便后边做合并操作。
  • 运行 gulp style测试。

安装命令:

yarn add gulp-sass --dev

编写gulpfile.js中的代码块: 如果想要在输出目录保持输入目录的文件层级加上{base: 'src'}即可

const style = () =>{
    return src('src/assets/styles/*.scss',{base: 'src'})
    .pipe(plugins.sass())
    .pipe(dest('temp'))
}
module.exports = {
    style
}

step3.脚本编辑

查看项目kds-gulp的项目目录,在src/assests/scripts存在js脚本文件,我开实际开发中可能会使用es6语法,生产环境中对es6兼容性可能会存在问题,我们需要通过babel把es6转换成es5语法,具体操作如下:

  • 安装gulp-babel插件。
  • 编写转换函数。
  • 将转译后的文件输出到temp临时目录,以便后边做合并操作。
  • 运行 gulp scripts测试。

安装命令:

yarn add gulp-babel --dev

编写代码:

const scripts = () =>{
    return src('src/assets/scripts/*.js',{base: 'src'})
			.pipe(plugins.babel({presets: ['@babel/env']}))
			.pipe(dest('temp'))
}
//将目标文件下所有js文件转换流传送给babel处理,最后输出到temp目录
module.exports = {
    scripts
}

step5.资源文件处理

现在开始对我们的图片字体等静态资源进行压缩处理,并进行缓存。

  • 安装gulp-imagemin插件和gulp-cache插件。
  • 压缩图片,减少图片体积。
  • 因为压缩图片比较耗时,我们只需要压缩修改的图片,没有修改的直接从缓存中读取。
  • 编写转换函数。
  • 运行 gulp img和gulp font测试。

安装命令

yarn add gulp-cache --dev
yarn add gulp-imagemin --dev

编写代码

const img = () =>{
    return src('src/assets/images/**',{base: 'src'}).pipe(plugins.cache(
        plugins.imagemin({
            progressive : true,//是否渐进的优化
            svgoPlugins : [{removeViewBox:false}],//svgo插件是否删除幻灯片
            interlaced : true //是否各行扫描
        })
    )).pipe(dest('dist'))
}
module.exports = {
    img
}

字体样式文件同理

const font = () => {
    return src('src/assets/fonts/**',{base: 'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}
module.exports = {
    font
}

step6.额外文件

对于非src下其他相关文件也同样需要打包到dist目下,例如public目录下,也需要处理一下。

const extra = () =>{
    return src('public/**',{base: 'public'})
    .pipe(dest('dist'))
}
module.exports = {
    extra
}

step7.组合执行命令

如果我们一个个去敲命令执行转换操作,麻烦且繁琐,使用parallel(),series()去进行组合嵌套,parallel,series可以去官网api查看,这里不多做叙述。

  • 使用parallel(),series()将函数组合到一起执行。
  • 生成dist前,执行clean先清除一遍以防有缓存。
  • 将temp目录下的文件进行合并压缩输出到dist目录。
  • 了解合并压缩过程请跳到上线准备章节。
  • 运行 gulp build测试。
const clean = () =>{
    return src(['dist','temp'])
    .pipe(plugins.clean())
}//清除已存在的dist包

const compile =  parallel([style,scripts,page]);//合并step2,3,4的操作

//上线前端操作
const build = series(clean, parallel(series(complie, useref),extra, image, font))//清除dist包后,执行step1,2,3,4,5,6的操作

module.exports = {
    build
}

测试调试

开发阶段我们需要不断修改代码并展现在浏览器中供我们调试开发,并且我们希望这种方式是“热更新的形式”。 我们可以通过gulp创建一个服务器来满足我们的开发需求。

step1.创建基础服务器

  • 安装browser-sync模块。
  • 通过browser-sync的create区创建一个服务器。
  • 编写我们的serve函数,并且初始化我们的服务器。
  • gulp build过后执行 gulp serve测试。

安装命令

yarn add browser-sync --dev

创建服务器

const borwserSync = require('browser-sync') 
const bs = borwserSync.create()//自动打开浏览器
const serve = () => {  
    bs.init({
      notify: false,
      port: 3000,//启动浏览器的端口号
      files:'dist/**',//监听dist文件下有改动的时候刷新页面
      server: {
        baseDir: ['dist','src','public'],//如果找不到目标文件,会按着数组目录依次查找
        routes: {
          '/node_modules': 'node_modules' //自动映射到项目下的node_modules
        }
      }
    })
}

step2.监听文件更改

上述操作的确可以动态的跟新服务器,但是仅限于dist目录发生改变的时候,这样我们不得不一遍一遍打包执行build操作,很麻烦,所以我们需要简化这步操作。

  • 通过watch()监听文件改变,来动态的执行我们对应的方法。
  • 合并命令行。
  • 执行gulp develop测试。
const serve = () => {...  
//第一个参数为监听路径,第二个为对应执行的处理函数。
watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload)
}

const compile =  parallel([style,scripts,page]);//合并step2,3,4的操作
//将打包命令和服务器启动整合到一起
const develop = series(compile,serve)
module.exports = {
    compile,
    develop
}

上线准备

上线前我们需要把html中的文件进行合并处理。这里要用到useref。

step1.合并

  • gulp-useref将HTML引用的多个CSS和JS合并起来,减小依赖的文件个数,从而减少浏览器发起的请求次数。
  • gulp-useref根据注释将HTML中需要合并压缩的区块找出来,对区块内的所有文件进行合并。
  • 它只负责合并,不负责压缩!

安装命令

yarn add gulp-useref --dev

编写代码

const useref = {
    rerurn src('temp/*.html',{base: 'temp'}).pipe(plugins.useref({searchPath:['temp','.'] }))  
           .pipe(dest('dist')) 
}

step2.压缩

  • 我们需要对js、css、html进行压缩。
  • 安装gulp-uglify、gulp-htmlmin、gulp-clean-css模块
  • 使用if插件对当前环境进行判断,执行不同压缩。

安装命令

yarn add gulp-htmlmin --dev
yarn add gulp-uglify --dev
yarn add gulp-clean-css --dev
yarn add gulp-if --dev

编写代码

const useref = {
    rerurn src('temp/*.html',{base: 'temp'}).pipe(plugins.useref({searchPath:['temp','.'] }))
            .pipe(plugins.if(/\.js$/, plugins.uglify()))
            .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
            .pipe(plugins.if(/\.html$/, plugins.htmlmin({ 
                collapseWhitespace: true,
                minifyCSS: true, //页面里的style和js脚本压缩
                minifyJS: true
            }))) //html    
           .pipe(dest('dist')) 
}

常用插件

这里介绍一些实际开发中经常用到的插件,gulp插件库已经很丰富了,如果有需要可以去官网查询。 gulpjs.com/plugins/

gulp-babel

描述:将ES6代码编译成ES5。

const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.src('./js/index.js')
    .pipe(babel({
        presets: ['@babel/preset-env']
}))
    .pipe(gulp.dest('./dist'))

gulp-sass

描述:编译sass。

const sass = require('gulp-sass');
gulp.src('./sass/**/*.scss')
    .pipe(sass({
        outputStyle: 'compressed'           // 配置输出方式,默认为nested
    }))
    .pipe(gulp.dest('./dist/css'));

gulp-rename

描述:用来重命名文件流中的文件。

var rename = require("gulp-rename");

gulp.src('./hello.txt')
  .pipe(rename('gb/goodbye.md'))    // 直接修改文件名和路径
  .pipe(gulp.dest('./dist')); 

gulp.src('./hello.txt')
  .pipe(rename({
    dirname: "text",                // 路径名
    basename: "goodbye",            // 主文件名
    prefix: "pre-",                 // 前缀
    suffix: "-min",                 // 后缀
    extname: ".html"                // 扩展名
  }))
  .pipe(gulp.dest('./dist'));

gulp-load-plugins

  • 要使用gulp的插件,首先得用require来把插件加载进来。
  • 如果要加载很多,代码变得又臭又长。
  • gulp-load-plugins插件正是用来解决这个问题。
var gulp = require('gulp'),
    //一些gulp插件,abcd这些命名只是用来举个例子
    a = require('gulp-a'), 
    b = require('gulp-b'),
    c = require('gulp-c'),
    d = require('gulp-d'),
    //更多的插件...
    z = require('gulp-...');  

自从有了它有了它以后
// package.json 

"devDependencies": {
    "gulp": "^3.9.1",
    "gulp-concat": "^2.6.1",
    "gulp-rename": "^1.2.2",
    "gulp-uglify": "^2.0.1"
}

// gulpfile.js

var plugins = require('gulp-load-plugins')();     // $ 是一个对象,加载了依赖里的插件

gulp.src('./**/*.js')
    .pipe(plugins.concat('all.js'))               // 使用插件就可以用$.PluginsName()
    .pipe(plugins.uglify())
    .pipe(plugins.rename('all.min.js'))
    .pipe(gulp.dest('./dist'))

gulp-clean-css

描述:压缩css文件,减小文件大小。

const gulp = require('gulp');
const babel = require('gulp-babel');

gulp.src('./js/index.js')
    .pipe(babel({
        presets: ['@babel/preset-env']
    }))
    .pipe(gulp.dest('./dist'))

gulp-cache

  • 监控到图片被改变了,替换了,才去压缩。
  • 如果仅仅是改变了图片名字,则不会被替换。
var cache = require('gulp-cache');

gulp.task('img', function (
	){
	gulp.src('./src/images/*.{jpg|jpeg|png|gif}',)
		.pipe(
			cache(
				imagemin({
			        progressive : true,//是否渐进的优化
			        svgoPlugins : [{removeViewBox:false}],//svgo插件是否删除幻灯片
			        interlaced : true //是否各行扫描
	    		})
	    	)
		)
		.pipe(
			gulp.dest('./src/images/*.{jpg|jpeg|png|gif}')
		)
});

gulp-swig

描述:swig 一个简单的,强大的,可扩展的JavaScript模板引擎。

var swig = require('gulp-swig');
var opts = {
  data: {
    headline: "Welcome"
  }
};
gulp.task('templates', function() {
  gulp.src('./lib/*.html')
    .pipe(swig(opts))
    .pipe(gulp.dest('./dist/'))
});

gulp-imagemin

描述:压缩图片。

var imagemin = require('gulp-imagemin');

gulp.src('./img/*.{jpg,png,gif,ico}')
    .pipe(imagemin())
    .pipe(gulp.dest('./dist/img'))

gulp-useref

描述:合并文件。

var gulp = require('gulp'),
    useref = require('gulp-useref');

gulp.task('default', function () {
    return gulp.src('app/*.html')
        .pipe(useref())
        .pipe(gulp.dest('dist'));
});

html中

需要配合构建注释使用

<html>
<head>
    <!-- build:css css/combined.css -->
    <link href="css/one.css" rel="stylesheet">
    <link href="css/two.css" rel="stylesheet">
    <!-- endbuild -->
</head>
<body>
    <!-- build:js scripts/combined.js -->
    <script type="text/javascript" src="scripts/one.js"></script>
    <script type="text/javascript" src="scripts/two.js"></script>
    <!-- endbuild -->
</body>
</html>

gulp-uglify

描述:用来压缩js文件,使用的是uglify引擎。

var gulp = require('gulp'),
    uglify = require("gulp-uglify");
 
gulp.task('minify-js', function () {
    gulp.src('js/*.js') // 要压缩的js文件
    .pipe(uglify())  //使用uglify进行压缩,更多配置请参考:
    .pipe(gulp.dest('dist/js')); //压缩后的路径
});

gulp-minify-css

描述:要压缩css文件时可以使用该插件。

var gulp = require('gulp'),
    minifyCss = require("gulp-minify-css");
 
gulp.task('minify-css', function () {
    gulp.src('css/*.css') // 要压缩的css文件
    .pipe(minifyCss()) //压缩css
    .pipe(gulp.dest('dist/css'));
});

gulp-htmlmin

描述:用来压缩html文件。

var gulp = require('gulp'),
    minifyHtml = require("gulp-htmlmin");
 
gulp.task('minify-html', function () {
    gulp.src('html/*.html') // 要压缩的html文件
    .pipe(minifyHtml()) //压缩
    .pipe(gulp.dest('dist/html'));
});