摘要:使用進(jìn)行模塊化打包在之前打包的過程中,命令行中輸出了一行,這表示并沒有收到任何模塊化的格式指令,因此會(huì)用默認(rèn)的模塊標(biāo)準(zhǔn)來對文件進(jìn)行打包。
前言
最近在做一個(gè)提供給瀏覽器和node同時(shí)使用的js的url模板工具類,在用什么打包工具上糾結(jié)了一段時(shí)間,正好有一天在知乎上看到了關(guān)于rollup的介紹,在自己試了試之后,就決定用rollup.js來打包自己的工具類了。
這篇文章主要是為了讓對rollup.js也有興趣的同學(xué)能夠快速入門rollup的使用方式而寫的,文章除了開始對rollup.js的基本介紹之外,主要用多個(gè)demo來介紹rollup.js的不同使用方法,以及介紹一些比較常用的rollup插件。讀者可以選擇自己有興趣的部分查看。
文章博客鏈接
本教程相關(guān)的所有demo都已上傳到github,rollup-demos,歡迎star。
rollup.js簡介首先簡單介紹一下rollup.JS。根據(jù)官方的介紹,rollup.js是一個(gè)模塊打包工具,可以幫助你從一個(gè)入口文件開始,將所有使用到的模塊文件都打包到一個(gè)最終的發(fā)布文件中(極其適合構(gòu)建一個(gè)工具庫,這也是我選擇用rollup來打包的原因)。
rollup.js有兩個(gè)重要的特性,其中一個(gè)就是它使用ES6的模塊標(biāo)準(zhǔn),這意味著你可以直接使用import和export而不需要引入babel(當(dāng)然,在現(xiàn)在的項(xiàng)目中,babel可以說是必用的工具了)。
rollup.js的另一個(gè)重要特性叫做"tree-shaking",這個(gè)特性可以幫助你將無用代碼(即沒有使用到的代碼)從最終的生成文件中刪去。舉個(gè)例子,我在A.js文件中定義了A1和A2兩個(gè)方法,同時(shí)在B文件中引入了這兩個(gè)方法,但是在B文件中只引入了A文件中的A1方法,那么在最后打包B文件時(shí),rollup就不會(huì)將A2方法引入到最終文件中。(這個(gè)特性是基于ES6模塊的靜態(tài)分析的,也就是說,只有export而沒有import的變量是不會(huì)被打包到最終代碼中的)
rollup.js實(shí)例 demo0 開始使用rollup初始化一個(gè)工程,創(chuàng)建一個(gè)依賴模塊文件lib.js和入口文件index.js。
export function logA() { console.log("function logA called") } export function logB() { console.log("function logB called") }
import { logA } from "./lib" logA()
現(xiàn)在我們要把lib.js和index.js打包成dist.js,首先要做的就是安裝rollup.js。
在這里我們有兩種安裝方法:
全局安裝:
打開你的命令行,輸入npm install rollup -g,等待rollup安裝完畢。安裝完成之后,試著輸入rollup -v來查看一下rollup是否安裝成功了
成功安裝完rollup之后,進(jìn)入到工程目錄下,輸入打包命令rollup index.js -o dist.js,index.js 是我們的入口文件, -o 表示輸出文件的路徑,在 -o 后面跟著的 dist.js 就是我們要生成的最終打包文件了。(其實(shí)這里本來應(yīng)該加上一個(gè)參數(shù)-i,用來表示入口文件的路徑,但rollup是會(huì)把沒有加參數(shù)的文件默認(rèn)為是入口文件,因此我們在這里省略了這個(gè)參數(shù))
顯示出這條信息之后,我們發(fā)現(xiàn)目錄下已經(jīng)多出了一個(gè) dist.js 文件,打開文件,我們發(fā)現(xiàn)里面的代碼是這樣的
function logA() { console.log("function logA called"); } logA();
此時(shí)我們就已經(jīng)完成了打包作業(yè),可以將dist.js引入到HTML文件或是node模塊中了
項(xiàng)目本地安裝:
進(jìn)入到項(xiàng)目目錄,打開命令行輸入npm install rollup --save-dev,把rollup加入到開發(fā)依賴中,然后在命令行中輸入./node_modules/.bin/rollup index.js -o dist.js
或者在package.json文件中添加npm scripts命令"build": "rollup index.js -o dist.js",在命令行中輸入npm run build來進(jìn)行打包
在打包完成之后,我們查看一下效果,新建一個(gè)index.html文件,在這個(gè)文件中引入我們打包出來的dist.js文件
rollup 打包測試
用瀏覽器打開index.html文件,打開控制臺,我們可以看到控制臺上輸出了一行文字
使用命令行運(yùn)行dist.js文件,我們也可以看到命令行中輸出了一行文字
這說明我們的打包文件dist.js是可以運(yùn)行的,打包成功。
PS:
接下來的demo中,默認(rèn)在項(xiàng)目內(nèi)安裝了rollup
接下來的demo中,非必要情況下不會(huì)對打包結(jié)果進(jìn)行運(yùn)行結(jié)果測試,讀者若需要驗(yàn)證打包效果,請自己編寫其他測試代碼。
demo1 使用rollup進(jìn)行模塊化打包在之前打包的過程中,命令行中輸出了一行No format option was supplied – defaulting to "es",這表示rollup并沒有收到任何模塊化的格式指令,因此會(huì)用默認(rèn)的es模塊標(biāo)準(zhǔn)來對文件進(jìn)行打包。
如果在demo0中的index.js文件中把logA()改成export default logA(),那么rollup最后的打包結(jié)果就會(huì)是
function logA() { console.log("function logA called"); } var index = logA(); export default index;
顯然這樣的代碼是不能直接在瀏覽器端和node端運(yùn)行的,我們需要把原先的ES6模塊轉(zhuǎn)化成瀏覽器和node支持的形式。
那么要去哪里找rollup把ES6代碼轉(zhuǎn)化成其他形式的方法呢?這里有兩個(gè)方案,一是去rollup的官網(wǎng)找相關(guān)的資料,二是使用rollup命令行的幫助命令,看看能不能找到相關(guān)的參數(shù)
我們使用rollup命令行的幫助命令,在命令行中輸入rollup -h
在這里我們可以看到類似版本號,幫助,使用配置文件等一系列參數(shù)。在這里我們可以找到-f這個(gè)參數(shù),他的說明是輸出的類型(amd,cjs,es,iife,umd),從括號里的內(nèi)容我們可以看出,使用這個(gè)參數(shù)可以確定打包完后的文件的模塊處理方式。(如果你還不知道這幾種模塊之間的區(qū)別,建議先去找一下相關(guān)的資料學(xué)習(xí)一下)
接下來我們用rollup來打包一下,在demo0中的index.js文件里將logA()改成export default logA(),在package.json文件中寫好不同模塊的打包命令
"build:amd": "rollup index.js -f amd -o ./dist/dist.amd.js", "build:cjs": "rollup index.js -f cjs -o ./dist/dist.cjs.js", "build:es": "rollup index.js -f es -o ./dist/dist.es.js", "build:iife": "rollup index.js -f iife -n result -o ./dist/dist.iife.js", "build:umd": "rollup index.js -f umd -n result -o ./dist/dist.umd.js", "build:all": "npm run build:amd && npm run build:cjs && npm run build:es && npm run build:iife && npm run build:umd"
在這里我們發(fā)現(xiàn)在設(shè)置模塊為iife(立即執(zhí)行函數(shù))和umd時(shí),還加上了一個(gè)參數(shù)-n,這是因?yàn)槲覀儗ogA()的結(jié)果設(shè)置為模塊的輸出結(jié)果,那么在使用iife和umd時(shí),需要事先設(shè)定模塊的名稱,才能讓其他人通過這個(gè)模塊名稱引用到你的模塊的輸出結(jié)果。
在命令行中輸入npm run build:all,運(yùn)行所有打包命令,查看效果
可以看到已經(jīng)輸出了5種不同模塊標(biāo)準(zhǔn)的打包文件,由于字?jǐn)?shù)原因,在這里我們只查看一個(gè)打包文件(dist.iife.js)的內(nèi)容
var result = (function () { "use strict"; function logA() { console.log("function logA called"); } var index = logA(); return index; }());
可以看到所有代碼都被打包到了一個(gè)立即執(zhí)行函數(shù)中,并且將函數(shù)的返回值(模塊的輸出內(nèi)容)賦值給了一個(gè)全局變量,而這個(gè)全局變量的名稱就是我們之前設(shè)置的模塊名稱。
PS: 使用amd模塊打包方式時(shí),若不指定模塊名稱,則會(huì)打包成匿名函數(shù),若想打包成一個(gè)具名函數(shù),則需要使用-u或--id來指定具名函數(shù)名稱。
除了-f之外,還有許多其他的參數(shù)可以使用,看到這里可能有些同學(xué)會(huì)覺得麻煩了,這么多參數(shù)用起來好麻煩,每次都要輸一長串的命令,那么有沒有更好的方法來控制rollup的參數(shù)配置呢?
當(dāng)然有,接下來我們就嘗試使用配置文件來控制rollup打包。
demo2 使用配置文件來進(jìn)行rollup打包創(chuàng)建一個(gè)demo2,沿用之前demo1的內(nèi)容,我們在demo2的項(xiàng)目下創(chuàng)建一個(gè)文件,取名為rollup.config.js,這個(gè)文件就是rollup的配置文件了,rollup根據(jù)配置文件的輸出配置來進(jìn)行打包,接下來我們在配置文件中輸入配置代碼:
export default { entry: "index.js", format: "cjs", dest: "./dist/dist.js" }
entry表示打包的入口文件,format表示要打包成的模塊類型,dest表示輸出文件的名稱路徑
PS: 若使用iife或umd模塊打包,需要添加屬性moduleName,用來表示模塊的名稱;若用amd模塊打包,可以配置amd相關(guān)的參數(shù)(使用umd模塊模式時(shí),也會(huì)使用到amd相關(guān)配置參數(shù)):
amd: { id: "amd-name", // amd具名函數(shù)名稱 define: "def" // 用來代替define函數(shù)的函數(shù)名稱 }
在這里我們發(fā)現(xiàn)配置文件也是使用了ES6語法,這是因?yàn)閞ollup可以自己處理配置文件,所以能夠直接用ES6的模塊輸出(當(dāng)然,你也可以選擇使用node的module.exports方式來輸出配置。
在package.json文件中編寫npm scripts命令
"build": "rollup -c"
-c這個(gè)參數(shù)表示使用配置文件來進(jìn)行打包,若后面沒有指定使用的配置文件路徑,則使用默認(rèn)的配置文件名稱rollup.config.js。
在命令行中輸入npm run build,執(zhí)行打包,可以看到生成了打包文件dist.js
"use strict"; function logA() { console.log("function logA called"); } var index = logA(); module.exports = index;
進(jìn)階: 當(dāng)rollup配置文件最終輸出的不是一個(gè)對象而是一個(gè)數(shù)組時(shí),rollup會(huì)把每一個(gè)數(shù)組元素當(dāng)成一個(gè)配置輸出結(jié)果,因此可以在一個(gè)配置文件內(nèi)設(shè)置多種輸出配置
例如,我們添加一個(gè)indexB.js文件,在這個(gè)文件中我們將logA替換為logB,并將rollup配置文件改為:
export default [{ entry: "index.js", format: "cjs", dest: "./dist/distA.js" },{ entry: "indexB.js", format: "iife", moduleName: "indexB", dest: "./dist/distB.js" }]
運(yùn)行打包命令,發(fā)現(xiàn)在dist目錄下生成了distA.js和distB.js兩個(gè)文件,說明多項(xiàng)配置打包成功。
除了上面這種輸出一個(gè)配置數(shù)組之外,你還可以通過配置target屬性來輸出多個(gè)打包文件:
export default { entry: "index.js", targets: [{ dest: "dist/bundle.cjs.js", format: "cjs" }, { dest: "dist/bundle.umd.js", moduleName: "res", format: "umd" }, { dest: "dist/bundle.es.js", format: "es" }, ] }
這樣配置會(huì)在dist目錄下面輸出bundle.cjs.js,bundle.umd.js和bundle.es.js三個(gè)打包文件,同時(shí)umd模塊的名稱會(huì)被定義成res。
demo3 監(jiān)聽文件變化,隨時(shí)打包我們在開發(fā)過程中,需要頻繁對源文件進(jìn)行修改,如果每次都自己手動(dòng)輸一遍打包命令,那真的是要煩死。因此,我們選擇使用rollup提供的監(jiān)聽功能,安裝rollup-wacth模塊,再在rollup命令后面加上-w參數(shù),就能讓rollup監(jiān)聽文件變化,即時(shí)打包。
安裝watch包:
npm i rollup-watch --save-dev // or yarn add rollup-watch --dev
編寫npm scripts:
"dev": "rollup -c -w"
執(zhí)行npm run dev,看到下面的提示:
好了,這個(gè)時(shí)候你就可以隨便修改你的源文件了,rollup會(huì)自動(dòng)為你打包的。
PS: 若是你不想監(jiān)聽某些文件,只要在配置文件中加上
watch: { exclude: ["path/to/file/which/you/want/to/ignore"] }
就行了,其中的exclude表示你想要忽略的文件的路徑(支持glob模式匹配)
demo4 是時(shí)候?qū)慐S6了ES6可以說是現(xiàn)代JS開發(fā)100%會(huì)用到的技術(shù)了,rollup雖然支持了解析import和export兩種語法,但是卻不會(huì)將其他的ES6代碼轉(zhuǎn)化成ES5代碼,因此我們在編寫ES6代碼的時(shí)候,需要引入插件來支持ES6代碼的解析。
安裝插件和你需要的babel preset:
npm i rollup-plugin-babel babel-preset-es2015 --save-dev // or yarn add rollup-plugin-babel babel-preset-es2015 --dev
創(chuàng)建.babalrc文件:
{ "presets": [ ["es2015", { "modules": false }] ] }
之所以使用modules:false這個(gè)參數(shù),是因?yàn)閞ollup默認(rèn)是通過ES6模塊語法來解析文件間的依賴,rollup默認(rèn)是不支持解析common.js的模塊規(guī)范的(怎么讓rollup支持我會(huì)在接下來的demo中講解),因此需要讓babel不轉(zhuǎn)化模塊相關(guān)的語法,不然rollup在使用過程中會(huì)報(bào)錯(cuò)。
編寫rollup配置文件:
import babel from "rollup-plugin-babel"; export default [{ entry: "index.js", format: "iife", dest: "./dist/dist.js", plugins: [ babel({ exclude: "node_modules/**" }) ] }]
rollup的配置文件的plugins屬性可以讓你添加在rollup打包過程中所要用到的插件,但是要注意的是,插件的添加順序決定了它們在打包過程中的使用順序,因此要注意配置文件的插件使用順序。
編寫ES6代碼
在這里我們新建三個(gè)文件,兩個(gè)類Person和Man和一個(gè)入口文件index.js
export default class Person { constructor (name, gender = "男") { this.name = name this.gender = gender } say () { console.log(`我的名字是${this.name},是一個(gè)${this.gender}生`) } }
import Person from "./Person" export default class Man extends Person { constructor (name) { super(name, "男") } }
import Man from "./src/Man" new Man("KainStar").say()
運(yùn)行打包命令npm run build
可以看到rollup輸出了一段提示文字,我們先不去管它,先看看打包出來的文件能不能運(yùn)行,執(zhí)行node dist/dist.js
可以看到代碼運(yùn)行成功了,那么我們回來繼續(xù)看之前的提示文字,它的意思是"classCallCheck"這個(gè)babel helper函數(shù)使用了多次,rollup推薦我們使用external-helpers這個(gè)插件或es2015-rollup這個(gè)babel-preset來簡化打包出來的代碼。
我們查看一下打包出來的dist.js文件,發(fā)現(xiàn)_classCallCheck這個(gè)函數(shù)被定義了兩次,分別被取名為_classCallCheck和_classCallCheck$1,這樣的代碼肯定是可以簡化的,因此我們引入external-helpers這個(gè)插件:
npm i babel-plugin-external-helpers --save-dev // or yarn add babel-plugin-external-helpers --dev
修改.babelrc文件為
{ "presets": [ ["es2015", { "modules": false }] ], "plugins": [ "external-helpers" ] }
或者在配置文件中使用babel配置
plugins: [ babel({ plugins: ["external-helpers"] }) ]
注意! 在rollup-plugin-babel的官方github倉庫中有一段配置是這樣的:
plugins: [ babel({ plugins: ["external-helpers"], externalHelpers: true }) ]
這段配置的使用要求是你需要設(shè)置全局的babelHelpers對象,以此來將打包文件中的babel相關(guān)代碼刪除,所以一般情況下不需要使用externalHelpers這個(gè)屬性。
PS: 你也可以使用babel-preset-es2015-rollup這個(gè)包(搭配babel-core),它集成了babel-preset-es2015,babel-plugin-transform-es2015-modules-commonjs和babel-plugin-external-helpers三個(gè)模塊,使用起來更加方便,只要將.babelrc文件修改成{ "presets": ["es2015-rollup"] }就可以使用了。
demo5 解析cjs,打包第三方模塊有時(shí)候我們會(huì)引入一些其他模塊的文件(第三方的或是自己編寫的),但是這些第三方的模塊為了能夠直接使用,往往不是ES6模塊而是用commonjs的模塊方式編寫的,這個(gè)時(shí)候我們需要將commonjs的模塊轉(zhuǎn)化為ES6模塊,這樣才能讓rollup進(jìn)行正確的解析。
解析commonjs
解析commonjs需要引入一個(gè)rollup插件——rollup-plugin-commonjs
安裝插件
npm i rollup-plugin-commonjs --save-dev // or yarn add rollup-plugin-commonjs --dev
在配置文件中配置插件
import commonjs from "rollup-plugin-commonjs" export default { entry: "index_cjs.js", format: "iife", dest: "./js/dist_cjs.js", plugins: [ commonjs() ] }
編寫cjs模塊的文件
exports.logA = function logA() { console.log("function logA called") } exports.logB = function logB() { console.log("function logB called") }
執(zhí)行打包,可以看到打包成功,也沒有輸出任何提示信息
打包第三方模塊
在打包第三方模塊的過程中,rollup無法直接解析npm模塊,因此需要引入插件rollup-plugin-node-resolve并配合之前的commonjs插件來解析這些第三方模塊
安裝插件和第三方模塊
npm i rollup-plugin-node-resolve lodash --save-dev // or yarn add rollup-plugin-node-resolve lodash --dev
在配置文件中配置插件
import commonjs from "rollup-plugin-commonjs" import resolve from "rollup-plugin-node-resolve" export default { entry: "index_module.js", format: "iife", dest: "./js/dist_module.js", plugins: [ resolve({ jsnext: true, main: true, browser: true }), commonjs() ] }
jsnext表示將原來的node模塊轉(zhuǎn)化成ES6模塊,main和browser則決定了要將第三方模塊內(nèi)的哪些代碼打包到最終文件中。
由于commonjs和node-resolve中的配置屬性很多,因此不一一解釋,希望了解更多的同學(xué)可以去官方倉庫查看說明。
編寫入口文件
import compact from "lodash/compact" const array = [0, 1, false, 2, "", 3] const compctedArray = compact(array) console.log(compctedArray)
在這里我們只引用了lodash中的compact方法,那么在最終代碼里,應(yīng)該也只會(huì)添加compact方法的代碼。
執(zhí)行打包命令,查看打包出來的文件:
(function () { "use strict"; /** * Creates an array with all falsey values removed. The values `false`, `null`, * `0`, `""`, `undefined`, and `NaN` are falsey. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to compact. * @returns {Array} Returns the new array of filtered values. * @example * * _.compact([0, 1, false, 2, "", 3]); * // => [1, 2, 3] */ function compact(array) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value) { result[resIndex++] = value; } } return result; } var compact_1$1 = compact; const array = [0, 1, false, 2, "", 3]; const compctedArray = compact_1$1(array); console.log(compctedArray); }());
確實(shí)只添加了compact方法的代碼,而沒有將lodash全部引入。
demo6 不要打包到一個(gè)文件,為rollup設(shè)置外部模塊和全局變量在平時(shí)的開發(fā)中,我們經(jīng)常會(huì)引入其他的模塊,但是在使用的時(shí)候,我們又不想把它們打包到一個(gè)文件里,想讓他們作為多帶帶的模塊(或文件)來使用,方便瀏覽器端進(jìn)行緩存,這個(gè)時(shí)候就需要使用配置文件中的external屬性了
我們在demo5的基礎(chǔ)上,把jquery安裝到第三方模塊中
npm i jquery --save-dev // or yarn add jquery --dev
將配置文件改成
import commonjs from "rollup-plugin-commonjs" import resolve from "rollup-plugin-node-resolve" export default { entry: "index.js", format: "iife", dest: "./js/dist.js", external: ["jquery"], plugins: [ resolve({ jsnext: true, main: true, browser: true }), commonjs() ] }
external用來表示一個(gè)模塊是否要被當(dāng)成外部模塊使用,屬性的值可以是一個(gè)字符串?dāng)?shù)組或一個(gè)方法,當(dāng)傳入的是一個(gè)字符串?dāng)?shù)組時(shí),所有數(shù)組內(nèi)的模塊名稱都會(huì)被當(dāng)成是外部模塊,不會(huì)被打包到最終文件中
當(dāng)傳入的是一個(gè)方法時(shí),方法有一個(gè)參數(shù)id,表示解析的模塊的名稱,我們可以自定義解析方式,若是要當(dāng)做外部模塊不打包到最終文件中,則返回true,若要一起打包到最終文件中,則返回false
在這里我們把jquery當(dāng)成一個(gè)外部模塊,執(zhí)行打包命令:
檢查打包出來的文件,我們發(fā)現(xiàn)lodash的compact方法依舊被打包進(jìn)了最終文件中,但是jquery卻沒有被打包進(jìn)去,而是以$的全局變量形式被傳入到了立即執(zhí)行函數(shù)中。
在這里rollup又給我們輸出了一條提示信息,意思是我們沒有在配置文件中給外部模塊jquery設(shè)置全局變量名稱,因此rollup自己猜測了一個(gè)名稱$,當(dāng)成是依賴的全局變量名。
如果直接使用全局的$的話,可能會(huì)因?yàn)樽兞?被其他引入的代碼覆蓋而報(bào)錯(cuò),因此我們要將$替換為不容易沖突的jQuery變量,在配置文件中添加globals屬性:
globals: { jquery: "jQuery" }
globals的值是一個(gè)對象,key表示使用的模塊名稱(npm模塊名),value表示在打包文件中引用的全局變量名,在這里我們就是把jquery模塊的全局變量名設(shè)置為jQuery,重新打包
在重新打包出來的文件中,我們發(fā)現(xiàn)最后傳入的參數(shù)已經(jīng)由$變?yōu)榱?b>jQuery,而且rollup也沒有輸出提示信息。
demo7 打包node內(nèi)置模塊有時(shí)候我們想要在瀏覽器端使用node自帶的一些內(nèi)置模塊,一般情況下會(huì)使用browserify這個(gè)工具來打包,但是browserify打包出來的文件實(shí)在太大,因此我們用rollup選擇性地導(dǎo)入我們需要的node內(nèi)置模塊
安裝插件
npm i rollup-plugin-node-builtins --save-dev // or yarn add rollup-plugin-node-builtins --dev
PS: node-builtins對不同的node內(nèi)置模塊支持不同,有些模塊可能需要使用其他的插件(例如rollup-plugin-node-globals)才能正常打包,具體的支持情況可以查看node-builtins的官方倉庫。
編寫配置文件
import builtins from "rollup-plugin-node-builtins" export default { entry: "index.js", format: "iife", dest: "./dist/dist.js", plugins: [ builtins() ] }
編寫入口文件
import { join } from "path" const path_base = "E://node" const path_joined = join(path_basem, "bin") console.log(path_joined)
在這里我們使用node內(nèi)置的path模塊,運(yùn)行打包命令,發(fā)現(xiàn)dist.js文件中引入了額外的100多行代碼,這100多行代碼就實(shí)現(xiàn)了path模塊的join方法供我們使用。
PS: 我建議,如果不是必要的情況,最好能夠使用其他人編寫的第三方實(shí)現(xiàn)庫或自己造輪子實(shí)現(xiàn),而不是使用node內(nèi)置的模塊,因?yàn)樵谝媚承┠K時(shí),node-builtins可能會(huì)引入過多的代碼,這樣會(huì)大大增加最后打包的文件的大小,使用他人的第三方庫或自己的實(shí)現(xiàn)可控性更高
demo8 配合CDN來使用rollup有時(shí)候我們可能會(huì)使用CDN服務(wù)器上的js文件,但是又不想在本地安裝一個(gè)相同的模塊(也有可能沒有對應(yīng)的模塊),可能在版本升級的時(shí)候會(huì)產(chǎn)生一些問題,這個(gè)時(shí)候我們就需要使用rollup的paths屬性了,這個(gè)屬性可以幫助你把依賴的代碼文件地址注入到打包之后的文件里。
編寫配置文件
export default { entry: "index.js", format: "amd", dest: "./dist/dist.js", external: ["jquery"], paths: { jquery: "https://cdn.bootcss.com/jquery/3.2.1/jquery.js" } }
在這里我們要使用cdn上的jquery文件,paths屬性的值可以是一個(gè)對象或用法與external屬性方法相似的方法(只是返回的不是boolean值而是文件的地址)。若使用對象來表示,則key值為需要引入的模塊名稱,value值為對應(yīng)的文件地址
編寫源文件
import $ from "jquery" $("#p").html("rollup 使用paths屬性配合CDN")
執(zhí)行打包命令,最后打包出來的文件內(nèi)容是:
define(["https://cdn.bootcss.com/jquery/3.2.1/jquery.js"], function ($) { "use strict"; $ = $ && $.hasOwnProperty("default") ? $["default"] : $; $("#p").html("rollup 使用paths屬性配合CDN"); });
可以看到rollup已經(jīng)把我們需要的CDN地址作為依賴加入到了打包文件中。
demo9 最小化你的代碼代碼發(fā)布時(shí),我們經(jīng)常會(huì)把自己的代碼壓縮到最小,以減少網(wǎng)絡(luò)請求中的傳輸文件大小。
rollup的插件rollup-plugin-uglify就是來幫助你壓縮代碼的,我們接下來就用這個(gè)插件來壓縮一下我們的代碼
npm i rollup-plugin-uglify --save-dev // or yarn add rollup-plugin-uglify --dev
編寫配置文件
import uglify from "rollup-plugin-uglify" export default { entry: "index.js", format: "iife", dest: "./dist/dist.js", plugins: [ uglify() ] }
運(yùn)行打包命令,查看dist.js文件,發(fā)現(xiàn)代碼已經(jīng)被壓縮了
但是,壓縮過的代碼在debug時(shí)會(huì)帶來很大的不便,因此我們需要在壓縮代碼的同時(shí)生成一個(gè)sourceMap文件
幸運(yùn)的是,rollup自己就支持sourceMap文件的生成,不需要我們?nèi)ヒ肫渌寮恍枰谂渲梦募屑由希?/p>
sourceMap: true
就可以了。
重新打包,我們發(fā)現(xiàn)不僅生成了dist.js.map文件,而且dist文件最后加上了一行//# sourceMappingURL=dist.js.map,并且在瀏覽器中可以正確加載源文件
PS: 若是將sourceMap屬性的值設(shè)置為inline,則會(huì)將sourceMap的內(nèi)容添加到打包文件的最后。
demo10 為你的代碼添eslint檢查在大型工程的團(tuán)隊(duì)開發(fā)中,我們需要保證團(tuán)隊(duì)代碼風(fēng)格的一致性,因此需要引入eslint,而且在打包時(shí)需要檢測源文件是否符合eslint設(shè)置的規(guī)范,若是不符合則拋出異常并停止打包。在這里我們使用rollup的eslint插件rollup-plugin-eslint:
安裝插件
npm i eslint rollup-plugin-eslint --save-dev // or yarn add eslint rollup-plugin-eslint --dev
編寫eslint配置文件.eslintrc
{ "env": { "browser": true, "commonjs": true, "es6": true, "node": true }, "parserOptions": { "ecmaFeatures": { "jsx": false }, "sourceType": "module" }, "rules": { "semi": ["error","never"] } }
在這里我們強(qiáng)制要求不使用分號,然后在源文件中加上一個(gè)分號
foo(element);
編寫rollup配置文件
import eslint from "rollup-plugin-eslint"; export default { entry: "./src/index.js", format: "iife", dest: "./dist/dist.js", plugins: [ eslint({ throwOnError: true, throwOnWarning: true, include: ["src/**"], exclude: ["node_modules/**"] }) ] }
eslint插件有兩個(gè)屬性需要說明:throwOnError和throwOnWarning設(shè)置為true時(shí),如果在eslint的檢查過程中發(fā)現(xiàn)了error或warning,就會(huì)拋出異常,阻止打包繼續(xù)執(zhí)行(如果設(shè)置為false,就只會(huì)輸出eslint檢測結(jié)果,而不會(huì)停止打包)
執(zhí)行打包命令,發(fā)現(xiàn)eslint在輸出了檢查結(jié)果之后拋出了異常,而且dist.js文件也沒有生成
刪除index.js文件中的分號,重新打包,發(fā)現(xiàn)打包成功
進(jìn)階: 在平時(shí)的開發(fā)過程中,我們經(jīng)常會(huì)使用IDE或編輯器的eslint插件,以便提早發(fā)現(xiàn)問題,但是有時(shí)候這些插件會(huì)去檢查打包完的文件,導(dǎo)致你的提示框里一直會(huì)有eslint檢測到錯(cuò)誤的消息
我們現(xiàn)在有兩種解決方案,一是創(chuàng)建一個(gè).eslintignore文件,將打包文件加進(jìn)去,讓eslint忽略這個(gè)文件
還有一種就是讓rollup在打包文件的開始和最后自動(dòng)生成注釋來阻止eslint檢測代碼,使用這種方法時(shí),需要使用rollup配置文件的兩個(gè)屬性:banner和footer,這兩個(gè)屬性會(huì)在生成文件的開頭和結(jié)尾插入一段你自定義的字符串。我們利用這個(gè)屬性,在打包文件的開頭添加/*eslint-disable */注釋,讓eslint不檢測這個(gè)文件。
添加banner和footer屬性
banner: "/*eslint-disable */"
重新打包,我們發(fā)現(xiàn)打包文件的開頭被插入了這段注釋字符串,而且eslint插件也不報(bào)dist.js文件的錯(cuò)了
/*eslint-disable */ (function () { "use strict"; // 具體代碼 }());demo11 控制開發(fā)環(huán)境和生產(chǎn)環(huán)境下的配置
配置文件的開發(fā)/生產(chǎn)環(huán)境配置
有時(shí)候我們會(huì)需要區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境,針對不同的打包要求輸出不同的打包配置,但是我們又不想寫rollup.config.dev.js和rollup.config.prod.js兩個(gè)文件,因?yàn)榭赡軆烧咧g的區(qū)別只是一個(gè)uglify插件。
因此,我們就需要用變量來控制配置文件的輸出內(nèi)容,rollup命令行給我們提供了一個(gè)設(shè)置環(huán)境變量的參數(shù)--environment,在這個(gè)參數(shù)后面加上你需要設(shè)置的環(huán)境變量,不同變量間用逗號分隔,用冒號后面的字符串表示對應(yīng)變量的值(若不加冒號,則默認(rèn)將值設(shè)為字符串true):
在package.json文件中編寫對應(yīng)的npm scripts命令:
"dev": "rollup -c --environment NODE_ENV:development", "build": "rollup -c --environment NODE_ENV:production"
最后修改我們的rollup配置文件
import uglify from "rollup-plugin-uglify" let isProd = process.env.NODE_ENV === "production" // 通用的插件 const basePlugins = [] // 開發(fā)環(huán)境需要使用的插件 const devPlugins = [] // 生產(chǎn)環(huán)境需要使用的插件 const prodPlugins = [uglify()] let plugins = [...basePlugins].concat(isProd ? prodPlugins:devPlugins) let destFilePath = isProd ? "./dist/dist.min.js": "./dist/dist.js" export default { entry: "index.js", format: "iife", dest: destFilePath, sourceMap: isProd, plugins: plugins }
我們分別運(yùn)行兩個(gè)npm scripts命令,查看打包的結(jié)果:
源文件開發(fā)/生產(chǎn)環(huán)境信息注入
上面是在配置文件里通過變量來改變輸出的配置類型,但是我們有時(shí)候需要將生產(chǎn)環(huán)境信息添加到源文件里,這個(gè)時(shí)候就需要使用rollup的配置屬性intro和outro了
如果說banner和footer是在文件開始和結(jié)尾添加字符串,那么intro和outro就是在被打包的代碼開頭和結(jié)尾添加字符串了,以iife模式來舉例,如果我們配置了這四個(gè)屬性,那么輸出結(jié)果就會(huì)是:
// banner字符串 (function () { "use strict"; // intro字符串 // 被打包的代碼 // outro字符串 }()); // footer字符串
這樣的形式
下面我們實(shí)際使用一下,在index.js文件里加上一段需要依賴的代碼
if (DEVELOPMENT) { console.log("處于開發(fā)環(huán)境") } else { console.log("處于生產(chǎn)環(huán)境") }
然后在我們的rollup配置文件里添加:
intro: "var DEVELOPMENT = " + !isProd,
這樣,當(dāng)我們最后生成的代碼時(shí),就會(huì)輸出開發(fā)環(huán)境或生產(chǎn)環(huán)境的提示:
源文件開發(fā)/生產(chǎn)環(huán)境信息替換
有時(shí)候我們會(huì)把開發(fā)/生產(chǎn)環(huán)境的信息直接寫在源文件里面,這個(gè)時(shí)候用intro來注入代碼的方式就不適合了。這個(gè)時(shí)候我們就需要使用rollup-plugin-replace插件來對源代碼的變量值進(jìn)行替換:
安裝插件
npm i rollup-plugin-replace --save-dev // or yarn add rollup-plugin-replace --dev
編寫配置文件
const basePlugins = [replace({ DEVELOPMENT: !isProd })] // 將intro屬性注釋掉 // intro: "var DEVELOPMENT = " + !isProd,
這里我們使用replace插件,以key-value對象的形式,將DEVELOPMENT的值替換為!isProd的值
執(zhí)行打包命令,并檢查打包結(jié)果:
進(jìn)階: replace除了直接使用key-value的形式替換對應(yīng)key同名變量的方法之外,還可以通過配置delimiters參數(shù)來實(shí)現(xiàn)模板功能:
配置replace插件參數(shù)
VERSION: "1.0.0", delimiters: ["{{", "}}"]
通過這個(gè)配置,在打包過程中,{{VERSION}}會(huì)被替換成1.0.0
在index.js文件內(nèi)添加相關(guān)代碼
var version = "{{VERSION}}" console.log("版本 v" + version)
打包的結(jié)果
var version = "1.0.0"; console.log("版本 v" + version);demo12 使用rollup的API
有時(shí)候我們會(huì)需要在打包的前后執(zhí)行一些其他的代碼,但是又不想引入其他構(gòu)建工具(例如gulp),那么就可以使用rollup提供的node API來編寫你自己的打包流程。
rollup模塊只提供了一個(gè)rollup函數(shù),這個(gè)函數(shù)的參數(shù)和我們編寫配置文件時(shí)導(dǎo)出的參數(shù)不同,減少了很多配置屬性,留下來的主要是一些輸入相關(guān)的配置。(具體的配置屬性可以查看rollup wiki的javascript API一節(jié))
執(zhí)行這個(gè)函數(shù)返回的是一個(gè)Promise,并且在then方法中提供一個(gè)bundle對象作為參數(shù),這個(gè)對象保存了rollup對源文件編譯一次之后的結(jié)果,而且提供了generate和write兩個(gè)方法
write方法提供了編譯并將打包結(jié)果輸出到文件里的功能,返回的是一個(gè)沒有參數(shù)的Promise,可以讓你自定義接下來執(zhí)行的代碼
generate方法是只提供了編譯的功能,返回一個(gè)Promise,這個(gè)Promise有一個(gè)對象參數(shù),包含了code(編譯完之后的代碼)和map(分析出來的sourceMap對象)兩個(gè)屬性,一般用在插件開發(fā)中
write和gengerate方法都接受有編譯相關(guān)屬性的對象作為傳入的編譯參數(shù),而write方法還額外接受dset屬性作為導(dǎo)出文件的名稱。
在這里我們只使用write方法來編寫一個(gè)為所有模塊類型打包,并輸出打包完畢提示的文件,至于generate的使用方法我們會(huì)放在編寫插件一節(jié)中介紹。
const rollup = require("rollup").rollup rollup({ entry: "index.js" }).then(bundle => { // 保存所有Promise的列表 let writePromiseList = [] // 聲明所有需要打包的模塊類型 let moduleTypesList = ["es","cjs","amd","umd","iife"] moduleTypesList.forEach(function(moduleType) { writePromiseList.push(bundle.write({ dest: "./dist/dist." + moduleType + ".js", format: moduleType, sourceMap: true })) }) return Promise.all(writePromiseList) }).then(() => { console.log("全部模塊格式打包完畢") // 其他代碼 })
將package.json文件內(nèi)的npm scripts命令修改為
"build": "node rollup.js"
執(zhí)行打包命令,查看打包結(jié)果
在這里我們可以看到,一個(gè)bundle可以被重復(fù)使用多次,因此我們可以用Promise.all方法來等待所有模塊打包完成后再輸出打包完畢的提示。
demo13 除了打包JS,我們還能……一個(gè)web項(xiàng)目內(nèi)肯定不會(huì)只有js文件,還有css、html(也可能是模板文件)和其他類型的文件,那么我們在打包的時(shí)候能不能把這些文件一起打包呢?
我們需要區(qū)分一下,在這里的打包有兩種意思,一種是讓這些文件可以像JS文件一樣,在源代碼中被import并使用;還有一種是通過在源文件中import這些文件,最后將它們合并到一起并導(dǎo)出到一個(gè)最終文件內(nèi)。
不同的rollup插件有不同的效果,在使用的時(shí)候一定要查看插件的相關(guān)說明
安裝插件
npm i rollup-plugin-scss --save-dev // or yarn add rollup-plugin-scss --dev
編寫配置文件
import scss from "rollup-plugin-scss" export default { entry: "./src/js/index.js", format: "iife", dest: "./dist/js/dist.js", sourceMap: true, plugins: [ scss({ output: "./dist/css/style.css" }) ] }
在這里我們嘗試編譯和打包scss文件,將其合并成一個(gè)style.css文件,并輸出到dist/css目錄下
編寫scss文件
$blue: #69c4eb; .bg-blue { background-color: $blue }
$white: #fff; .text-white { color: $white; }
然后在源文件中引用這兩個(gè)scss文件
import "../scss/text.scss" import "../scss/bg.scss" var html = `` document.body.innerHTML = html測試文字
執(zhí)行打包命令,查看效果
extra 編寫你自己的rollup插件有時(shí)候我們可能需要自己編寫rollup插件來實(shí)現(xiàn)需求,rollup官方在wiki上提供了關(guān)于編寫插件的一些介紹,下面我們就根據(jù)這些介紹來寫一個(gè)自己的rollup插件。
我們在這里仿照scss插件編寫一個(gè)stylus的rollup插件,讓使用者可以import stylus文件,并編譯打包導(dǎo)出到指定的目錄下(為了節(jié)省代碼量,只寫了輸出到指定路徑的功能代碼,其他的功能可以參考scss插件的具體代碼)。
首先創(chuàng)建項(xiàng)目,在package.json文件中,除了一般信息之外,還要加上
"main": "index.cjs.js", "module": "index.es.js", "jsnext:main": "index.es.js"
這些信息用來區(qū)分使用不同模塊規(guī)范時(shí)使用的文件
安裝我們需要用到的模塊
npm i rollup rollup-plugin-babel babel-preset-es2015-rollup babel-core --save-dev npm i rollup-pluginutils stylus --save // or yarn add rollup rollup-plugin-babel babel-preset-es2015-rollup babel-core --dev yarn add rollup-pluginutils stylus
rollup-pluginutils和stylus是我們運(yùn)行時(shí)需要的兩個(gè)模塊,stylus用來解析stylus文件,pluginutils則提供給了我們一些編寫插件常用的函數(shù)
編寫rollup配置文件
import babel from "rollup-plugin-babel" export default { entry: "./index.es.js", dest: "./index.cjs.js", format: "cjs", plugins: [ babel() ] }
rollup插件需要一個(gè)含有指定屬性的對象作為插件內(nèi)容,rollup官方建議我們在編寫插件的時(shí)候,export一個(gè)返回值為插件對象的函數(shù),這樣可以方便使用者指定插件的參數(shù)。
rollup會(huì)將解析的部分結(jié)果作為參數(shù)調(diào)用插件返回的對象中的一些函數(shù)屬性,這些函數(shù)會(huì)在合適的時(shí)候被rollup調(diào)用(相當(dāng)于rollup在執(zhí)行各個(gè)操作時(shí)的鉤子函數(shù)),下面我們介紹一些常用的屬性:
name:插件的名稱,提供給rollup進(jìn)行相關(guān)信息的輸出
load:不指定這個(gè)屬性時(shí),解析模塊會(huì)默認(rèn)去讀取對應(yīng)路徑文件的內(nèi)容;而當(dāng)該值為函數(shù)(id => code)時(shí),可以將函數(shù)最后的返回值作為文件的內(nèi)容提供給rollup(可以用來生成自定義格式的代碼)
resolveId:一個(gè)( (importee, importer) => id)形式的函數(shù),用來解析ES6的import語句,最后需要返回一個(gè)模塊的id
transform:最常使用的屬性,是一個(gè)函數(shù),當(dāng)rollup解析一個(gè)import時(shí),會(huì)獲取到對應(yīng)路徑文件的內(nèi)容,并將內(nèi)容和模塊的名稱作為參數(shù)提供給我們;這個(gè)函數(shù)執(zhí)行完畢之后,需要返回一個(gè)作為代碼的字符串或是類似{ code, map }結(jié)構(gòu)的對象,用來表示解析完之后該模塊的實(shí)際內(nèi)容,map指的是sourceMap,而如果我們沒有要導(dǎo)出的sourceMap,就可以將返回的map值設(shè)為{mappings: ""}
ongenerate:當(dāng)我們或rollup調(diào)用generate方法時(shí),會(huì)被調(diào)用的一個(gè)鉤子函數(shù),接受generate的option作為參數(shù)
onwrite:和ongenerate一樣,調(diào)用write方法時(shí),會(huì)被調(diào)用的一個(gè)鉤子函數(shù),接受write的option作為參數(shù)
一般情況下,我們通過transform函數(shù)來獲取文件的id和內(nèi)容,并對內(nèi)容做一些處理,若需要輸出文件則使用ongenerate或onwrite在rollup打包的最后階段來做相應(yīng)的輸出。
load和resolveId在一般情況下不會(huì)使用,除非你有特殊的需求(例如對路徑、模塊id進(jìn)行修改等)
根據(jù)上面這些內(nèi)容,我們編寫具體的插件內(nèi)容
import { createFilter } from "rollup-pluginutils" import fs from "fs" import path from "path" import stylus from "stylus" // 遞歸創(chuàng)建文件夾 function mkdirs(dir) { return new Promise((resolve, reject) => { fs.exists(dir, (exist) => { if (exist) { resolve() } else { mkdirs(path.dirname(dir)).then(() => { fs.mkdir(dir, (err) => { if (err) { reject() } else { resolve() } }) }) } }) }) } // 導(dǎo)出一個(gè)function export default function stylusPlugin(options = {}) { // 創(chuàng)建一個(gè)文件過濾器,過濾以css,styl結(jié)尾的文件 const stylusFilter = createFilter(options.include || ["**/*.css", "**/*.styl"], options.exclude) // dest用來保存指定的輸出路徑 let dest = options.output, // styleNodes用來暫存不同文件的css代碼 styleNodes = {} // 編譯stylus文件 function complier(str, stylusOpt) { return new Promise((resolve, reject) => { stylus.render(str, stylusOpt, (err, css) => { if (err) { reject(err) } else { resolve(css) } }) }) } return { // 插件名稱 name: "rollup-plugin-stylus", // 解析import時(shí)調(diào)用,獲取文件名稱和具體代碼,將它們保存起來 transform (code, id) { if (!stylusFilter(id)) { return } styleNodes[id] = code return "" }, // generate時(shí)調(diào)用,用stylus解析代碼,并輸出到指定目錄中 async ongenerate (genOpt) { let css = "" for (let id in styleNodes) { // 合并所有css代碼 css += styleNodes[id] || "" } // 編譯stylus代碼 if (css.length) { try { css = await complier(css, Object.assign({}, options.stylusOpt)) } catch (error) { console.log(error) } } // 沒有指定輸出文件路徑時(shí),設(shè)置一個(gè)默認(rèn)文件 if (typeof dest !== "string") { if (!css.length) { return } dest = genOpt.dest || "bundle.js" if (dest.endsWith(".js")) { dest = dest.slice(0, -3) } dest = dest + ".css" } // 創(chuàng)建目錄,并將css寫入到結(jié)果文件內(nèi) await mkdirs(path.dirname(dest)) return new Promise((resolve, reject) => { fs.writeFile(dest, css, (err) => { if (err) { reject(err) } else { resolve() } }) }) } } }
這樣,一個(gè)解析并打包stylus文件的rollup插件就寫好了,你可以在你的工程中引用這個(gè)文件,也可以將其作為一個(gè)模塊發(fā)布,以便于分享給其他人使用。
總結(jié) and 一個(gè)完整的rollup項(xiàng)目的模板rollup在打包JS上是一個(gè)十分快捷方便的工具,但和webpack相比,他的生態(tài)圈還是不夠強(qiáng)大,對于大型web工程的適應(yīng)度相對不足
rollup的優(yōu)點(diǎn)在于方便的配置,天然的ES6模塊支持讓我們可以直接使用import和export語法,在打包JS上,不實(shí)現(xiàn)自己的模塊機(jī)制,而是使用目前常見的模塊規(guī)范有助于其他工具(例如requirejs)來引用打包文件;tree-shaking的特性也有助于減少代碼量,因此我認(rèn)為rollup比起構(gòu)建應(yīng)用工程項(xiàng)目,更適合用來構(gòu)建一個(gè)JS庫或node模塊
我將上面介紹的插件集合到一起,添加了測試的支持,制作了一個(gè)較為完整的rollup工程模板。放在rollup-project-template目錄下,需要的同學(xué)可以自?。阋部梢栽黾踊騽h除任意你需要的模塊,來組建屬于你自己的rollup項(xiàng)目模板)
參考資料rollup官方wiki
rollup插件合集
如何通過 Rollup.js 打包 JavaScript —— 知乎專欄
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87245.html
摘要:我寫過一些開源項(xiàng)目,在開源方面有一些經(jīng)驗(yàn),最近開到了阮老師的微博,深有感觸,現(xiàn)在一個(gè)開源項(xiàng)目涉及的東西確實(shí)挺多的,特別是對于新手來說非常不友好最近我寫了一個(gè),旨在從多方面快速幫大家搭建一個(gè)標(biāo)準(zhǔn)的庫,本文將已為例,介紹寫一個(gè)開源庫的知識 我寫過一些開源項(xiàng)目,在開源方面有一些經(jīng)驗(yàn),最近開到了阮老師的微博,深有感觸,現(xiàn)在一個(gè)開源項(xiàng)目涉及的東西確實(shí)挺多的,特別是對于新手來說非常不友好 show...
摘要:通過這個(gè)教程學(xué)習(xí)如何使用打包工具配合來取代或處理樣式文件。使用這個(gè)命令安裝插件更新。如果你沒有項(xiàng)目的副本,你可以通過這條命令克隆在結(jié)束這個(gè)狀態(tài)下的項(xiàng)目為添加監(jiān)聽插件。在代碼塊內(nèi),添加如下內(nèi)容簡單起見我省略了文件的大部分內(nèi)容 通過這個(gè)教程學(xué)習(xí)如何使用JavaScript打包工具Rollup配合PostCSS來取代Grunt或Gulp處理樣式文件。 上一篇文章中,我們完成了使用Rollup...
摘要:所以,打包工具就出現(xiàn)了,它可以幫助做這些繁瑣的工作。打包工具介紹僅介紹款主流的打包工具,,,,以發(fā)布時(shí)間為順序。它定位是模塊打包器,而屬于構(gòu)建工具。而且在其他的打包工具在處理非網(wǎng)頁文件比如等基本還是需要借助它來實(shí)現(xiàn)。 本文當(dāng)時(shí)寫在本地,發(fā)現(xiàn)換電腦很不是方便,在這里記錄下。 前端的打包工具 打包工具可以更好的管理html,css,javascript,使用可以錦上添花,不使用也沒關(guān)系...
摘要:平時(shí)有使用過和開發(fā)的同學(xué),應(yīng)該能體會(huì)到模塊化開發(fā)的好處。原因很簡單打包出來的使用了關(guān)鍵字,而小程序內(nèi)部并支持。是一個(gè)模塊打包器,可以將小塊代碼編譯成大塊復(fù)雜的代碼,例如或應(yīng)用程序。官網(wǎng)的這段介紹,正說明了就是用來打包的。 博客地址 最近有個(gè)需求,需要為小程序?qū)懸粋€(gè)SDK,監(jiān)控小程序的后臺接口調(diào)用和頁面報(bào)錯(cuò)(類似fundebug) 聽起來高大上的SDK,其實(shí)就是一個(gè)JS文件,類似平時(shí)開發(fā)...
摘要:既可以通過一個(gè)配置文件使用命令行接口來調(diào)用,也可以他自己的使用。使用最簡單的方法就是通過命令行接口。命令縮寫會(huì)以監(jiān)視模式運(yùn)行。這時(shí)運(yùn)行下將不會(huì)有錯(cuò)誤拋出,包含導(dǎo)入的組件。 介紹 概覽 rollup是一個(gè)js打包器,用來將很細(xì)碎的js編譯打包成大的復(fù)雜的東西,像是一個(gè)庫或者一個(gè)應(yīng)用。其使用了ES6自帶的新標(biāo)準(zhǔn)來格式化和打包js代碼,而不是原先的Commonjs或者AMD這類解決方案。ES...
閱讀 3411·2023-04-25 20:37
閱讀 3152·2021-09-07 09:59
閱讀 1675·2019-08-29 12:43
閱讀 1195·2019-08-28 18:27
閱讀 489·2019-08-26 13:50
閱讀 2041·2019-08-26 10:33
閱讀 3602·2019-08-23 18:39
閱讀 2411·2019-08-23 18:09