有4种不同的URL类型;
http://www.example.com/images/icons.png../images/icons.png/images/icons.png//www.example.com/images/icons.png我有一个大型的静态文件站点(html,css,js),它是用拼图构建的。这个框架采用PHP模板并将它们编译成静态HTML。我还使用Gulp任务来编译资产(sass,js..etc)。
使用Jigsaw的构建过程,我可以使用完整的绝对路径/urls (http://example.com/path-to/page)或根相关(/path-to/page)构建站点。
这很好,但是现在客户端希望站点使用文档相对,因为它们现在将站点托管在子目录中,URL指向该子目录。
例如,http://example.com将指向http://xx.server.com/hosted-files/directory
我的问题是Jigsaw不允许文档相关的URL。是否有一个gulp/node脚本可以用来转换所有引用(图像源、链接、css paths..etc)?或者还有其他解决方案(例如使用.htacccess)?
TLDR;
我需要用文档相对路径和URL替换多个HTML文件和目录中的任何绝对引用或根相对引用。或者还有其他解决方案(例如使用.htacccess)?
发布于 2018-04-04 15:05:49
我已经设法解决了我自己的问题,我觉得这是一个“无趣”的解决办法。
我基本上已经创建了一个定制的gulp插件,用文档相关路径替换URL/ paths.等等。
gulpfile.js - relative-urls任务在所有其他任务完成后运行。
const relative = require('./tasks/document-relative');
gulp.task('relative-urls', function() {
return gulp.src('build/**/*.html')
.pipe( relative({
directory: 'build',
url: 'http://localhost:8000',
}) )
.pipe( gulp.dest('build') );
});./tasks/document-relative.js插件
'use strict';
const fs = require('fs');
const PluginError = require('plugin-error');
const through = require('through2');
const PLUGIN_NAME = 'document-relative';
let count = 0;
module.exports = function(options) {
// Remove slashes from beginning and end of string
const strip_slashes = (string) => {
return string ? string.replace(/^\/|\/$/g, '') : null;
}
// Users options object
options = options || {};
// Cleanup options
const base_dir = strip_slashes(options.directory);
const url = strip_slashes(options.url) + '/';
return through({
objectMode: true,
writable: true,
readable: true
},
function(file, enc, callback) {
count++;
// Check for null file
if (file.isNull()) {
return callback(null, file);
}
if (file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Stream not supported!'));
return callback(null, file);
}
if (file.isBuffer()) {
// Get contents of this file
let html = file.contents.toString(enc);
// This files full path (/home/usr/project/build/page/example/index.html)
const path = file.path;
// Path task was run from (/home/usr/project/)
const cwd = file.cwd+( base_dir ? '/'+base_dir : '' );
// Project specific path (/page/example/index.html)
const relative = path.replace(cwd, '');
// Get array of directories ['page', 'example', 'index.html']
let paths = strip_slashes(relative).split('/');
// Remove last item ['page', 'example']
paths.pop();
// Add ../ for nth number of paths in array
let rel_path = paths.length === 0 ? '' : ('../'.repeat(paths.length));
// Replace dom attributes (e.g. href="/page/example")
html = html.replace( /(?:(?!="\/\/)="\/)/g, '="'+rel_path );
// Replace inline background (e.g. background: url('/image/something.jpg'))
html = html.replace( /url\(\'\//g, 'url(\''+rel_path );
html = html.replace( /url\('\//g, 'url(''+rel_path );
// If user defined URL, match and remove
if (url && url.length) {
html = html.replace( new RegExp(url, 'g'), rel_path );
}
// Overwrite file
fs.writeFileSync(file.path, html, {
encoding: enc,
flag:'w'
});
return callback();
}
});
};这基本上会打开构建文件夹中的所有.html文件,计算每个文件的深度路径(/ folder 1/folder 2/index.html),并将url (http://localhost:8000)的任何实例替换为为计算出的路径数重复的../。
发布于 2020-11-12 23:44:06
节点具有path.relative。
url和directory的来源。const path = require("path");
// create a regular expression from your url property.
const domain_expression = new RegExp(url);
// Once you have an offending 'href' you can do this.
// - Here 'href' is Absolute, but this same code would work
// with Root-Relative paths too.
const href = "http://localhost:8000/images/icons.png";
const file_index = href.lastIndexOf("/") + 1;
const file_component = href.substring(file_index);
const root_relative = href.replace(domain_expression, "");
const relative_href = path.relative(`${directory}/${root_relative}`, directory);
const _href = relative_href + file_component;
// _href = ../../icons.pnghttps://stackoverflow.com/questions/49650419
复制相似问题