Skip to content

Commit

Permalink
chore: remove cdn_system.version
Browse files Browse the repository at this point in the history
  • Loading branch information
MHuiG committed Aug 19, 2022
1 parent 324a75a commit 6318b27
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 161 deletions.
4 changes: 0 additions & 4 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ default:
############################### CDN System ###############################

cdn_system:
# 静态资源版本控制
# 本地文件使用文件内容的hash值作为版本号(app.8c1e7c88.js)
# 建议静态资源设置标头 浏览器缓存一年边缘缓存一个月 cache-control: max-age=86400, s-maxage=31536000 如果有更新记得刷新缓存
version: true
# ========================================================================
# cdn数据配置文件见 "theme/_cdn.yml", 可以在 source/_data/cdn.yml 覆盖 theme/_cdn.yml
# 变量说明:
Expand Down
321 changes: 164 additions & 157 deletions scripts/helpers/revisioned.js
Original file line number Diff line number Diff line change
@@ -1,167 +1,174 @@
// hexo g 执行 hexo s 跳出

// https://blog.imkero.com/posts/hexo-page-performance.html#静态资源版本控制


const minimatch = require("minimatch");
const crypto = require('crypto');

const stream2buffer = (stream) => {
if(!stream) return;
return new Promise((resolve, reject) => {
const _buf = [];
stream.on("data", (chunk) => _buf.push(chunk));
stream.on("end", () => resolve(Buffer.concat(_buf)));
stream.on("error", (err) => reject(err));
});
};

const readFileAsBuffer = (filePath) => {
return stream2buffer(hexo.route.get(filePath));
};

const readFileAsString = async (filePath) => {
const buffer = await readFileAsBuffer(filePath);
return buffer.toString();
};

const parseFilePath = (filePath) => {
const parts = filePath.split("/");
const originalFileName = parts[parts.length - 1];

const dotPosition = originalFileName.lastIndexOf(".");

const dirname = parts.slice(0, parts.length - 1).join("/");
const basename =
dotPosition === -1
? originalFileName
: originalFileName.substring(0, dotPosition);
const extension =
dotPosition === -1 ? "" : originalFileName.substring(dotPosition);

return [dirname, basename, extension];
};

const genFilePath = (dirname, basename, extension) => {
let dirPrefix = "";
if (dirname) {
dirPrefix += dirname + "/";
}

if (extension && !extension.startsWith(".")) {
extension = "." + extension;
}

return dirPrefix + basename + extension;
};

const getRevisionedFilePath = (filePath, revision) => {
const [dirname, basename, extension] = parseFilePath(filePath);
return genFilePath(dirname, `${basename}.${revision}`, extension);
};

const revisioned = (filePath) => {
if (!hexo.theme.config.cdn_system.version) {
return filePath;
}
let arg = process.argv[2];
if (arg == "s" || arg == "server") {
return filePath
}
return getRevisionedFilePath(filePath, `!!revision:${filePath}!!`);
};

hexo.extend.helper.register("revisioned", revisioned);

const calcFileHash = async (filePath) => {
if (hexo.route.get(filePath)) {
const buffer = await stream2buffer(hexo.route.get(filePath));
const fileHash = crypto.createHash("md5").update(buffer).digest('hex').substring(0, 8);
return fileHash;
} else {
// 随机生成 hash
return crypto.randomBytes(16).toString('hex').substring(0, 8);
}

};

const replaceRevisionPlaceholder = async () => {

if (!hexo.theme.config.cdn_system.version) {
return;
}
try {
const options = hexo.config.new_revision || {};
const include = options.include || [];
// // hexo g 执行 hexo s 跳出

// // https://blog.imkero.com/posts/hexo-page-performance.html#静态资源版本控制


// const minimatch = require("minimatch");
// const crypto = require('crypto');

// const stream2buffer = (stream) => {
// if(!stream) return;
// return new Promise((resolve, reject) => {
// const _buf = [];
// stream.on("data", (chunk) => _buf.push(chunk));
// stream.on("end", () => resolve(Buffer.concat(_buf)));
// stream.on("error", (err) => reject(err));
// });
// };

// const readFileAsBuffer = (filePath) => {
// return stream2buffer(hexo.route.get(filePath));
// };

// const readFileAsString = async (filePath) => {
// const buffer = await readFileAsBuffer(filePath);
// return buffer.toString();
// };

// const parseFilePath = (filePath) => {
// const parts = filePath.split("/");
// const originalFileName = parts[parts.length - 1];

// const dotPosition = originalFileName.lastIndexOf(".");

// const dirname = parts.slice(0, parts.length - 1).join("/");
// const basename =
// dotPosition === -1
// ? originalFileName
// : originalFileName.substring(0, dotPosition);
// const extension =
// dotPosition === -1 ? "" : originalFileName.substring(dotPosition);

// return [dirname, basename, extension];
// };

// const genFilePath = (dirname, basename, extension) => {
// let dirPrefix = "";
// if (dirname) {
// dirPrefix += dirname + "/";
// }

// if (extension && !extension.startsWith(".")) {
// extension = "." + extension;
// }

// return dirPrefix + basename + extension;
// };

// const getRevisionedFilePath = (filePath, revision) => {
// const [dirname, basename, extension] = parseFilePath(filePath);
// return genFilePath(dirname, `${basename}.${revision}`, extension);
// };

// const revisioned = (filePath) => {
// if (!hexo.theme.config.cdn_system.version) {
// return filePath;
// }
// let arg = process.argv[2];
// if (arg == "s" || arg == "server") {
// return filePath
// }
// return getRevisionedFilePath(filePath, `!!revision:${filePath}!!`);
// };

// hexo.extend.helper.register("revisioned", revisioned);

// const calcFileHash = async (filePath) => {
// if (hexo.route.get(filePath)) {
// const buffer = await stream2buffer(hexo.route.get(filePath));
// const fileHash = crypto.createHash("md5").update(buffer).digest('hex').substring(0, 8);
// return fileHash;
// } else {
// // 随机生成 hash
// return crypto.randomBytes(16).toString('hex').substring(0, 8);
// }

// };

// const replaceRevisionPlaceholder = async () => {
// console.log(hexo.theme.config.cdn_system.version);
// if (!hexo.theme.config.cdn_system.version) {
// return;
// }
// try {
// const options = hexo.config.new_revision || {};
// const include = options.include || [];

const hashPromiseMap = {};
const hashMap = {};
const doHash = (filePath) =>
calcFileHash(filePath).then((hash) => {
hashMap[filePath] = hash;
});
// const hashPromiseMap = {};
// const hashMap = {};
// const doHash = (filePath) =>
// calcFileHash(filePath).then((hash) => {
// hashMap[filePath] = hash;
// });

await Promise.all(
hexo.route.list().map(async (path) => {
const [, , extension] = parseFilePath(path);
if (![".css", ".js", ".html"].includes(extension)) {
return;
}
// await Promise.all(
// hexo.route.list().map(async (path) => {
// const [, , extension] = parseFilePath(path);
// if (![".css", ".js", ".html"].includes(extension)) {
// return;
// }

let fileContent = await readFileAsString(path);
// let fileContent = await readFileAsString(path);

const regexp = /\.!!revision:([^\)]+?)!!/g;
const matchResult = [...fileContent.matchAll(regexp)];
if (matchResult.length) {
const hashTaskList = [];
// const regexp = /\.!!revision:([^\)]+?)!!/g;
// const matchResult = [...fileContent.matchAll(regexp)];
// if (matchResult.length) {
// const hashTaskList = [];

// 异步获取文件 hash
matchResult.forEach((group) => {
const filePath = group[1];
if (!(filePath in hashPromiseMap)) {
hashPromiseMap[filePath] = doHash(filePath);
}
hashTaskList.push(hashPromiseMap[filePath]);
});
// // 异步获取文件 hash
// matchResult.forEach((group) => {
// const filePath = group[1];
// if (!(filePath in hashPromiseMap)) {
// hashPromiseMap[filePath] = doHash(filePath);
// }
// hashTaskList.push(hashPromiseMap[filePath]);
// });

// 等待全部 hash 完成
await Promise.all(hashTaskList);
// // 等待全部 hash 完成
// await Promise.all(hashTaskList);

// 替换 placeholder
fileContent = fileContent.replace(regexp, function (match, filePath) {
if (!(filePath in hashMap)) {
throw new Error("file hash not computed");
}
return "." + hashMap[filePath];
});
// // 替换 placeholder
// fileContent = fileContent.replace(regexp, function (match, filePath) {
// if (!(filePath in hashMap)) {
// throw new Error("file hash not computed");
// }
// return "." + hashMap[filePath];
// });

hexo.route.set(path, fileContent);
}
})
);
// hexo.route.set(path, fileContent);
// }
// })
// );

await Promise.all(
hexo.route.list().map(async (path) => {
for (let i = 0, len = include.length; i < len; i++) {
if (minimatch(path, include[i])) {
return doHash(path);
}
}
})
);
// await Promise.all(
// hexo.route.list().map(async (path) => {
// for (let i = 0, len = include.length; i < len; i++) {
// if (minimatch(path, include[i])) {
// return doHash(path);
// }
// }
// })
// );

await Promise.all(
Object.keys(hashMap).map(async (filePath) => {
hexo.route.set(
getRevisionedFilePath(filePath, hashMap[filePath]),
await readFileAsBuffer(filePath)
);
hexo.route.remove(filePath);
})
);
} catch (error) {
hexo.log.error("cdn_version ERROR: " + error);
}
};

hexo.extend.filter.register("after_generate", replaceRevisionPlaceholder,9999);
// await Promise.all(
// Object.keys(hashMap).map(async (filePath) => {
// hexo.route.set(
// getRevisionedFilePath(filePath, hashMap[filePath]),
// await readFileAsBuffer(filePath)
// );
// hexo.route.remove(filePath);
// })
// );
// } catch (error) {
// hexo.log.error("cdn_version ERROR: " + error);
// }
// };

// hexo.extend.filter.register("after_generate", replaceRevisionPlaceholder,9999);


// cdn_system:
// # 静态资源版本控制
// # 本地文件使用文件内容的hash值作为版本号(app.8c1e7c88.js)
// # 建议静态资源设置标头 浏览器缓存一年边缘缓存一个月 cache-control: max-age=86400, s-maxage=31536000 如果有更新记得刷新缓存
// version: true

0 comments on commit 6318b27

Please sign in to comment.