首页
7. 使用Gulp来自动化构建我们主题的资源

在前面的教程里,我们提到构建 Ghost 主题需要用到 gulp 来作为构建工具。 gulp 的工具链对于我们主题的开发和发布都起着很重要的作用,有了它我们可以更关注在主题的制作上面。

这篇教程对于 gulp 本身不会做太多讲解,大家可以去它的官网获取更多的知识。

使用 yarn 来管理依赖

yarn 相比 npm,它安装包的速度更快一些,所以我更倾向去用它来做依赖管理工具。

安装

npm install -g yarn
yarn -v

常用命令

# 全局安装
yarn global add [package]
# 安装依赖到不同环境
yarn add [package] --dev
yarn add [package] --peer
yarn add [package] --optional
# 更新依赖
yarn upgrade [package]
# 移除依赖
yarn remove [package]

安装 Gulp 工具链

全局安装 Gulp

# 安装 gulp
yarn global add gulp@latest

安装完后执行 gulp -v,如果有问题,我们可以在主题的项目里面安装

yarn add gulp --dev

安装插件

gulp 提供了丰富的插件来满足我们不同的应用场景。我们主要用到它的一些插件来做主题的资源管理。

image_1eiamvncnivb6da15ve1ae01o5p9.png-99.2kB

gulp-autoprefixer

Autoprefixer 是一个很实用的 css 后处理器,它可以自动帮我们处理浏览器的兼容性问题。使用它后,在写 css 的时候,我们没必要去针对特定的浏览器去写一些样式。

yarn add gulp-autoprefixer --dev

gulp-less

Less 是一门 css 预处理语言,我们用它来写主题的样式更方便扩展可管理。选择 LessSass 可以完全凭自己的喜好,对于我们这种小型的主题开发来说,两者的差别并不是很大。gulp-less 插件可以将我们的 less 文件编译成 css

yarn add gulp-less --dev

gulp-clean-css

这个插件是用来压缩 css 文件的,使生成环境的文件体积变得更小。

yarn add gulp-clean-css --dev

gulp-uglify

这个插件时用来压缩 js 文件的。

yarn add gulp-uglify --dev

gulp-concat

这个插件是把多个文件合并成一个文件

yarn add gulp-concat --dev

gulp-rename

这个插件是对文件重命名

yarn add gulp-rename --dev

到这里,我们需要的插件都安装好了。接下来我们就开始写 gulp 脚本了。

编写 gulpfile 文件

在我们主题的根目录下我们创建一个 gulpfile.js 文件并在文件中输入以下内容

function defaultTask(cb) {
  // place code for your default task here
  cb();
}

exports.default = defaultTask

在主题的根目录下执行 gulp 命令

gulp

image_1eib1fiv57vt7uurhg1huhpkcm.png-19kB

默认任务将执行,因为任务为空,所以实际上什么都没做。

创建任务

我们要做的事情其实很简单,就是把 src 目录里面的资源压缩打包到 assets 里即可。

在开发主题的时候,我们需要监测 src 目录里文件的变化,如果有文件发生了变化就执行任务;在上生产环境时,我们手动执行一下即可。

最终的 gulpfile.js如下:

const { src, dest, series, parallel, watch } = require('gulp');
const less = require('gulp-less');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const autoprefixer = require('gulp-autoprefixer');
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');

//编译、合并、压缩less文件
const buildLess = (cb) => {
  return src(['src/less/**/*.less'])
    .pipe(concat('style.less'))
    .pipe(less())
    .pipe(autoprefixer())
    .pipe(cleanCSS({ compatibility: 'ie8' }))
    .pipe(dest('src/css'))
}

//合并压缩后的css文件
const buildCss = (cb) => {
  return src(['src/css/*.css'])
    .pipe(concat('style.min.css'))
    .pipe(autoprefixer())
    .pipe(cleanCSS({ compatibility: 'ie8' }))
    .pipe(dest('assets/css'))
}

//压缩、合并js文件
const mainJs = (cb) => {
  return src(['src/js/jquery.min.js', 'src/js/main.js'])
    .pipe(uglify())
    .pipe(concat('index.js'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(dest('assets/js'))
}

//文件监听
const auto = (cb) => {
  watch('src/assets/less/**/*.less', series(buildLess, buildCss))
  watch('src/assets/css/*.css', buildCss)
  watch('src/assets/js/**/*.js', mainJs)
}

//生产环境构建
exports.build = series(buildLess, buildCss, mainJs)
//开发环境构建
exports.dev = auto

任务讲解

gulp4 把任务分为了公开任务和私有任务。公开任务使用 exports 导出,可以通过 gulp 命令直接调用。

这里我们公开了两个任务:builddev,分别对应生产环境和开发环境

gulp build
gulp dev

私有任务被设计在内部使用,通常可以用 series()parallel() 来组合使用。我们实现了 buildLessbuildCssmainJsauto 这几个私有任务。

buildLess 任务做的事情是把 src/less 文件夹下所有的 less 文件合并为一个 style.less 文件,然后转换成同名的 css 文件,使用 autoprefixer 后处理器,最终压缩并生成到 src/css 文件夹中。

buildCss 任务做的事情是把 src/css 文件夹下所有的 css 文件合并为一个 style.min.css 文件,使用 autoprefixer 后处理器,最终压缩并生成到 assets/css 文件夹中。

mainJs 任务同上,做的事情都不复杂。auto 任务实现了文件的监听,当我们修改了代码后,会自动构建对应的任务,方便我们实时去预览效果。

构建任务

我们可以先把任务中需要的文件都新建好。 注意:前面我们在 assets/css 里建了一个 main.css,我们把它移到 src/css 里。 然后清空 assets 文件夹

image_1eib5rni6151osba9m1131113a41t.png-13kB

执行 gulp build 后就可以生成生产环境的资源。最终在 assets 里面有一个 css/style.min.css 文件和一个 js/index.min.js 文件

image_1eib5ssgi1vg91u4bmgb1toq1a2v2a.png-6.5kB

到这里,我们使用 gulp 来管理主题的资源就完成了。最后别忘了,到 default.hbs 里引入文件。

<!DOCTYPE html>
<html lang="{{@site.lang}}">

<head>
  {{!-- Document Settings --}}
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />

  {{!-- Base Meta --}}
  <title>{{meta_title}}</title>
  <meta name="HandheldFriendly" content="True" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  {{!-- Styles'n'Scripts --}}
  <link rel="stylesheet" type="text/css" href="{{asset "css/style.min.css"}}" />

  {{!-- This tag outputs SEO meta+structured data and other important settings --}}
  {{ghost_head}}

</head>

<body class="{{body_class}}">
  <div class="site-wrapper">
    {{!-- All the main content gets inserted here, index.hbs, post.hbs, etc --}}
    {{{body}}}
  </div>
  <script src="{{asset 'js/index.min.js'}}"></script>
  {{ghost_foot}}

</body>

</html>

示例代码:https://github.com/KINGMJ/maple-test/tree/features/tutorials-7