ค้นหาเว็บไซต์

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*/
        }
    }
}

บทความที่เกี่ยวข้อง