歷史上,JavaScript 一直沒有模塊(module)體系,沒法將一個大程序拆分紅互相依賴的小文件,再用簡單的方法拼裝起來。其餘語言都有這項功能,好比 Ruby 的require
、Python 的import
,甚至就連 CSS 都有@import
,可是 JavaScript 任何這方面的支持都沒有,這對開發大型的、複雜的項目造成了巨大障礙。html
在 ES6 以前,社區制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種。前者用於服務器,後者用於瀏覽器。ES6 在語言標準的層面上,實現了模塊功能,並且實現得至關簡單,徹底能夠取代 CommonJS 和 AMD 規範,成爲瀏覽器和服務器通用的模塊解決方案。前端
ES6 模塊的設計思想是儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時肯定這些東西。好比,CommonJS 模塊就是對象,輸入時必須查找對象屬性。git
一個模塊就是一個獨立的文件。該文件內部的全部變量,外部沒法獲取。es6
若是你但願外部可以讀取模塊內部的某個變量,就必須使用export
關鍵字導出該變量。想要是要其餘模塊導出的內容, 就必須使用 import
導入;github
導入的值不能從新分配,儘管導入的對象和數組能夠被修改(導出模塊,以及任何其餘的導入,都將受到該修改的影響)。在這種狀況下,它們的行爲與 const 聲明相似。shell
從源模塊導入其原始名稱的特定項目。npm
import { something } from './module.js';
複製代碼
從源模塊導入特定項,並在導入時指定自定義名稱。json
import { something as somethingElse } from './module.js';
複製代碼
將源模塊中的全部內容做爲對象導入,將全部源模塊的命名導出公開爲屬性和方法。默認導出被排除在此對象以外。數組
import as module from './module.js'
複製代碼
上面的 「something」 的例子將被附加到做爲屬性的導入對象上。「module.something」。瀏覽器
導入源文件的 默認導出
import something from './module.js';
複製代碼
加載模塊代碼,但不要建立任何新對象。
import './module.js';
複製代碼
這對於polyfills是有用的,或者當導入的代碼的主要目的是與原型有關的時候。
導出具體聲明的值:
var something = true;
export { something };
複製代碼
在導出時重命名:
export { something as somethingElse };
複製代碼
聲明後當即導出:
// 這能夠與 `var`, `let`, `const`, `class`, and `function` 配合使用
export var something = true;
複製代碼
導出一個值做爲源模塊的默認導出:
export default something;
複製代碼
僅當源模塊只有一個導出時,才建議使用此作法。
將默認和命名導出組合在同一模塊中是很差的作法,儘管它是規範容許的。
Rollup 是一個 JavaScript 模塊打包器,能夠將小塊代碼編譯成大塊複雜的代碼,。Rollup 對代碼模塊使用新的 ES Module 標準,而不是之前的社區模塊化方案,如 CommonJS 和 AMD。ES6 模塊已經被現代化瀏覽器原生實現,2020 年 Vue 做者發佈了 Vite ,定義爲下一代前端開發與構建工具,目的是取代依賴 Webpack 打包的各類構建工具,而 Vite 的模塊化工具使用的就是 Rollup;
使用 npm install --global rollup
進行安裝, 運行 rollup --help
能夠查看可用的選項和參數。
幫助信息中的提示中: Usage: rollup [options] <entry file>
就展現了 Rollup 的基本用法, 咱們準備三個文件 index.js 爲入口主文件, 而後使用 ES6 模塊化語法引入user.js 和 message.js 文件,並在mian.js 中使用兩個文件導出的數據內容;
// ======= index.js ============
import msg from './message'
import {names} from './user'
console.log(names())
console.log(msg)
console.log('Rollup Test Code')
// ======== message.js ===========
export default {
hi: 'Hey '
}
// ======== user.js ===========
export const names = () => {
console.log('xiling')
}
export const ages = () => {
console.log(666)
}
複製代碼
命令行終端執行: rollup index.js
$ rollup index.js
index.js → stdout...
var msg = {
hi: 'Hey '
};
const names = () => {
console.log('xiling');
};
console.log(names());
console.log(msg);
console.log('Rollup Test Code');
複製代碼
在命令終端中, 咱們能看到最終打包後的編譯代碼被打印出來了, 咱們須要的是將小塊的文件代碼打包到一個大的文件中, 想要實現效果,只須要在命令中添加指定的命令參數便可: rollup index.js --file bundle.js
,生成 bundle.js 文件,代碼以下:
var msg = {
hi: 'Hey '
};
const names = () => {
console.log('xiling');
};
console.log(names());
console.log(msg);
console.log('Rollup Test Code');
複製代碼
咱們看到,打包後的代碼很是簡潔,就是將須要運行的代碼,按照順序拼裝到一塊兒,注意,是隻會保留用到的代碼,這就是Rollup 最先提出的 Tree-shaking 特性,後來被幾乎因此打包工具參考引入;
什麼是 Tree-shaking 呢? 基本原理很是簡單, Rollup 在打包的過程當中, 靜態分析代碼中的 import,只引入最基本最精簡代碼, 並將排除任何未實際使用的代碼。因此能夠生成輕量、快速,以及低複雜度的 library 和應用程序。
咱們通常在命令行中使用 Rollup。你也能夠提供一份配置文件(可要可不要)來簡化命令行操做,同時還能啓用 Rollup 的高級特性, 配置文件是一個ES6模塊,它對外暴露一個對象,這個對象包含了一些Rollup須要的一些選項。一般,咱們把這個配置文件叫作rollup.config.js
,它一般位於項目的根目錄;
注意: Rollup 自己會處理配置文件,因此可使用 export default
語法——代碼不會通過 Babel 等相似工具編譯,因此只能使用所用 Node.js 版本支持的 ES2015 語法。
配置選項列表 : https://www.rollupjs.com/guide/big-list-of-options
// rollup.config.js
export default {
// 包的入口點 (例如:你的 main.js 或者 index.js)
input:'index.js',
// 出口配置
output:{
file:'budle.js', //打包到那個文件
format:'esm' // 生成包的格式
}
}
複製代碼
輸入 : input [string]: 'index.js' 這個包的入口點 (例如:你的 main.js
或者 app.js
或者 index.js
)
輸出 : output [object]:{}
output.file [string]: 'bundle.js' 要寫入的文件。也可用於生成 sourcemaps,若是適用
output.format [string] :'iife' 生成包的格式。 下列之一:
amd
– 異步模塊定義,用於像RequireJS這樣的模塊加載器cjs
– CommonJS,適用於 Node 和 Browserify/Webpackesm
– 將軟件包保存爲 ES 模塊文件,在現代瀏覽器中能夠經過 <script type=module>
標籤引入iife
– 一個自動執行的功能,適合做爲<script>
標籤。(若是要爲應用程序建立一個捆綁包,您可能想要使用它,由於它會使文件大小變小。)umd
– 通用模塊定義,以amd
,cjs
和 iife
爲一體system
- SystemJS 加載器格式若是你想使用Rollup的配置文件,記得在命令行里加上--config
或者-c
若是須要不一樣的配置,也能夠指定與默認 rollup.config.js
文件不一樣的配置文件:
rollup --config rollup.config.dev.js
rollup --config rollup.config.prod.js
複製代碼
目前爲止,咱們經過相對路徑,將一個入口文件和一個模塊建立成了一個簡單的 bundle。隨着構建更復雜的 bundle,一般須要更大的靈活性——引入 npm 安裝的模塊、經過 Babel 編譯代碼、和 JSON 文件打交道等。
爲此,咱們能夠用 插件(plugins) 在打包的關鍵過程當中更改 Rollup 的行爲;
Rollup 擁有很是豐富的插件體系,能夠去 插件列表: https://github.com/rollup/awesome 看一下;
這裏咱們將使用 rollup-plugin-json 插件,使 Rollup 可以讀取 JSON 文件中的數據。
將 rollup-plugin-json 安裝爲開發依賴,由於代碼實際執行時不依賴這個插件——只是在打包時使用:
npm install rollup-plugin-json -D
複製代碼
編輯 rollup.config.js
文件,加入 JSON 插件:
// 直接使用 ES module 導入插件
import json from 'rollup-plugin-json';
export default {
input:'./src/index.js',
output:{
file:'./dist/budle.js',
format:'iife',
},
// 插件導出的是一個函數,直接調用函數,
// 注意,是調用的結果直接給到 插件數組中
plugins: [ json() ]
}
複製代碼
更改 index.js 的代碼, 從 package.json 中讀取數據:
import msg from './message'
import { names } from './user'
import { name, version } from '../package.json';
console.log(`項目名稱:${name},項目版本:${version}`)
console.log(names())
console.log(msg)
console.log('Rollup Test Code')
複製代碼
打包事後的代碼, 只保留了 name 和 version 兩個內容, 這也就是 tree-shaking 起的做用。
做者: 西嶺老溼
參考來源 :