首页 > 解决方案 > gulp-useref 找不到绝对路径

问题描述

我有这样的公共资源:

public/
    xyz/
        index.html
        js/
            a.js
            b.js
        css/
            a.css
            b.css

我想用来gulp-useref构建html,我改成index.html这个:

<!-- build:css /xyz/css/index.css -->
<link href="/xyz/css/a.css" rel="stylesheet" />
<link href="/xyz/css/b.css" rel="stylesheet" />
<!-- endbuild -->

<!-- build:js /xyz/js/index.js -->
<link href="/xyz/js/a.js" rel="stylesheet" />
<link href="/xyz/js/b.js" rel="stylesheet" />
<!-- endbuild -->

我这样写 gulp:

gulp.task("html", async function() {
    gulp.src("public/xyz/*.html")
    .pipe(useref())
    .pipe(gulpif("*.js", uglify()))
    .pipe(gulpif("*.css", cssMin()))
    .pipe(gulp.dest("dist/public/xyz"))
})

第一个问题是:useref 找不到absolute path: /xyz/js/a.js.

然后我尝试将 html 模板更改为:

<!-- build:css /xyz/css/index.css -->
<link href="css/a.css" rel="stylesheet" />
<link href="css/b.css" rel="stylesheet" />
<!-- endbuild -->

<!-- build:js /xyz/js/index.js -->
<link href="js/a.js" rel="stylesheet" />
<link href="js/b.js" rel="stylesheet" />
<!-- endbuild -->

它运行正常,然后出现第二个问题,useref产生冗余xyz目录:

dist/
    public/
        xyz/
            index.html
            xyz/
                js/
                    a.js
                    b.js
                css/
                    a.css
                    b.css

标签: javascriptgulpgulp-useref

解决方案


假设您希望目录输出如下所示:

dist/
    xyz/
        index.html
        js/
            a.js
            b.js
        css/
            a.css
            b.css

然后,您需要执行以下操作:

  1. 更改源 glob 以影响资产根路径中的所有 html。在这种情况下,它将是public
  2. 使用gulp-useref#transformPath选项,该选项提供了自定义资产路径分辨率的机制。

这是下面代码的repl.it

const gulp = require('gulp');
const gulpIf = require('gulp-if');
const useref = require('gulp-useref');
const uglify = require('gulp-uglify');
const minifyCss = require('gulp-clean-css');

const path = require('path');

const ABS_PATH_INDICATOR = `${path.sep}${path.sep}`;

gulp.task('html', async function () {
    gulp.src('public/**/*.html')
        .pipe(
            useref({
                transformPath(assetPath) {
                    // an absolute path asset will have a file path
                    // that has two separators in the path
                    // e.g. <script src="/xyz/js/a.js"></script> will have
                    // /home/<rootpath>/<project-path>/public/xyz//xyz/js/a.js

                    // is this path using an absolute path as an asset?
                    if (assetPath.includes(ABS_PATH_INDICATOR)) {
                        // get the absolute path
                        const absPath = assetPath
                            .split(ABS_PATH_INDICATOR)
                            .pop();

                        // resolve the path properly
                        return path.resolve(path.join('public', absPath));
                    }

                    // else return the path properly
                    return assetPath;
                },
            })
        )
        .pipe(gulpIf('*.js', uglify()))
        .pipe(gulpIf('*.css', minifyCss()))
        .pipe(gulp.dest('dist'));
});

推荐阅读