Repository navigation
Expand file tree
/
Copy pathtransform.js
More file actions
94 lines (80 loc) · 2.72 KB
/
Copy pathtransform.js
File metadata and controls
94 lines (80 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
const less = require('less');
const babel = require('@babel/core');
const path = require('path');
const fs = require('fs');
const MD5 = require('crypto-js/md5');
const terser = require('terser');
async function replaceAsync(str, reg, replacer) {
const matches = [...str.matchAll(reg)];
let tempStr = str;
for (let i = 0; i < matches.length; i++) {
const matchItem = matches[i];
const newText = await replacer(...matchItem);
tempStr = tempStr.replace(matchItem[0], newText);
}
return tempStr;
}
async function transformLess(code, options) {
const reg =
/( *)(style\(lang="less"\)\.)((?:(\r?\n)(?:\1 +.+)?)+)\r?\n(?:\1 +)?/g;
async function replacer(matchText, empty, blockTag, lessCode, crlf) {
const blank = /\r?\n( +)/.exec(lessCode)?.[1] ?? '';
const res = await less.render(lessCode, {
...options.less,
compress: options.compress,
paths: [options.root],
});
const css = res.css.trim().replace(/^( *)/gm, `${blank}$1`);
return empty + `${blockTag}${crlf}${css}${crlf}`;
}
return replaceAsync(code, reg, replacer);
}
function transformJs(code, options) {
const reg = /( *)(script\.)((?:(\r?\n)(?:\1 +.+)?)+)\r?\n(?:\1)?/g;
async function replacer(matchText, empty, blockTag, sourceCode, crlf) {
const blank = /\r?\n( +)/.exec(sourceCode)?.[1] ?? '';
const res = babel.transformSync(sourceCode, {
presets: ['@babel/preset-env'],
...options.babel,
root: options.root,
});
let jsCode = res.code;
if (options.compress) {
jsCode = (await terser.minify(jsCode)).code;
}
jsCode = jsCode.trim().replace(/^( *)/gm, `${blank}$1`);
return empty + `${blockTag}${crlf}${jsCode}${crlf}`;
}
return replaceAsync(code, reg, replacer);
}
function transformUrlHash(code, options) {
const reg = /(src|href)="(.*?\?.*?v=)\{hash\}"/g;
function replacer(matchText, attrName, urlunholder) {
const pureUrlPath = urlunholder.slice(0, urlunholder.indexOf('?'));
const filename = path.join(
options.root,
options.mapHashUrl?.(pureUrlPath) ?? pureUrlPath
);
if (fs.existsSync(filename)) {
const hash = MD5(fs.readFileSync(filename, 'utf-8')).toString();
return attrName + `="${urlunholder}${hash.slice(0, 10)}"`;
}
return matchText;
}
return code.replace(reg, replacer);
}
/**
*
* @param {*} code
* @param {*} options
*/
async function transform(code, options) {
options ??= {};
options.root ??= process.cwd();
let transformedCode = code;
transformedCode = await transformLess(transformedCode, options);
transformedCode = await transformJs(transformedCode, options);
transformedCode = await transformUrlHash(transformedCode, options);
return transformedCode;
}
module.exports = transform;