在 WordPress 的 Enqueue 函数中使用动态哈希文件名

Avatar of Pascal Klau (@pascalaoms)
Pascal Klau (@pascalaoms) 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

以下是来自 Pascal Klau 的客座文章,他自称是来自德国的 Web 开发培训生,使用 WordPress、Gulp,以及最近的 VueJS 和 Webpack。

在我学习 Web 技术的过程中,我偶然发现了文件缓存的重要性。对于网页性能来说,这是一件非常重要的事情。我也偶尔会注意到,当文件被修改后,刷新页面时,浏览器仍然可能使用旧版本(由于缓存)。有一个解决方案!

哈希打破缓存

在文件名中添加哈希值可以让浏览器认为它是一个完全不同的文件。从而“打破缓存”。例如,如果文件 `main.3hZ9.js` 更改为 `main.8a3s.js`,浏览器将肯定重新下载它。此重命名可以通过任务运行器自动完成。

但是对于我们这些使用 WordPress 的人来说,有一个问题。您需要按名称手动加载文件,但您无法知道随机生成的哈希值。

wp_enqueue_script('main', get_template_directory_uri() . '/js/main.3hZ9.js', array('jquery'), null, true);

使用 Gulp 添加哈希值

在我们解决 WordPress 问题之前,以下是添加哈希值的方法。

由于我使用的是 Gulp,gulp-hash 非常方便。如果您使用的是 Grunt,则有 等效项

// ES5
var gulp = require('gulp'),
    hash = require('gulp-hash');

var options = {
    hashLength: 4,
    template: '<%= name %>.<%= hash %><%= ext %>'
};

gulp.src('./js/**/*.js')
  .pipe(hash(options))
  .pipe(gulp.dest('build'));
// ES6 + Gulp 4
import gulp from 'gulp'
import hash from 'gulp-hash'

let options = {
  hashLength: 4,
  template: '<%= name %>.<%= hash %><%= ext %>'
};

export function hashing() {
  return gulp.src('./js/**/*.js')
    .pipe(hash(options))
    .pipe(gulp.dest('build'))
};

const dev = gulp.series(hashing);
export { dev };
export default dev;

WordPress 解决方案

以下是如何自动加载哈希文件!诀窍是我们不需要知道哈希名称,PHP 会找到文件。

首先,我们准备好 遍历文件系统 中我们的资源所在的目录。

function enqueue_files() {
  $dirJS = new DirectoryIterator(get_stylesheet_directory() . '/js');
}

现在我们遍历所有文件并筛选以 `.js` 结尾的文件。

foreach ($dirJS as $file) {

  if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {

  }

}

依赖项需要 WordPress 中的名称,因此我们可以根据文件名进行设置。“main” 比 “main.3hZ9” 更好(因为它不会改变),因此我们可以去除哈希值以获得加载名称。

foreach ($dirJS as $file) {

    if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
        $fullName = basename($file);    // main.3hZ9.js
        $name = substr(basename($fullName), 0, strpos(basename($fullName), '.')); // main
    }
}

在 WordPress 中,您加载的任何资源可能都需要依赖项。您可以通过将它们作为数组传递给加载函数来自行声明。在这里,我们正在检查文件并在需要时添加依赖项

foreach ($dirJS as $file) {

    if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
        $fullName = basename($file);
        $name = substr(basename($fullName), 0, strpos(basename($fullName), '.'));

        switch($name) {

            case 'main':
                $deps = array('vendor');
                break;

            default:
                $deps = null;               
                break;

        }
    }
}

现在全部放在一起!

我们现在拥有加载资源所需的一切,因此将其全部放在一起

foreach ($dirJS as $file) {

  if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
    $fullName = basename($file);
    $name = substr(basename($fullName), 0, strpos(basename($fullName), '.'));

    switch($name) {

        case 'main':
            $deps = array('vendor');
            break;

        default:
            $deps = null;               
            break;

    }

    wp_enqueue_script( $name, get_template_directory_uri() . '/js/' . $fullName, $deps, null, true );

  }

}

CSS 文件的工作方式相同,只是 WP 加载函数略有不同。

PHP filemtime 怎么样?

使用 WordPress,您可以在其加载函数中添加一个破坏缓存的 URL 参数,使用 filemtime。它会在每次修改文件时添加时间戳

$file = get_template_directory_uri() . '/js/main.js'
wp_enqueue_script( 'main', $file, null, filemtime($file), true );

// => [...]/main.js?1203291283

为什么我不使用此技术?

我将 JavaScript 文件捆绑到 `main.js` 和 `vendor.js` 中(在我的情况下,使用 Webpack)。当编辑 `main.js` 时,`vendor.js` 的时间戳也会发生变化。因此它将每次都被下载,而实际上并没有任何不同。

另一方面,哈希值保持不变。

结论

现在,您可以通过 Gulp 在文件更改时动态地向文件添加哈希值。并且您可以在 WordPress 中加载这些文件,而无需知道新文件名的目录。