實(shí)現(xiàn)構(gòu)建工具之打包改進(jìn)

最近查看browserify源碼在扰,發(fā)現(xiàn)其沒有用eval和new Function痢虹,原因如下:
確保browserify的安裝使用了語(yǔ)法-error@1.1.1或 后來(lái)存在一個(gè)安全漏洞,惡意文件可能會(huì) 瀏覽時(shí)執(zhí)行代碼悬钳。 該漏洞涉及破壞用于 檢查語(yǔ)法以了解更多信息性錯(cuò)誤昨登。在節(jié)點(diǎn)0.10中,Function()以“eval()”的形式實(shí)現(xiàn)障般,這樣惡意代碼甚至可以執(zhí)行 如果從未調(diào)用“function()”返回的函數(shù)调鲸。節(jié)點(diǎn)0.11確實(shí)如此 似乎不易受攻擊。 多虧了Cal Leeming[cal@iops.io] 感謝你發(fā)現(xiàn)并揭露這個(gè)錯(cuò)誤挽荡!

經(jīng)過(guò)一番思考藐石,發(fā)現(xiàn)之前 重寫的browserify也可以改進(jìn)為不使用eval和new Function
改進(jìn)代碼如下:
browserify.js

const fs = require("fs");
const { resolve } = require("path");

const moduleFuncCache = [];
let curIndex = 0;

//記錄path和數(shù)組對(duì)應(yīng)資源數(shù)組位置
const pathIndexMap = {};
const codeSplicing = (path) => {
  // 獲取絕對(duì)路徑
  const wholePath = resolve(path);

  if (pathIndexMap[wholePath] !== undefined) return;

  const text = fs
    .readFileSync(wholePath, "utf-8")
    .trim()
    .replace(/require/g, "_require")
    .replace(/_require\(['\"](.*)['\"]\)/g, function (matched, $1) {
      codeSplicing($1);
      return `_require(${pathIndexMap[resolve($1)]})`;
    })
    .replace(/;$/, "");

  moduleFuncCache.push(`
    function(){
      const module = {exports:{}};
      let {exports} = module;
      ${text}
      return module.exports
    }
  `);
  pathIndexMap[wholePath] = curIndex++;
};

const getCode = () => {
  // eval方式轉(zhuǎn)函數(shù)
  return `
        // 自執(zhí)行函數(shù),避免全局污染
        (function(){
            const moduleCache = []
            const _require = function(index){
                // 第一次引用該模塊則執(zhí)行定拟,后續(xù)從緩存中取
                if(!moduleCache[index]) moduleCache[index] = formatModuleFuncCache[index]()
                return moduleCache[index]
            }

            //數(shù)組收集于微,省去了json序列化的過(guò)程,從而省去轉(zhuǎn)碼的過(guò)程
            const formatModuleFuncCache = [${moduleFuncCache}]

            //執(zhí)行入口文件代碼
            formatModuleFuncCache[${moduleFuncCache.length - 1}]()
        })()
    `;
};

//主函數(shù),傳入文件路徑青自,返回最終打包完成的代碼塊
const browserify = (path) => {
  // 為每個(gè)require的模塊拼接代碼株依,為其提供module實(shí)例,并返回module.exports
  codeSplicing(path);

  // 阻止代碼延窜,使其能解析代碼cache對(duì)象恋腕,并依照引入順序來(lái)執(zhí)行代碼塊
  return getCode();
};

// 執(zhí)行命令行傳入打包源文件 node ./browserify.js index.js,此時(shí)path即index.js
const [path] = process.argv.splice(2);
// 寫目標(biāo)文件;
fs.writeFileSync("./chunk.js", browserify(path));

能夠改進(jìn)的核心原因是:

  • 對(duì)象不方便轉(zhuǎn)字符串逆瑞,需要借助json
  • json對(duì)中文解析能力弱荠藤,需要轉(zhuǎn)碼,而函數(shù)代碼轉(zhuǎn)碼就需要在chunk中轉(zhuǎn)回來(lái)呆万,則被動(dòng)地必須使用eval或者new Function
  • 數(shù)組很方便轉(zhuǎn)化成代碼字符串商源,不需要經(jīng)過(guò)上述流程

代碼地址:https://github.com/a793816354/myBrowserify/tree/arr

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末车份,一起剝皮案震驚了整個(gè)濱河市谋减,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扫沼,老刑警劉巖出爹,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異缎除,居然都是意外死亡严就,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門器罐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)梢为,“玉大人,你說(shuō)我怎么就攤上這事轰坊≈” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵肴沫,是天一觀的道長(zhǎng)粟害。 經(jīng)常有香客問(wèn)我,道長(zhǎng)颤芬,這世上最難降的妖魔是什么悲幅? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任套鹅,我火速辦了婚禮,結(jié)果婚禮上汰具,老公的妹妹穿的比我還像新娘卓鹿。我一直安慰自己,他們只是感情好郁副,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布减牺。 她就那樣靜靜地躺著,像睡著了一般存谎。 火紅的嫁衣襯著肌膚如雪拔疚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天既荚,我揣著相機(jī)與錄音稚失,去河邊找鬼。 笑死恰聘,一個(gè)胖子當(dāng)著我的面吹牛句各,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晴叨,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凿宾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了兼蕊?” 一聲冷哼從身側(cè)響起初厚,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孙技,沒想到半個(gè)月后产禾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牵啦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年亚情,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哈雏。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡楞件,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出裳瘪,到底是詐尸還是另有隱情土浸,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布盹愚,位于F島的核電站栅迄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏皆怕。R本人自食惡果不足惜毅舆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一西篓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧憋活,春花似錦岂津、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至辜梳,卻和暖如春粱甫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背作瞄。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工茶宵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宗挥。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓乌庶,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親契耿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞒大,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容