互联网的不断发展推动了web前端技术快速的向前,各种前端库或框架百花齐放。自动化构建是将源代码利用工具自动转换成用户可以使用的目标文件的过程,将复杂且重复性任务交给程序脚本自动完成,从而减小我们开发的工作量,加快开发速度。这里咱们先了解下gulp的使用,给咱们开发前端页面带了哪些便捷之处。
前言
通过以下简单案例,来描述下如何利用Gulp拆分工作量,快速进行项目开发并生成需要页面。
首先该企业站所有页面头部和尾部内容都是一样的,可以分别独立为header.html和footer.html两文件;另外再分析内页时发现,左侧导航样式及布局也是一致的,所以可以独立出aside.html文件,大概如下所示:
所有独立出来部分的内容和样式开发完全后,可以通过后面所讲的gulp-html-tpl,将所有片段化文件合并到一起,这部分工作是交给gulp自动完成的,这样一个完整的页面就可以生成出来了。
代码如下所示:
<template src="header.html"></template>
<div class="main">
<div class="container">
中间内容部分
</div>
</div>
<template src="footer.html"></template>
生成后代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>网站标题</title>
<link rel="stylesheet" type="text/css" href="引入样式文件">
<script type="text/javascript" src="引入脚本文件"></script>
</head>
<body>
<header>
公共头部内容
</header>
<div class="main">
<div class="container">
中间内容部分
</div>
</div>
<footer>
公共页脚内容
</footer>
</body>
</html>
这样开发静态页面好处在于,当项目中静态页面数量过多时,不必为修改公共部分而烦恼了;可以直接在header.html、footer.html或aside.html这些文件内修改,gulp会自动帮我们把修改内容重写到所有html页面中。
当然gulp前端自动开发好处不仅限于此,更多技巧就自己去实践并发现吧。
一、环境搭建步骤
1.package.json初始化命令
在项目目录中,输入以下命令,生成package.json文件(注:需提前安装nodejs运行环境+Git)
nodejs地址:点击下载
Git地址:点击下载
npm init
文件生成前,填写如下内容后,package.json文件即可生成
Press ^C at any time to quit.
package name: (beilequanapp_plugin) //项目名称
version: (1.0.0) //版本号
description: //项目描述
entry point: (index.js) //入口函数
test command: //执行脚本文件(默认node app.js)
git repository: //git仓库
keywords: //关键词
author: //作者
license: (ISC) //许可证(默认ISC)
2.gulp全局安装
//默认安装
npm install --global gulp
//指定版本安装,这里使用指定版本安装(3.9.1较为稳定)
npm install --global gulp@3.9.1
3.gulp本地依赖安装
//默认安装为4.0.2,该版本某些函数已废弃,故使用3.9.1版本较为稳定
npm install --save-dev gulp@3.9.1
/*
注:--save-dev和--save区域
开发和测试所需要的依赖,即本地环境
--save-dev 简写:-D 添加到devDependencies
生产环境所需依赖,即线上环境
--save 简写:-S 添加到dependencies
*/
4.browerify安装
browerify可以让类似于node的require()的方式来组织javascript代码,通过预编译让前端javascript可以直接使用node NPM安装的一些库;命令如下:
npm install --save-dev browser-sync
5.其他插件安装
//用于在HTML中引入其他HTML片段,同时支持多目录查询 和模板渲染
npm install --save-dev gulp-html-tpl
//HTML内容压缩
npm install --save-dev gulp-htmlmin
//合并文件
npm install --save-dev gulp-concat
//替换原文件名称
npm install --save-dev gulp-rename
//预编译css样式文件
npm install --save-dev gulp-sass
//根据浏览器版本自动处理浏览器前缀
npm install --save-dev gulp-autoprefixer
//css样式压缩
npm install --save-dev gulp-minify-css
//babel编译es6(默认安装为8.0,不太稳定)
npm install --save-dev gulp-babel@7 babel-core babel-preset-env babel-preset-es2015
//压缩图片
npm install --save-dev gulp-imagemin
//使用UglifyJS缩小js文件
npm install --save-dev gulp-uglify
//批量引入 package.json文件中的依赖工具
npm install --save-dev gulp-load-plugins
6.在package.json文件同级目录中,创建gulpfile.js文件
var gulp = require('gulp');
var browserSync = require('browser-sync');
var $ = require('gulp-load-plugins')();
gulp.task('sass', function(){
gulp.src('assets/css/*.scss') //读取css目录中所有scss文件
.pipe($.sass()) //预编译css
.pipe($.autoprefixer()) //自动添加兼容前缀
.pipe($.minifyCss()) //压缩Css
.pipe(gulp.dest('dist/css')); //重新写入指定运行目录
});
gulp.task('uglify', function(){
gulp.src('assets/js/*.js') //读取js目录中所有js文件
.pipe($.concat('common.min.js')) //连接所有js文件并重命令为app.min.js
.pipe($.uglify()) //压缩js
.pipe(gulp.dest(_dist + '/css')); //重新写入指定目录
});
//预编译html
gulp.task('html', function(){
gulp.src('assets/*.html').pipe($.htmlTpl({
tag: 'template',
paths: ['assets/template'],
log: false
}))
.pipe($.htmlmin()) //压缩html内容
.pipe(gulp.dest(_dist + '/'));
});
gulp.task('default', function(){
//执行进程函数
gulp.run('sass', 'uglify', 'html');
//开启服务环境
browserSync({
server: {
baseDir: 'dist/',
tunnel: true
}
});
//监听样式文件,如有变动重新执行进程sass预编译样式文件
gulp.watch('assets/css/*.scss', ['sass']).on('change', browserSync.reload);
//监听js
gulp.watch('assets/js/*.js', ['uglify']).on('change', browserSync.reload);
//监听html
gulp.watch('assets/*.html', ['html']).on('change', browserSync.reload);
});
二、使用cmd或git Bash执行
输入命令: gulp,这样就可以运行了,执行效果如下
三、js合并处理后,会出现 Uncaught ReferenceError: require is not define
此问题是由于babel 只是帮助你转译语法,需要转译为浏览器端可用的代码还需要 webpack 或 browserify。这里使用browserify,注意版本号,过高版本无法正常运行。
//文件打包组件
npm install --save-dev browserify@14
//支持import from export解析
npm install --save-dev babelify@8
//stream流和buffer流处理
npm install --save-dev vinyl-source-stream vinyl-buffer
//gulpfile.js如下修改
var babelify = require('babelify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
//上述uglify进程作以下修改
gulp.task('uglify', function(){
return browserify({
entries: 'assets/js/index.js',
debug: true
})
.transform(babelify, {presets: ["es2015"], extensions: [".js"]})
.bundle()
.pipe(source('app.js'))
.pipe(gulp.dest('dist/js'));
});
Gulp更多详细教程,可以查看以下教程:Gulp构建前端自动化工作流 - 《Gulp构建前端自动化工作流(Gulp入门介绍)》 - 书栈网 · BookStack
四、html页面创建
前面有安装gulp-html-tpl插件,这个可以很多帮助我们拆分html页面模块;这样咱们也能像java, php等后台开发语言一样,把头和尾独立出来了。
1.注意前面gulpfile.js中,对gulp-html-tpl的设置, paths: ['assets/template']为指定引入模板的目录,
2.如上图,创建头部header.html和底部footer.html文件,放在template目录即可
1)header.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>页面标题</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<script type="text/javascript" src="js/common.min.js"></script>
</head>
<body>
2)footer.html文件
</body>
</html>
3.头部和尾部文件创建好,即可引入了,如1中图示,在assets目录创建index.html文件
<!-- 引入头部文件 -->
<template src="header.html"></template>
<div class="main">
<!-- 中间内容部分 -->
</div>
<!-- 引入底部文件 -->
<template src="footer.html"></template>
4.因为每个页面中标题或相关数据需要渲染指定内容,如何把内容传输到模板页面中呢,这个gulp-html-tpl已经很好帮助我们处理好了,具体用户法下:
1)修改header.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<script type="text/javascript" src="js/common.min.js"></script>
</head>
<body>
2)在index.html中引入数据
<!-- 引入头部文件 -->
<template src="header.html" title="首页"></template>
<div class="main">
<!-- 中间内容部分 -->
</div>
<!-- 引入底部文件 -->
<template src="footer.html"></template>
3)除了在template标签上添加变量属性传输数据外,也可以通过以下方式定义
<!-- 引入头部文件 -->
<template src="header.html">
{
"title": "首页"
}
</template>
<div class="main">
<!-- 中间内容部分 -->
</div>
<!-- 引入底部文件 -->
<template src="footer.html"></template>
5.如何在模板内部引入html,这个方法也很简单:
1)header.html文件修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<script type="text/javascript" src="js/common.min.js"></script>
</head>
<body>
<!-- 引入banner HTML代码 -->
{{bannerHtml}}
2)index.html文件中传入html代码
<!-- 引入头部文件 -->
<template src="header.html" title="首页">
<fragment id="bannerHtml">
<div class="banner">
<img src="..." alt="" />
</div>
</fragment>
</template>
<div class="main">
<!-- 中间内容部分 -->
</div>
<!-- 引入底部文件 -->
<template src="footer.html"></template>
6.需要了解更多gulp-html-tpl语法,可点击下面链接查看
五、css样式表创建
由于传统css书写无法嵌入式书写,无法定义变量,无样式复用机制等等,导致难以维护及工作量较大原因,衍生出CSS预编译处理器。目前网上主流的三个预编译处理器有Less、Sass和Stylus。本篇主要讲sass,想了解其他几项可以去其官网查看语法。
Less地址:Less 中文网
Sass地址:Sass教程 Sass中文文档 | Sass中文网
Stylus地址:Stylus - 富于表现力、健壮、功能丰富的 CSS 预处理器 | Stylus 中文网
1.在css目录中,可以创建common.sass文件
/*定义字体大小*/
$fontSize12: 12px;
$fontSize14: 14px;
$fontSize16: 16px;
$fontSize18: 18px;
/*定义颜色*/
$colorWhite: #FFFFFF;
$colorBlack: #000000;
$colorBlack2: #333333;
$colorGray: #666666;
$colorGray2: #999999;
/*定义常用尺寸*/
$middleWidth: 1200px;
html, body{
font-size: $fontSize12;
color: $colorBlack2;
}
div.main{
.container{
width: $middleWidth;
}
}
这里暂时先简单示例下基本语法,更多且更复杂的语法使用,请去其官方查看文档。
六、js文件创建
在gulpfile.js文件里,指定了合并js目录为assets/js/*.js中,故需要合并的js创建在assets/js目录中即可。这样在assets/js目录中创建的所有js文件会合并到common.min.js文件中。由于这里通过通配符进行文件读取,所以合并顺序可能不是我们想要的;其实也可以通过指定文件进行合并,具体修改如下:
//原uglify进程
gulp.task('uglify', function(){
gulp.src('assets/js/*.js')
.pipe($.concat('common.min.js'))
.pipe($.uglify())
.pipe(gulp.dest(_dist + '/css'));
});
//修改后uglify进程
gulp.task('uglify', function(){
//将通配符匹配,修改为数组并指定文件形式进行合并
gulp.src([
"assets/js/lib.js",
"assets/js/utils.js",
"assets/js/index.js",
])
.pipe($.concat('common.min.js'))
.pipe($.uglify())
.pipe(gulp.dest(_dist + '/css'));
});
现在我们可以正常开发我们功能了。这是先例举下index.js创建并开发,例如我们现在需要开发一个轮播图插件功能,在index.js写法如下:
/**
* 轮播图
*/
var Slideshow = function(params){
//功能代码
}
window.slideshow = Slideshow;
这样在html中引入common.min.js脚本文件后,就可以使用轮播图功能了,例如:
<script type="text/javascript">
//执行轮播图函数
Slideshow({
container: '#slider',
dots: true
});
</script>
七、import和export使用
首先我们安装下jquery插件,可以极大简化javascript编程,能写更少代码,实现更的多的功能。
npm install jquery
7.1 这样先看下如何使用import吧,代码如下:
import jQuery from 'jquery';
//因此我们可以把功能 更改 为jquery插件形式进行开发了
$.fn.Slideshow = function(params){
//功能代码
}
调用方法修改:
<div id="slider"></div>
<script type="text/javascript">
$('#slider').Slideshow({
dots: true
});
</script>
7.2 使用export
我们也可以开发自己的类库,然后通过import引入,这里我们在js目录下创建lib类库;由于uglify进程中没有指定lib目录,所以该目录中js不会合并到common.min.js中。在lib目录中创建utils.js工具类,代码示例:
//将颜色值转为rgba
function color2Rgb(_value){
var rgb = '';
//功能代码...
return rgb;
}
//格式化日期
function formmatDate(_value){
//功能代码
}
export {color2Rgb, formmatDate}
现在我们在index.js文件中引入utils.js功能:
import jQuery from 'jquery';
import {color2Rgb, formmatDate} from './lib/utils.js';
//因此我们可以把功能 更改 为jquery插件形式进行开发了
$.fn.Slideshow = function(params){
//日期格式化
var dateStr = formmatDate(new Date());
//功能代码
}
八、打包文件自动同步到服务器指定位置
使用纯javascript实现的scp2将文件复制到远程服务器。
8.1 安装gulp-scp2
npm install --save gulp-scp2
8.2 定义执行进程
const gulp = require('gulp')
const scp = require('gulp-scp2')
//定义上传执行进程
gulp.task('upload', () => {
return gulp.src('dist/**/*')
.pipe(scp({
host: '服务器IP',
username: '账号',
password: '登录密码',
dest: '服务器文件存储路径',
watch: function(client) {
client.on('write', function(o) {
console.log('write %s', o.destination);
});
}
}))
.on('error', (err) => {
console.log(err)
})
.on('end', () => {
console.log('上传完成')
})
})