亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vite中Rollup打包的實現(xiàn)

 更新時間:2025年03月28日 09:57:06   作者:Wang's Blog  
Rollup是一個JavaScript模塊打包器,它可以將多個小的JavaScript 模塊打包成一個大的模塊,本文主要介紹了Vite中Rollup打包的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下

概述

  • Rollup 是一款基于 ES Module 模塊規(guī)范實現(xiàn)的 JavaScript 打包工具,在前端社區(qū)中赫赫有名,同時也在 Vite 的架構(gòu)體系中發(fā)揮著重要作用
  • 不僅是 Vite 生產(chǎn)環(huán)境下的打包工具,其插件機制也被 Vite 所兼容,可以說是 Vite 的構(gòu)建基石

快速上手

首先讓我們用 $ npm init -y 新建一個項目,然后安裝 rollup 依賴: $ pnpm i rollup

接著新增 src/index.js 和 src/util.js 和 rollup.config.js 三個文件,目錄結(jié)構(gòu)如下所示:

├── package.json
├── pnpm-lock.yaml
├── rollup.config.js
└── src
 ├── index.js
 └── util.js

文件的內(nèi)容分別如下:

// src/index.js
import {
  add
} from "./util";

console.log(add(1, 2));

// src/util.js
export const add = (a, b) => a + b;
export const multi = (a, b) => a * b;

// rollup.config.js
// 以下注釋是為了能使用 VSCode 的類型提示
/**
 * @type { import('rollup').RollupOptions }
 */
const buildOptions = {
  input: ["src/index.js"],
  output: {
    // 產(chǎn)物輸出目錄
    dir: "dist/es",
    // 產(chǎn)物格式
    format: "esm",
  },
};
export default buildOptions;

你可以在 package.json 中加入如下的構(gòu)建腳本:

{
	 // rollup 打包命令,`-c` 表示使用配置文件中的配置
	 "build": "rollup -c"
}

接著在終端執(zhí)行一下 $ npm run build,可以看到如下的命令行信息:

OK,現(xiàn)在你已經(jīng)成功使用 Rollup 打出了第一份產(chǎn)物! 我們可以去 dist/es 目錄查看一下產(chǎn)物的內(nèi)容

// dist/es/index.js
// 代碼已經(jīng)打包到一起
const add = (a, b) => a + b;
console.log(add(1, 2));

同時你也可以發(fā)現(xiàn), util.js 中的 multi 方法并沒有被打包到產(chǎn)物中,這是因為 Rollup
具有天然的 Tree Shaking 功能,可以分析出未使用到的模塊并自動擦除。所謂 Tree Shaking (搖樹),也是計算機編譯原理中 DCE (Dead Code Elimination,即消除無用代碼) 技術(shù)的一種實現(xiàn)。由于 ES 模塊依賴關(guān)系是確定的,和運行時狀態(tài)無關(guān)。因此 Rollup 可以在編譯階段分析出依賴關(guān)系,對 AST 語法樹中沒有使用到的節(jié)點進行刪除,從而實現(xiàn) Tree Shaking

常用配置

1 ) 多產(chǎn)物配置

在打包 JavaScript 類庫的場景中,我們通常需要對外暴露出不同格式的產(chǎn)物供他人使用,不僅包括 ESM ,也需要包括諸如 CommonJS 、 UMD 等格式,保證良好的兼容性。那么,同一份入口文件,如何讓 Rollup 給我們打包出不一樣格式的產(chǎn)物呢?我們基于上述的配置文件來進行修改:

// rollup.config.js
/**
 * @type { import('rollup').RollupOptions }
 */
const buildOptions = {
  input: ["src/index.js"],
  // 將 output 改造成一個數(shù)組
  output: [{
      dir: "dist/es",
      format: "esm",
    },
    {
      dir: "dist/cjs",
      format: "cjs",
    },
  ],
};
export default buildOptions;

從代碼中可以看到,我們將 output 屬性配置成一個數(shù)組,數(shù)組中每個元素都是一個描述對象,決定了不同產(chǎn)物的輸出行為。

2 )多入口配置

除了多產(chǎn)物配置,Rollup 中也支持多入口配置,而且通常情況下兩者會被結(jié)合起來使用。接下來,就讓我們繼續(xù)改造之前的配置文件,將 input 設(shè)置為一個數(shù)組或者一個對象,如下所示

{
	 input: ["src/index.js", "src/util.js"]
}

// 或者
{
	 input: {
		 index: "src/index.js",
		 util: "src/util.js",
	 },
}

通過執(zhí)行 $ npm run build 可以發(fā)現(xiàn),所有入口的不同格式產(chǎn)物已經(jīng)成功輸出

如果不同入口對應(yīng)的打包配置不一樣,我們也可以默認導(dǎo)出一個 配置數(shù)組 ,如下所示:

// rollup.config.js
/**
 * @type { import('rollup').RollupOptions }
 */
const buildIndexOptions = {
  input: ["src/index.js"],
  output: [
    // 省略 output 配置
  ],
};
/**
 * @type { import('rollup').RollupOptions }
 */
const buildUtilOptions = {
  input: ["src/util.js"],
  output: [
    // 省略 output 配置
  ],
};
export default [buildIndexOptions, buildUtilOptions];

如果是比較復(fù)雜的打包場景(如 Vite 源碼本身的打包),我們需要將項目的代碼分成幾個部分,用不同的 Rollup 配置分別打包,這種配置就很有用了。

3 )自定義 output 配置

剛才我們提到了 input 的使用,主要用來聲明入口,可以配置成字符串、數(shù)組或者對象,使用比較簡單。而 output 與之相對,用來配置輸出的相關(guān)信息,常用的配置項如下:

 // 產(chǎn)物輸出目錄
 dir: path.resolve(__dirname, 'dist'),
   // 以下三個配置項都可以使用這些占位符:
   // 1. [name]: 去除文件后綴后的文件名
   // 2. [hash]: 根據(jù)文件名和文件內(nèi)容生成的 hash 值
   // 3. [format]: 產(chǎn)物模塊格式,如 es、cjs
   // 4. [extname]: 產(chǎn)物后綴名(帶`.`)
   // 入口模塊的輸出文件名
   entryFileNames: `[name].js`,
   // 非入口模塊(如動態(tài) import)的輸出文件名
   chunkFileNames: 'chunk-[hash].js',
   // 靜態(tài)資源文件輸出文件名
   assetFileNames: 'assets/[name]-[hash][extname]',
   // 產(chǎn)物輸出格式,包括`amd`、`cjs`、`es`、`iife`、`umd`、`system`
   format: 'cjs',
   // 是否生成 sourcemap 文件
   sourcemap: true,
   // 如果是打包出 iife/umd 格式,需要對外暴露出一個全局變量,通過 name 配置變量名
   name: 'MyBundle',
   // 全局變量聲明
   globals: {
     // 項目中可以直接用`$`代替`jquery`
     jquery: '$'
   }
 }

4 )依賴 external

對于某些第三方包,有時候我們不想讓 Rollup 進行打包,也可以通過 external 進行外部化:

{
 	external: ['react', 'react-dom']
}

在 SSR 構(gòu)建或者使用 ESM CDN 的場景中,這個配置將非常有用,

5 ) 接入插件能力

在 Rollup 的日常使用中,我們難免會遇到一些 Rollup 本身不支持的場景,比如 兼容CommonJS 打包 、 注入環(huán)境變量 、 配置路徑別名 、 壓縮產(chǎn)物代碼 等等。這個時候就需要我
們引入相應(yīng)的 Rollup 插件了。接下來以一個具體的場景為例帶大家熟悉一下 Rollup 插件的使用。

雖然 Rollup 能夠打包 輸出 出 CommonJS 格式的產(chǎn)物,但對于 輸入 給 Rollup 的代碼并不支持 CommonJS,僅僅支持 ESM。你可能會說,那我們直接在項目中統(tǒng)一使用 ESM規(guī)范就可以了啊,這有什么問題呢?需要注意的是,我們不光要考慮項目本身的代碼,還要考慮第三方依賴。目前為止,還是有不少第三方依賴只有 CommonJS 格式產(chǎn)物而并未提供 ESM 產(chǎn)物,比如項目中用到 lodash 時,打包項目會出現(xiàn)這樣的報錯:

因此,我們需要引入額外的插件去解決這個問題。首先需要安裝兩個核心的插件包:

  • pnpm i @rollup/plugin-node-resolve @rollup/plugin-commonjs
  • @rollup/plugin-node-resolve 是為了允許我們加載第三方依賴,否則像 import React from 'react' 的依賴導(dǎo)入語句將不會被 Rollup 識別。
  • @rollup/plugin-commonjs 的作用是將 CommonJS 格式的代碼轉(zhuǎn)換為 ESM 格式

然后讓我們在配置文件中導(dǎo)入這些插件:

// rollup.config.js
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
/**
 * @type { import('rollup').RollupOptions }
 */
export default {
  input: ["src/index.js"],
  output: [{
      dir: "dist/es",
      format: "esm",
    },
    {
      dir: "dist/cjs",
      format: "cjs",
    },
  ],
  // 通過 plugins 參數(shù)添加插件
  plugins: [resolve(), commonjs()],
};

現(xiàn)在我們以 lodash 這個只有 CommonJS 產(chǎn)物的第三方包為例測試一下: $ pnpm i lodash

在 src/index.js 加入如下的代碼:

import { merge } from "lodash";
console.log(merge);

然后執(zhí)行 $ npm run build,你可以發(fā)現(xiàn)產(chǎn)物已經(jīng)正常生成了

在 Rollup 配置文件中, plugins 除了可以與 output 配置在同一級,也可以配置在output 參數(shù)里面,如:

// rollup.config.js
import { terser } from 'rollup-plugin-terser'
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
export default {
	 output: {
		 // 加入 terser 插件,用來壓縮代碼
		 plugins: [terser()]
	 },
	 plugins: [resolve(), commonjs()]
}

當(dāng)然,你可以將上述的 terser 插件放到最外層的 plugins 配置中。

需要注意的是, output.plugins 中配置的插件是有一定限制的,只有使用 Output 階段相關(guān)鉤子(具體內(nèi)容將在下一節(jié)展開)的插件才能夠放到這個配置中,可以去這個站點, 查看 Rollup 的 Output 插件列表

另外,這里也給大家分享其它一些比較常用的 Rollup 插件庫:

JavaScript API 方式調(diào)用

以上我們通過 Rollup 的配置文件結(jié)合 rollup -c 完成了 Rollup 的打包過程,但有些場景下我們需要基于 Rollup 定制一些打包過程,配置文件就不夠靈活了,這時候我們需要用到對應(yīng) JavaScript API 來調(diào)用 Rollup,主要分為 rollup.rollup 和 rollup.watch 兩個API,接下來我們以具體的例子來學(xué)習(xí)一下。

首先是 rollup.rollup ,用來一次性地進行 Rollup 打包,你可以新建 build.js ,內(nèi)容如下:

// build.js
const rollup = require("rollup");
// 常用 inputOptions 配置
const inputOptions = {
  input: "./src/index.js",
  external: [],
  plugins: []
};
const outputOptionsList = [
  // 常用 outputOptions 配置
  {
    dir: 'dist/es',
    entryFileNames: `[name].[hash].js`,
    chunkFileNames: 'chunk-[hash].js',
    assetFileNames: 'assets/[name]-[hash][extname]',
    format: 'es',
    sourcemap: true,
    globals: {
      lodash: '_'
    }
  }
  // 省略其它的輸出配置
];

async function build() {
  let bundle;
  let buildFailed = false;
  try {
    // 1. 調(diào)用 rollup.rollup 生成 bundle 對象
    bundle = await rollup.rollup(inputOptions);
    for (const outputOptions of outputOptionsList) {
      // 2. 拿到 bundle 對象,根據(jù)每一份輸出配置,調(diào)用 generate 和 write 方法分別生成和寫入產(chǎn)物
      const {
        output
      } = await bundle.generate(outputOptions);
      await bundle.write(outputOptions);
    }
  } catch (error) {
    buildFailed = true;
    console.error(error);
  }
  if (bundle) {
    // 最后調(diào)用 bundle.close 方法結(jié)束打包
    await bundle.close();
  }
  process.exit(buildFailed ? 1 : 0);
}
build();

主要的執(zhí)行步驟如下:

  • 通過 rollup.rollup 方法,傳入 inputOptions ,生成 bundle 對象
  • 調(diào)用 bundle 對象的 generate 和 write 方法,傳入 outputOptions ,分別完成產(chǎn)物和生成和磁盤寫入
  • 調(diào)用 bundle 對象的 close 方法來結(jié)束打包

接著你可以執(zhí)行 node build.js ,這樣,我們就可以完成了以編程的方式來調(diào)用 Rollup打包的過程。除了通過 rollup.rollup 完成一次性打包,我們也可以通過 rollup.watch 來完成 watch模式下的打包,即每次源文件變動后自動進行重新打包。你可以新建 watch.js 文件,內(nèi)容入下:

// watch.js
const rollup = require("rollup");
const watcher = rollup.watch({
  // 和 rollup 配置文件中的屬性基本一致,只不過多了`watch`配置
  input: "./src/index.js",
  output: [{
      dir: "dist/es",
      format: "esm",
    },
    {
      dir: "dist/cjs",
      format: "cjs",
    },
  ],
  watch: {
    exclude: ["node_modules/**"],
    include: ["src/**"],
  },
});
// 監(jiān)聽 watch 各種事件
watcher.on("restart", () => {
  console.log("重新構(gòu)建...");
});
watcher.on("change", (id) => {
  console.log("發(fā)生變動的模塊id: ", id);
});
watcher.on("event", (e) => {
  if (e.code === "BUNDLE_END") {
    console.log("打包信息:", e);
  }
});

現(xiàn)在你可以通過執(zhí)行 node watch.js 開啟 Rollup 的 watch 打包模式,當(dāng)你改動一個文件后可以看到如下的日志,說明 Rollup 自動進行了重新打包,并觸發(fā)相應(yīng)的事件回調(diào)函數(shù):

發(fā)生生變動的模塊id: /xxx/src/index.js
重新構(gòu)建...
打包信息: 

{
  code: 'BUNDLE_END',
  duration: 10,
  input: './src/index.js',
  output: [
    // 輸出產(chǎn)物路徑
  ],
  result: {
    cache: {
      /* 產(chǎn)物具體信息 */ },
    close: [AsyncFunction: close],
    closed: false,
    generate: [AsyncFunction: generate],
    watchFiles: [
      // 監(jiān)聽文件列表
    ],
    write: [AsyncFunction: write]
  }
}

基于如上的兩個 JavaScript API 我們可以很方便地在代碼中調(diào)用 Rollup 的打包流程,相比于配置文件有了更多的操作空間,你可以在代碼中通過這些 API 對 Rollup 打包過程進行定制,甚至是二次開發(fā)

到此這篇關(guān)于Vite中Rollup打包的實現(xiàn)的文章就介紹到這了,更多相關(guān)Vite Rollup打包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue+element樹組件 實現(xiàn)樹懶加載的過程詳解

    vue+element樹組件 實現(xiàn)樹懶加載的過程詳解

    這篇文章主要介紹了vue+element樹組件 實現(xiàn)樹懶加載的過程,本文通過圖文實例代碼相結(jié)合給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • vue移動端使用appClound拉起支付寶支付的實現(xiàn)方法

    vue移動端使用appClound拉起支付寶支付的實現(xiàn)方法

    這篇文章主要介紹了vue移動端使用appClound拉起支付寶支付的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Vue中實現(xiàn)滾動加載與無限滾動

    Vue中實現(xiàn)滾動加載與無限滾動

    本文主要介紹了Vue中實現(xiàn)滾動加載與無限滾動,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 深入理解vue.js中$watch的oldvalue與newValue

    深入理解vue.js中$watch的oldvalue與newValue

    這篇文章主要給大家介紹了關(guān)于vue.js中$watch的oldvalue與newValue的相關(guān)資料,文中通過示例代碼介紹的非常詳細,并且介紹了關(guān)于watch的其他測試,對大家學(xué)習(xí)或者使用vue.js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編來一起看看吧。
    2017-08-08
  • 詳解在vue3中使用jsx的配置以及一些小問題

    詳解在vue3中使用jsx的配置以及一些小問題

    本文主要介紹了在vue3中使用jsx的配置以及一些小問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 解決Vue.js 2.0 有時雙向綁定img src屬性失敗的問題

    解決Vue.js 2.0 有時雙向綁定img src屬性失敗的問題

    下面小編就為大家分享一篇解決Vue.js 2.0 有時雙向綁定img src屬性失敗的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • vuex中store.commit和store.dispatch的區(qū)別及使用方法

    vuex中store.commit和store.dispatch的區(qū)別及使用方法

    這篇文章主要介紹了vuex中store.commit和store.dispatch的區(qū)別及使用方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Vue中使用Echarts可視化圖表寬度自適應(yīng)的完美解決方案

    Vue中使用Echarts可視化圖表寬度自適應(yīng)的完美解決方案

    這篇文章主要介紹了Vue中使用Echarts可視化圖表,寬度自適應(yīng)解決方案,我的解決方案是,在放置Echarts的容器(div)外層再套一層容器(div),外層容器寬度固定設(shè)置手機屏幕寬,感興趣的朋友跟隨小編一起看看吧
    2022-09-09
  • vue之a(chǎn)-table中實現(xiàn)清空選中的數(shù)據(jù)

    vue之a(chǎn)-table中實現(xiàn)清空選中的數(shù)據(jù)

    今天小編就為大家分享一篇vue之a(chǎn)-table中實現(xiàn)清空選中的數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • vue實現(xiàn)動態(tài)控制el-table表格列的展示與隱藏

    vue實現(xiàn)動態(tài)控制el-table表格列的展示與隱藏

    這篇文章主要介紹了vue實現(xiàn)動態(tài)控制el-table表格列的展示與隱藏,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評論