Rollup 基礎(chǔ)知識(shí)(2)

Design-Build.jpg

Rollup 官網(wǎng)

rollupjs.jpg

我們來(lái)看一看 vue 是使用了 Rollup 進(jìn)行打包項(xiàng)目的抗斤。通過(guò) npm 創(chuàng)建一個(gè)項(xiàng)目,然后創(chuàng)建 script.js 或者 index.js 文件愈魏,來(lái)作為可執(zhí)行的腳步文件碌补,首先我們需要引入所需要庫(kù)后添。

今天我們就 vue 打包的源碼分析來(lái)看一看 rollup 在 vue 中應(yīng)用蔚约。


th (1).jpeg
const fs = require('fs')
const path = require('path')
const rollup = require('rollup')
const terser = require('terser')

fs 和 path 是 nodejs 提供有關(guān)文件操作和路徑解析的包娇澎, rollup 和 terser 是用于構(gòu)建打包項(xiàng)目庫(kù)逐工,當(dāng)然這里 rollup 使我們今天主角描融。如果不存在 dist 文件夾我們就創(chuàng)建一個(gè)别智。

if (!fs.existsSync('dist')) {
    fs.mkdirSync('dist')
}

接下來(lái)讀取 config 這個(gè)配置文件,

let builds = require('./config').getAllBuilds()
if (process.env.TARGET) {
  module.exports = genConfig(process.env.TARGET)
} else {
  exports.getBuild = genConfig
  //通常我們會(huì)調(diào)用這個(gè)
  exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}

這里輸出 getAllBuilds 是返回一個(gè)方法稼稿,方法Object.keys 獲取對(duì)象的屬性集合薄榛,

var foo = {name:'koo',age:23}
undefined
Object.keys(foo)
(2) ["name", "age"]
Object.keys(foo).map(function(item){ console.log(foo[item])})
VM493:1 koo
VM493:1 23

用 genConfig 為每個(gè)要打包module輸出配置

function genConfig (name) {
  const opts = builds[name]
  const config = {
    input: opts.entry,
    external: opts.external,
    plugins: [
      flow(),
      alias(Object.assign({}, aliases, opts.alias))
    ].concat(opts.plugins || []),
    output: {
      file: opts.dest,
      format: opts.format,
      banner: opts.banner,
      name: opts.moduleName || 'Vue'
    },
    onwarn: (msg, warn) => {
      if (!/Circular/.test(msg)) {
        warn(msg)
      }
    }
  }

  // built-in vars
  // const vars = {
  //   __WEEX__: !!opts.weex,
  //   __WEEX_VERSION__: weexVersion,
  //   __VERSION__: version
  // }
  // feature flags
  // Object.keys(featureFlags).forEach(key => {
  //   vars[`process.env.${key}`] = featureFlags[key]
  // })
  // build-specific env
  // if (opts.env) {
  //   vars['process.env.NODE_ENV'] = JSON.stringify(opts.env)
  // }
  // config.plugins.push(replace(vars))

  if (opts.transpile !== false) {
    config.plugins.push(buble())
  }

  Object.defineProperty(config, '_name', {
    enumerable: false,
    value: name
  })

  return config
}

這里主要是返回一個(gè) rollup 在構(gòu)建項(xiàng)目所用的配置文件,簡(jiǎn)單地解釋一下 config 各個(gè)屬性让歼,

  • input 輸入文件

  • plugins 插件敞恋,vue 開(kāi)始使用 flow 來(lái)作為自己類(lèi)型系統(tǒng)的,alias 方法
    -i, --input 要打包的文件(必須)
    -o, --output.file 輸出的文件 (如果沒(méi)有這個(gè)參數(shù)谋右,則直接輸出到控制臺(tái))
    -f, --output.format [es] 輸出的文件類(lèi)型 (amd, cjs, es, iife, umd)
    -e, --external 將模塊ID的逗號(hào)分隔列表排除
    -g, --globals 以module ID:Global 鍵值對(duì)的形式硬猫,用逗號(hào)分隔開(kāi)
    任何定義在這里模塊ID定義添加到外部依賴(lài)
    -n, --name 生成UMD模塊的名字
    -m, --sourcemap 生成 sourcemap (-m inline for inline map)
    --amd.id AMD模塊的ID,默認(rèn)是個(gè)匿名函數(shù)
    --amd.define 使用Function來(lái)代替define
    --no-strict 在生成的包中省略"use strict";
    --no-conflict 對(duì)于UMD模塊來(lái)說(shuō)改执,給全局變量生成一個(gè)無(wú)沖突的方法
    --intro 在打包好的文件的塊的內(nèi)部(wrapper內(nèi)部)的最頂部插入一段內(nèi)容
    --outro 在打包好的文件的塊的內(nèi)部(wrapper內(nèi)部)的最底部插入一段內(nèi)容
    --banner 在打包好的文件的塊的外部(wrapper外部)的最頂部插入一段內(nèi)容
    --footer 在打包好的文件的塊的外部(wrapper外部)的最底部插入一段內(nèi)容
    --interop 包含公共的模塊(這個(gè)選項(xiàng)是默認(rèn)添加的

  • Object.defineProperty 將 name 作為 _name 屬性寫(xiě)入到 config 對(duì)象中并且為不可遍歷啸蜜。

根據(jù) name 獲取 opts, 就是 web-runtime-cjs-dev屬性值,opts 對(duì)象提供壓縮web-runtime-cjs-dev基本信息辈挂。我們可以將每個(gè)屬性和上面函數(shù)進(jìn)行對(duì)應(yīng)衬横。

const builds = {
  // Runtime only (CommonJS). Used by bundlers e.g. Webpack & Browserify
  'web-runtime-cjs-dev': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/zi.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
  }
}
const aliases = require('./alias')
const resolve = p => {
  const base = p.split('/')[0]
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1))
  } else {
    return path.resolve(__dirname, '../', p)
  }
}

alias 文件

const path = require('path')

const resolve = p => path.resolve(__dirname, '../', p)

module.exports = {
  web: resolve('src/platforms/web'),
}

build 函數(shù)接受 builds 作為參數(shù)通過(guò)回調(diào)中再次調(diào)用自己來(lái)完成異步執(zhí)行完所有的構(gòu)建任務(wù)。

build(builds)


function build(builds) {
    let built = 0
    const total = builds.length
    const next = () => {
        buildEntry(builds[built]).then(() => {
            built++
            if (built < total) {
                next()
            }
        }).catch(logError)
    }

    next()
}

最后看看 buildEntry 方法终蒂,我們這里調(diào)用 rollup 成功后構(gòu)建項(xiàng)目代碼通過(guò) primise 來(lái)獲取蜂林,然后就可以對(duì)處理好的代碼進(jìn)行一些寫(xiě)入附加信息等操作。

function buildEntry(config) {
    const output = config.output
    const { file, banner } = output
    const isProd = /(min|prod)\.js$/.test(file)
    return rollup.rollup(config)
        .then(bundle => bundle.generate(output))
        .then(({ output: [{ code }] }) => {
            if (isProd) {
                const minified = (banner ? banner + '\n' : '') + terser.minify(code, {
                    toplevel: true,
                    output: {
                        ascii_only: true
                    },
                    compress: {
                        pure_funcs: ['makeMap']
                    }
                }).code
                return write(file, minified, true)
            } else {
                return write(file, code)
            }
        })
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拇泣,一起剝皮案震驚了整個(gè)濱河市噪叙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霉翔,老刑警劉巖睁蕾,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異债朵,居然都是意外死亡子眶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)葱弟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)壹店,“玉大人,你說(shuō)我怎么就攤上這事芝加。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵藏杖,是天一觀的道長(zhǎng)将塑。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蝌麸,這世上最難降的妖魔是什么点寥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮来吩,結(jié)果婚禮上敢辩,老公的妹妹穿的比我還像新娘。我一直安慰自己弟疆,他們只是感情好戚长,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著怠苔,像睡著了一般同廉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柑司,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天迫肖,我揣著相機(jī)與錄音,去河邊找鬼攒驰。 笑死蟆湖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玻粪。 我是一名探鬼主播帐姻,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奶段!你這毒婦竟也來(lái)了饥瓷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤痹籍,失蹤者是張志新(化名)和其女友劉穎呢铆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蹲缠,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棺克,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了线定。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娜谊。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖斤讥,靈堂內(nèi)的尸體忽然破棺而出纱皆,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布派草,位于F島的核電站搀缠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏近迁。R本人自食惡果不足惜艺普,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鉴竭。 院中可真熱鬧歧譬,春花似錦、人聲如沸搏存。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)祭埂。三九已至面氓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛆橡,已是汗流浹背舌界。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工泰演, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人睦焕。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像垃喊,于是被迫代替她去往敵國(guó)和親猾普。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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

  • 你是否是 JavaScript 新手?并且對(duì)模塊嗡呼,模塊加載器和模塊打包器感到困惑嗎纸俭?或者你已經(jīng)編寫(xiě)了一段時(shí)間的 J...
    鋼鋼_94d5閱讀 1,842評(píng)論 0 2
  • 前言 前一段時(shí)間利用空閑時(shí)間學(xué)習(xí)了一下vue組件的封裝揍很,也在工作中進(jìn)行了實(shí)踐郎楼,將公司常用的一個(gè)api抽象成了vue...
    朱小維閱讀 13,816評(píng)論 1 30
  • 1.幾種基本數(shù)據(jù)類(lèi)型?復(fù)雜數(shù)據(jù)類(lèi)型?值類(lèi)型和引用數(shù)據(jù)類(lèi)型?堆棧數(shù)據(jù)結(jié)構(gòu)? 基本數(shù)據(jù)類(lèi)型:Undefined窒悔、Nul...
    極樂(lè)君閱讀 5,520評(píng)論 0 106
  • rollup是一款小巧的javascript模塊打包工具,更適合于庫(kù)應(yīng)用的構(gòu)建工具;可以將小塊代碼編譯成大塊復(fù)雜的...
    IOneStar閱讀 15,092評(píng)論 2 7
  • 33阶界、JS中的本地存儲(chǔ) 把一些信息存儲(chǔ)在當(dāng)前瀏覽器指定域下的某一個(gè)地方(存儲(chǔ)到物理硬盤(pán)中)1聋庵、不能跨瀏覽器傳輸:在...
    萌妹撒閱讀 2,084評(píng)論 0 2