javascript - Terser: เพิ่มคำนำหน้ากับตัวแปรและฟังก์ชันที่ถูกบีบอัดทั้งหมด
ฉันกำลังทำงานกับสคริปต์ไฟล์เดียวที่มีไว้เพื่อรวมในหน้าเว็บผ่านแท็ก <script> ซึ่งกำลังถูกสร้างด้วย Vite.js โดยใช้ Terser minifier
หลังจากทำการเปลี่ยนแปลง ฉันสังเกตเห็นว่ารุ่นที่สร้างขึ้นของสคริปต์ของฉันทันใดนั้นเกิดข้อผิดพลาดทุกครั้งที่ฉันเรียกใช้โค้ด Google Analytics
หลังจากที่ทำการค้นคว้าบ้าง ฉันสังเกตว่าแพ็กเกจอื่นๆ บนเว็บไซต์ที่ฉันกำลังใส่สคริปต์นั้นกำลังเรียกฟังก์ชันที่ชื่อว่า ga() ข้อผิดพลาดเกิดขึ้นเพราะ Terser กำลังบีบอัด/ปรับชื่อฟังก์ชันในสคริปต์ของฉันและตั้งชื่อมันเป็น ga() ซึ่งแล้วจะไปขัดแย้งกับฟังก์ชันอื่นที่ฉันไม่สามารถควบคุมได้
ฉัน สมมติ ว่า Terser จะมีตัวเลือกในการหรือไม่ก็ได้
- ไม่ทำให้เป็นชื่อเฉพาะ
- เติมคำนำหน้าทุกฟังก์ชันที่ถูกทำให้ยุ่งเหยิง
แต่ดูเหมือนว่ามันจะไม่มีทั้งสองอย่าง
ฉันสามารถแก้ปัญหาได้โดยการเพิ่มสิ่งต่อไปนี้ลงในการตั้งค่าของฉัน:
minify: "terser",
terserOptions: {
keep_fnames: true,
},
ซึ่งทำให้ Terser หยุดการบิดเบือนชื่อฟังก์ชันใด ๆ ทั้งหมด แต่ชัดเจนว่านี่ไม่ดีนักเพราะมันกำลังเสียโอกาสมากมายสำหรับการย่อรหัส
มีวิธีใดบ้างที่จะบอก Terser ให้ยังคงบิดฟังก์ชันทั้งหมด แต่ทำเช่นนั้นโดยเพิ่มคำนำหน้า เช่น a_ ด้วย?
คำตอบ #1
คุณสามารถใช้ mangle.nth_identifier เพื่อสร้างชื่อด้วยตัวเองตั้งแต่เริ่มต้น และรวมคำนำหน้าในชื่อนั้น ๆ การใช้โค้ดนี้และ base54Prefix(prefix) สำหรับ mangle.nth_identifier ควรได้ผล
// adapted from base54 https://github.com/terser/terser/blob/master/lib/scope.js
const base54Prefix = ((prefix) => {
const leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
const digits = "0123456789".split("");
let chars;
let frequency;
function reset() {
frequency = new Map();
leading.forEach(function(ch) {
frequency.set(ch, 0);
});
digits.forEach(function(ch) {
frequency.set(ch, 0);
});
}
function consider(str, delta) {
for (var i = str.length; --i >= 0;) {
frequency.set(str[i], frequency.get(str[i]) + delta);
}
}
function compare(a, b) {
return frequency.get(b) - frequency.get(a);
}
function sort() {
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
}
// Ensure this is in a usable initial state.
reset();
sort();
function base54(num) {
var ret = "", base = 54;
num++;
do {
num--;
ret += chars[num % base];
num = Math.floor(num / base);
base = 64;
} while (num > 0);
return prefix + ret;
}
return {
get: base54,
consider,
reset,
sort
};
});
function mergeSort(array, cmp) {
if (array.length < 2) return array.slice();
function merge(a, b) {
var r = [], ai = 0, bi = 0, i = 0;
while (ai < a.length && bi < b.length) {
cmp(a[ai], b[bi]) <= 0
? r[i++] = a[ai++]
: r[i++] = b[bi++];
}
if (ai < a.length) r.push.apply(r, a.slice(ai));
if (bi < b.length) r.push.apply(r, b.slice(bi));
return r;
}
function _ms(a) {
if (a.length <= 1)
return a;
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
left = _ms(left);
right = _ms(right);
return merge(left, right);
}
return _ms(array);
}
คำตอบ #2
ใช่ คุณสามารถทำได้ด้วย regex คุณสามารถตรวจสอบโพสต์นี้หรือไปที่ mangle.properties เพื่อดูเอกสารอย่างครบถ้วน
terserOptions: {
mangle: {
properties: {
regex: /(^P1|^p1|^_p1)[A-Z]\w*/
}
}
}
