Maine

纵有疾风起,人生不言弃

使用 Gulp 加速 WordPress 开发

古语云:工欲善其事必先利其器,虽然使用任何一款编辑器就可以直接进行 WordPress 的主题开发,但是却不够便捷,因此我们将配合使用如今非常流行的构建工具 Gulp 来加速我们的 WordPress 主题开发,这将改变我们的工作流程,以下步骤将会被自动完成:

  • 复制较新的PHP主题文件
  • 优化图像文件
  • 将 SCSS 文件编译为单个缩小的CSS文件
  • 合并所有的JavaScript文件,使用 Babel 转义ES6语法,并且删除调试语句以及压缩
  • 文件更新时自动刷新浏览器

Gulp 介绍

Gulp是一个基于JavaScript的构建系统,它可以获取源文件并将其转换为优化版本。如果您还没有用过Gulp,请参阅Gulp.js官网以获取使用说明。初始步骤如下:

  1. 安装Node.js。
  2. 全局安装Gulp: npm install gulp-cli -g
  3. 创建一个项目文件夹并从终端进入:mkdir mytheme 然后 cd mytheme
  4. 使用npm初始化项目: npm init

项目文件

Gulp(或任何)构建工具需要一组包含未修改过的源代码和图像源文件。然后对它们进行处理,操作和压缩来创建编译后的文件。

WordPress安装在Web服务器的文件夹中,在运行Apache的linux系统上,服务器文件夹可能是 /var/www/。您的WordPress主题必须在Wordpress的子文件夹/wp-content/themes/中定义。因此,包含我们最终编译后的文件的文件夹可以是/var/www/wp-content/themes/mytheme/。WP主题至少需要两个文件:

  • 一个style.css样式表,在顶部的注释中包含元数据
  • 一个index.php模板文件。

你可以将源文件放在mytheme文件夹中的某个位置。如果你最终要将主题给别人下载,同时还想要别人使用你开发时使用的源代码进行主题的修改,那么这可能很有用。但是,在这里,我们将使用Web服务器无法访问的源文件夹,例如~/mytheme/。这种方法的好处:

  1. 你的主题源文件可以在单个文件夹和存储库中进行管理,而不会影响最终生成的主题或WordPress文件夹。
  2. 最终构建的主题文件夹仅包含它所需的文件,没有开发文件。
  3. Gulp、插件和其他应用程序不包含在主题文件夹中。因此它们不会被意外的复制到生产服务器,这是没有必要的,而且可能会产生安全隐患。

项目的 src 文件夹还需要四个子文件夹:

  • template – WordPress PHP主题文件
  • images – 主题使用的图像
  • scss – SCSS源文件
  • js – JavaScript源文件。

最终开发目录结构大概如下:

~/mytheme/
    -src
    ---template
    ---images
    ---scss
    ---js
    -package.json
    -...

安装依赖项

在开发文件夹下(~/mytheme/)运行以下 npm 命令以安装gulp以及其插件和所有开发依赖项:

npm install --save-dev autoprefixer browser-sync css-mqpacker cssnano gulp gulp-concat gulp-deporder gulp-imagemin gulp-newer gulp-postcss gulp-sass gulp-strip-debug gulp-uglify gulp-util postcss-assets [email protected] babel-preset-env babel-preset-es2015 babelify browserify vinyl-buffer vinyl-source-stream

这个时候,在项目文件夹下将被创建 node_modules 文件夹,包含所有依赖。

创建Gulp配置文件

在源文件夹中创建新的gulpfile.js配置文件,并添加以下代码:

// Gulp.js config file

'use strict';

const 
    dir = {
        // 源文件和构建目录
        src:    'src/',
                // 注意:这里的路径需要根据自己的 wordpress 安装路径进行修改
        build:  '/var/www/wp-content/themes/mytheme/'
    },

    // Gulp 和 插件
    gulp        = require('gulp'),
    gutil       = require('gulp-util'),
    newer       = require('gulp-newer'),
    imagemin    = require('gulp-imagemin'),
    sass        = require('gulp-sass'),
    postcss     = require('gulp-postcss'),
    deporder    = require('gulp-deporder'),
    stripdebug  = require('gulp-strip-debug'),
    uglify      = require('gulp-uglify'),
    sourcemaps  = require('gulp-sourcemaps'),
    browserify  = require('browserify'),
    source      = require('vinyl-source-stream'),
    buffer      = require('vinyl-buffer'),
    babelify    = require('babelify')
;

// Browser sync
var browsersync = false;

// PHP
const php = {
    src:    dir.src + 'template/**/*.php',
    build:  dir.build
};

// 复制 PHP 文件
gulp.task('php', () => {
    return gulp.src(php.src)
        .pipe(newer(php.build))
        .pipe(gulp.dest(php.build));
});

我们定义了默认文件夹,加载模块,然后创建php任务以将新文件和更新的文件从源文件夹复制到主题文件夹。

保存gulpfile.js,并在 template 文件夹下创建一些.php文件。然后输入以下命令:

gulp php

所有 php 文件都将被复制到主题文件夹/var/www/wp-content/themes/mytheme/

图像处理

通常可以使用imagemin等工具进一步压缩图像文件。将以下代码添加到gulpfile.js:

// 图像处理
const images = {
    src:    dir.src + 'images/**/*',
    build:  dir.build + 'images/'
};

gulp.task('images', () => {
    return gulp.src(images.src)
        .pipe(newer(images.build))
        .pipe(imagemin())
        .pipe(gulp.dest(images.build));
});

保存然后运行gulp images。images任务将复制源文件夹下的images文件夹中任何新的图片或更新的图片的压缩版本到 /var/www/wp-content/themes/mytheme/images/ 中。

Scss编译

WordPress无法直接使用Sass文件; 你必须编译成一个style.css文件。将以下代码添加到gulpfile.js:

// Sass 编译
var css = {
    src:    dir.src + 'scss/style.scss',
    watch:  dir.src + 'scss/**/*',
    build:  dir.build,
    sassOpts: {
        outputStyle     : 'nested',
        imagePath       : images.build,
        precision       : 3,
        errLogToConsole : true
    },
    processors: [
        require('postcss-assets')({
            loadPaths: ['images/'],
            basePath: dir.build,
            baseUrl: '/wp-content/themes/mytheme/'
        }),
        require('autoprefixer')({
            browsers: ['last 2 versions', '> 2%']
        }),
        require('css-mqpacker'),
        require('cssnano')
    ]
};

gulp.task('css', gulp.series('images', () => {
    return gulp.src(css.src)
        .pipe(sass(css.sassOpts))
        .pipe(postcss(css.processors))
        .pipe(gulp.dest(css.build))
        .pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
}));

使用以下命令启动此新任务 gulp css

  • 首先运行Gulp images任务(CSS中可能需要图像)
  • scss/style.scss使用快速的 LibSass 编译器在源文件中编译Sass代码
  • 使用 PostCSS 自动添加资产的引用,添加浏览器前缀,将媒体查询代码打包在一起,并缩小生成的CSS代码
  • 将样式表输出到/var/www/wp-content/themes/mytheme/style.css
  • 强制执行Browsersync CSS重新加载(稍后会详细介绍)

scss/style.scss文件必须包含顶部的WordPress主题元数据,例如:

/*!
    Theme Name: My Theme
    Theme URI: https://www.cainiaofly.com/
    Description: Demonstration theme
    Version: 1.0.0
    Author: Maine
    Author URI: https://www.cainiaofly.com/
    Tags: Gulp,Wordpress

    License: MIT
    License URI: http://opensource.org/licenses/mit-license.php
*/

@import '_base';
@import '_forms';
@import '_tables';
@import 'components/_widget1';
// etc...

使用/*!作为第一行非常重要。这可以确保cssnano minifier不会删除注释以至于主题无法使用。

postcss-assets 插件可以让你使用代码来引用图像资源,如:

.widget1 {
  width: width('myimage.jpg');
  height: height('myimage.jpg');
  background-image: resolve('myimage.jpg');
}

您还可以使用自动Base64编码内联图像:

.widget2 {
  background-image: inline('myimage.jpg');
}

JavaScript处理

将以下代码添加到gulpfile.js:


// Javascript 的处理
const js = {
    src:        dir.src + 'js/**/*',
    build:      dir.build + 'js/',
    filename:   'scripts.js'
};

gulp.task('browserify', () => {
    return browserify({
        entries: js.entry,
        debug: true
    })
    .transform("babelify", {presets: ["es2015"]}).on('error', (error) => {
        gutil.log(gutil.colors.red('[Error]'), err.toString());
    })
    .bundle()
    .pipe(source(js.filename))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(js.build))
});

gulp.task('js', gulp.series('browserify', () => {
    return gulp.src(js.build + '/**/*.js')
        .pipe(deporder())
        // .pipe(stripdebug())
        .pipe(uglify())
        .pipe(gulp.dest(js.build))
        .pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
}));

另外,需要在项目文件夹中创建 .babelrc 文件,作为babel的配置文件,并添加如下内容:

{
    "presets": [
        "env",
        "es2015"
    ]
}

最后使用以下命令运行此新任务:gulp js

  • 处理源js文件夹中的所有JavaScript文件
  • 使用 Babel 进行 ES6 到 ES5 的转换
  • 适当地修改文件。在JavaScript文件的顶部添加注释以声明依赖项,例如// requires: lib1.js或// requires: config.js lib1.js。
  • 连接成一个文件
  • 去除所有调试和控制台记录语句(开发阶段可以先关闭)
  • 压缩代码
  • 将结果代码输出到/var/www/wp-content/themes/mytheme/js/scripts.js
  • 强制执行Browsersync CSS重新加载(稍后会详细介绍)。

运行所有任务

我们可以将以下代码添加到gulpfile.js:而不是单独调用每个任务:

gulp.task('build', gulp.parallel('php', 'css', 'js'));

您现在可以使用gulp build并行运行php,js,css和images任务。(注意images是css任务的依赖关系,所以我们不需要直接调用它。)

启用文件监视和浏览器同步

您的工作流程可以通过以下方式大幅改进

  1. 让Gulp在启动相应任务之前监视文件更改。
  2. 更改时自动重新加载CSS和JavaScript文件(无需刷新页面)。
  3. 模板文件更改时自动刷新页面。

首先,我们需要在gulpfile.js中定义一个browsersync任务。这将为运行WordPress的Web服务器创建代理服务器localhost(根据需要更改此域名或使用IP地址):


// Browser sync
const syncOpts = {
    // 你的WP运行在虚拟主机下,而且还绑定了一个自定义的域名,那么
    // localhost 也可以改成你运行wp的虚拟主机绑定的域名
    proxy:      'localhost',
    files:      dir.build + '**/*',
    open:       false,
    notify:     false,
    ghostMode:  false,
    ui: {
        port: 8001
    }
};

gulp.task('browsersync', () => {
    if(browsersync === false) {
        browsersync = require('browser-sync').create();
        browsersync.init(syncOpts);
    }
});

现在添加一个watch任务来运行Browsersync,监视文件更改并运行相应的任务:


// 监视
gulp.task('watch', gulp.parallel('browsersync', () => {
    console.log('watch......');
    // 页面改变
    gulp.watch(php.src, gulp.parallel('php')).on('change', () => {
        browsersync ? browsersync.reload : {};
    });

    // 图像改变
    gulp.watch(images.src, gulp.parallel('images')).on('change', browsersync ? browsersync.reload : gutil.noop);

    // css 改变
    gulp.watch(css.watch, gulp.parallel('css'));

    // js 改变
    gulp.watch(js.src, gulp.parallel('js')).on('change', browsersync ? browsersync.reload : gutil.noop);
}));

最后,添加一个default运行初始构建并启动watch任务的Gulp 任务:

// default task
gulp.task('default', gulp.series('build', 'watch'));

在从命令行运行gulp。控制台将显示类似以下的输出。

[BS] Proxying: http://localhost
[BS] Access URLs:
 -------------------------------------
       Local: http://localhost:3000
    External: http://192.168.1.103:3000
 -------------------------------------
          UI: http://localhost:8001
 UI External: http://192.168.1.103:8001
 -------------------------------------
[BS] Watching files...

这个时候你再查看你的 WordPress 站点就不要访问 http://localhost 了,而是访问http://localhost:3000 ,你的WordPress网站还将像以前一样被加载,但Gulp将监视更改并立即应用更新。你永远不需要切换到浏览器并再次单击刷新!

按Ctrl/Cmd + C键停止任务。

OK!!!

点赞
  1. 头条说道:

    文章不错非常喜欢 :redface:

  2. 头条新闻说道:

    文章不错非常喜欢,支持

  3. 焦大云系统说道:

    文章不错非常喜欢,支持

发表评论

电子邮件地址不会被公开。 必填项已用*标注