Rollup的基本使用

Rollup的基本使用

rollup.js是一個模塊打包工具,可使項目從一個入口文件開始,將全部使用到的模塊文件都打包到一個最終的發佈文件中,Rollup極其適合構建一個工具庫,Vue.js源碼就是經過Rollup打包構建的。javascript

描述

rollup對代碼模塊使用新的標準化格式,這些標準都包含在JavaScriptES6版本中,而不是之前的特殊解決方案,如CommonJSAMD等,也就是說rollup使用ES6的模塊標準,這意味着咱們能夠直接使用importexport而不須要引入babel,固然,在如今的項目中,babel能夠說是必用的工具,此外rollup實現了另外一個重要特性叫作tree-shaking,這個特性能夠幫助你將無用代碼,即沒有使用到的代碼自動去掉,這個特性是基於ES6模塊的靜態分析的,也就是說,只有export而沒有import的變量是不會被打包到最終代碼中的。css

示例

個人一個小油猴插件就是經過rollup打包的,GreasyFork地址爲https://greasyfork.org/zh-CN/scripts/405130,所有源碼地址爲https://github.com/WindrunnerMax/TKScript,使用npm run build便可打包構建,package.json文件與rollup.config.js文件配置以下。java

{
  "name": "TKScript",
  "version": "1.0.0",
  "description": "Tampermonkey",
  "scripts": {
    "build": "rollup -c"
  },
  "author": "Czy",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.10.4",
    "@babel/preset-env": "^7.10.4",
    "install": "^0.13.0",
    "npm": "^6.14.5",
    "rollup": "^2.18.2",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-postcss": "^3.1.2",
    "rollup-plugin-uglify": "^6.0.4",
    "rollup-plugin-userscript-metablock": "^0.2.5"
  }
}
import postcss from "rollup-plugin-postcss";
import babel from "rollup-plugin-babel";
// import { uglify } from "rollup-plugin-uglify";
import metablock from "rollup-plugin-userscript-metablock";

const config = {
    postcss: {
        minimize: true,
        extensions: [".css"],
    },
    babel: {
        exclude: ["node_modules/**"],
        presets: [
            [
                "@babel/env", {
                    modules: false,
                    targets: "last 2 versions, ie >= 10"
                }
            ]
        ]
    },

}

export default [{
    input: "./src/copy/src/index.js",
    output: {
        file: "./dist/copy.js",
        format: "iife",
        name: "copyModule"
    },
    plugins: [
        postcss(config.postcss),
        babel(config.babel),
        // uglify(),
        metablock({
            file: "./src/copy/meta.json"
        })
    ]
},{
    input: "./src/site-director/src/index.js",
    output: {
        file: "./dist/site-director.js",
        format: "iife",
        name: "linkModule"
    },
    plugins: [
        postcss(config.postcss),
        babel(config.babel),
        // uglify(),
        metablock({
            file: "./src/site-director/meta.json"
        })
    ]
}];

使用方法

安裝

  • 全局安裝: npm install rollup -g
  • 項目安裝: npm install rollup --save-devyarn add rollup -D

命令行工具

  • -i, --input <filename>: 要打包的文件(必須)。
  • -o, --file <output>: 輸出的文件(若是沒有這個參數,則直接輸出到控制檯)。
  • -f, --format <format>: 輸出的文件類型。
    • amd: 異步模塊定義,用於像RequestJS這樣的模塊加載器。
    • cjs: CommonJS, 適用於NodeBrowserify/webpack
    • es: 將軟件包保存爲ES模塊文件。
    • iife: 一個自動執行的功能,適合做爲script標籤這樣的,只能在瀏覽器中運行。
    • umd: 通用模塊定義,以amdcjsiife爲一體。
    • system: SystemJS加載器格式。
  • -e, --external <ids>: 將模塊ID的逗號分隔列表排除。
  • -g, --globals <pairs>: 以moduleID:Global鍵值對的形式,用逗號分隔開任何定義在這裏模塊ID定義添加到外部依賴。
  • -n, --name <name>: 生成UMD模塊的名字。
  • -m, --sourcemap: 生成sourcemap
  • --amd.id: AMD模塊的ID,默認是個匿名函數。
  • --amd.define: 使用Function來代替define
  • --no-strict: 在生成的包中省略use strict;
  • --no-conflict: 對於UMD模塊來講,給全局變量生成一個無衝突的方法。
  • --intro: 在打包好的文件的塊的內部(wrapper內部)的最頂部插入一段內容。
  • --outro: 在打包好的文件的塊的內部(wrapper內部)的最底部插入一段內容。
  • --banner: 在打包好的文件的塊的外部(wrapper外部)的最頂部插入一段內容。
  • --footer: 在打包好的文件的塊的外部(wrapper外部)的最底部插入一段內容。
  • --interop: 包含公共的模塊(這個選項是默認添加的)。
  • -w, --watch: 監聽源文件是否有改動,若是有改動,從新打包。
  • --silent: 不要將警告打印到控制檯。
  • -h, --help: 輸出幫助信息。
  • -v, --version 輸出版本信息。

配置文件

// rollup.config.js
export default {
  // 核心選項
  input,     // 必須
  external,
  plugins,

  // 額外選項
  onwarn,

  // danger zone
  acorn,
  context,
  moduleContext,
  legacy

  output: {  // 必須 (若是要輸出多個,能夠是一個數組)
    // 核心選項
    file,    // 必須
    format,  // 必須
    name,
    globals,

    // 額外選項
    paths,
    banner,
    footer,
    intro,
    outro,
    sourcemap,
    sourcemapFile,
    interop,

    // 高危選項
    exports,
    amd,
    indent
    strict
  },
};

input

inputrollup -i,--input,打包入口文件路徑,參數類型爲String | String [] | { [entryName: string]: string }
使用數組或者字符串做爲選項值的時候的時候,默認使用的是文件的原始名稱,做爲文件的basename,能夠在output:entryFileNames = entry-[name].js配置選項做爲[name]動態參數傳遞進去。node

input: "./src/index.js";
input: ["./src/index.js", "./other/index.js"];

用鍵值對{key: value}的選項值做爲參數,使用的對象的鍵做爲文件的basename,用來在output:entryFileNames配置選項做爲[name]動態參數傳遞進去。jquery

input: { main: "./src/index.js", vendor: "./other/index.js" }

external

externalrollup -e,--external, 維持包文件指定id文件維持外鏈,不參與打包構建 參數類型爲String[] | (id: string, parentId: string, isResolved: boolean) => booleanwebpack

  • format類型爲iife或者umd格式的時候須要配置output.globals選項參數以提供全局變量名來替換外部導入。
  • external是一個函數的時候,各個參數表明的含義分別是: id,全部導入的文件id,即import訪問的路徑;parentimport所在的文件絕對路徑;isResolved,表示文件id是否已經過插件處理過。
{
  // ...,
  external: [ 
      'some-externally-required-library',  
      'another-externally-required-library'
  ]
}
// or 
{
  // ...,
  external: (id, parent, isResolved) => {
    return true; 
  }
}

plugins

能夠提供rollup不少插件選項,參數類型爲Plugin | (Plugin | void)[]git

{
  // ...,
  plugins: [
      resolve(), 
      commonjs(), 
      isProduction && (await import("rollup-plugin-terser")).terser()
 ]
}

onwarn

攔截警告信息,若是沒有提供,警告將被複制並打印到控制檯,警告是至少有一個codemessage屬性的對象,咱們能夠控制如何處理不一樣類型的警告。github

onwarn (warning) {
  // 跳過某些警告
  if (warning.code === 'UNUSED_EXTERNAL_IMPORT') return;

  // 拋出異常
  if (warning.code === 'NON_EXISTENT_EXPORT') throw new Error(warning.message);

  // 控制檯打印一切警告
  console.warn(warning.message);
}

許多警告也有一個loc屬性和一個frame,能夠定位到警告的來源。web

onwarn ({ loc, frame, message }) {
  // 打印位置(若是適用)
  if (loc) {
    console.warn(`${loc.file} (${loc.line}:${loc.column}) ${message}`);
    if (frame) console.warn(frame);
  } else {
    console.warn(message);
  }
}

acorn

這是danger zone,修改rollup解析js配置,rollup內部使用的acorn庫解析js, acorn庫提供瞭解析js的相關配置api,通常不多須要修改。在下面這個例子中,這個acorn-jsx插件和使用babel並非同一個意思,這個插件的左右是讓acornjs解析器能認識jsx語法,通過rollup打包後展現的仍是jsx語法,而babel會直接修改jsx結構成爲普通js語法。npm

import jsx from "acorn-jsx";

export default {
  // ...
  acornInjectPlugins: [
      jsx()
  ]
};

context

默認狀況下,模塊的上下文,即頂級的this的值爲undefined,在極少數狀況下,可能須要將其更改成其餘內容,例如window

moduleContext

context同樣,可是每一個模塊能夠是id:context對的對象,也能夠是id=>context函數。

legacy

爲了增長對諸如IE8之類的舊版環境的支持,經過剝離更多可能沒法正常工做的現代化的代碼,其代價是偏離ES6模塊環境所需的精確規範。

output

output是輸出文件的統一配置入口, 包含不少可配置選項 參數類型爲Object | Array,單個輸出爲一個對象,要輸出多個,能夠是一個數組。

output.file

output.filerollup -o,--file,必填,對於單個文件打包可使用該選項指定打包內容寫入帶路徑的文件,參數類型爲String

output: {
    file: "./dist/index.js" 
}

output.format

output.formatrollup -f,--format,必填,打包格式類型 ,配置可選項有amdcjsesiifeumdsystem,選項說明同命令行配置選項,參數類型爲String

output: { 
    format: "iife"
}

output.name

output.formatrollup -f,--format生成包名稱,參數類型爲String

export default {
  // ...,
  output: {
    name: "bundle"
  }
};

output.globals

output.globalsrollup -g,--globals,配合配置external選項指定的外鏈在umdiife文件類型下提供的全局訪問變量名參數類型,參數類型爲{ [id: String]: String } | ((id: String) => String)

export default {
  // ...,
  globals: {
    jquery: "$"
  }
};

output.paths

它獲取一個ID並返回一個路徑,或者id: path對的Object,在提供的位置,這些路徑將被用於生成的包而不是模塊ID,從而容許從CDN加載依賴關係。

// app.js
import { selectAll } from 'd3';
selectAll('p').style('color', 'purple');
// ...

// rollup.config.js
export default {
  input: 'app.js',
  external: ['d3'],
  output: {
    file: 'bundle.js',
    format: 'amd',
    paths: {
      d3: 'https://d3js.org/d3.v4.min'
    }
  }
};

// bundle.js
define(['https://d3js.org/d3.v4.min'], function (d3) {

  d3.selectAll('p').style('color', 'purple');
  // ...

});

output.banner

字符串前置到文件束bundlebanner選項不會破壞sourcemaps,參數類型爲String

export default {
  // ...,
  output: {
      banner: "/* library version " + version + " */",
  }
};

output.footer

字符串前置到文件束bundlefooter選項不會破壞sourcemaps,參數類型爲String

export default {
  // ...,
  output: {
      footer: "/* follow me on Github! */",
  }
};

output.intro

相似於output.banner,若是說bannerfooter是在文件開始和結尾添加字符串,那麼introoutro就是在被打包的代碼開頭和結尾添加字符串了。

export default {
  // ...,
  output: {
      intro: "/* library version " + version + " */",
  }
};

output.outro

相似於output.footer,若是說bannerfooter是在文件開始和結尾添加字符串,那麼introoutro就是在被打包的代碼開頭和結尾添加字符串了。

export default {
  // ...,
  outro: {
      footer: "/* follow me on Github! */",
  }
};

output.sourcemap

sourcemaprollup -m,--sourcemap, --no-sourcemap,若是true,將建立一個單獨的sourcemap文件,若是inline, sourcemap將做爲數據URI附加到生成的output文件中。

output.sourcemapFile

生成的包的位置,若是這是一個絕對路徑,sourcemap中的全部源代碼路徑都將相對於它,map.file屬性是sourcemapFile的基本名稱basename,由於sourcemap的位置被假定爲與bundle相鄰,若是指定outputsourcemapFile不是必需的,在這種狀況下,將經過給bundle輸出文件添加.map後綴來推斷輸出文件名,通常應用場景不多,在特殊場景須要改變sourcemap的指向文件地址時纔會用到。

output.interop

是否添加interop塊,默認狀況下interop: true,爲了安全起見,若是須要區分默認和命名導出,則rollup會將任何外部依賴項default導出到一個單獨的變量,這一般只適用於您的外部依賴關係,例如與Babel,若是肯定不須要它,則可使用interop: false來節省幾個字節。

output.exports

使用什麼導出模式,默認爲auto,它根據entry模塊導出的內容猜想你的意圖。

  • default: 若是使用export default...僅僅導出一個文件,那適合用這個。
  • named: 若是導出多個文件,適合用這個。
  • none: 若是不導出任何內容,例如正在構建應用程序,而不是庫,則適合用這個。

output.amd

打包amd模塊相關定義。

  • amd.id: 用於AMD/UMD軟件包的ID
  • amd.define: 要使用的函數名稱,而不是define

output.indent

是要使用的縮進字符串,對於須要縮進代碼的格式amdiifeumd,也能夠是false無縮進或true默認自動縮進。

output.strict

truefalse,默認爲true,是否在生成的非ES6軟件包的頂部包含usestrict pragma,嚴格來講ES6模塊始終都是嚴格模式,因此應該沒有很好的理由來禁用它。

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

https://www.rollupjs.com/
https://segmentfault.com/a/1190000010628352
https://github.com/JohnApache/rollup-usage-doc
相關文章
相關標籤/搜索