深入學習rollup來進行打包 原

深入學習rollup來進行打包

閱讀目錄

回到頂部

一:什麼是Rollup?

  rollup是一款用來es6模塊打包代碼的構建工具(支持css和js打包)。當我們使用ES6模塊編寫應用或者庫時,它可以打包成一個單獨文件提供瀏覽器和Node.js來使用。
它的優點有如下
  1. 能組合我們的腳本文件。
  2. 移除未使用的代碼(僅僅使用ES6語法中)。
  3. 在瀏覽器中支持使用 Node modules。
  4. 壓縮文件代碼使文件大小儘可能最小化。

Rollup最主要的優點是 它是基於ES2015模塊的,相比於webpack或Browserify所使用的CommonJS模塊更加有效率,因爲Rollup使用一種叫做
tree-shaking的特性來移除模塊中未使用的代碼,這也就是說當我們引用一個庫的時候,我們只用到一個庫的某一段的代碼的時候,它不會把所有的代碼打包進來,而僅僅打包使用到的代碼(webpack2.0+貌似也引入了tree-shaking)。

注意:Rollup只會在ES6模塊中支持tree-shaking特性。目前按照CommonJS模塊編寫的jquery不能被支持tree-shaking.

rollup 的應用場景

現在目前流行的打包有 gulp 和 webpack,那麼與前面兩個對比,我覺得rollup更適合打包js庫,但是對於打包一個項目的整個應用的話,我到覺得webpack更適合,比如打包一些圖片,字體等資源文件的時候,webpack很適合,目前貌似沒有看到rollup可以做到這些。
之所以我來研究rollup,是因爲最近在看vuex的源碼的時候,看到它的js庫就是使用rollup來進行打包的。

回到頂部

二:如何使用Rollup來處理並打包JS文件?

2-1 安裝Rollup並創建配置文件,通過如下命令安裝:
      進入項目根目錄後,運行命令: npm install --save-dev rollup

2-2 在項目的根目錄下新建一個新文件 rollup.config.js, 之後再在文件中添加如下代碼:

複製代碼

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  }
}

複製代碼

下面再來了解一下各個配置的含義:
input: rollup先執行的入口文件。
output:rollup 輸出的文件。
output.format: rollup支持的多種輸出格式(有amd,cjs, es, iife 和 umd, 具體看 http://www.cnblogs.com/tugenhua0707/p/8150915.html)
sourceMap —— 如果有 sourcemap 的話,那麼在調試代碼時會提供很大的幫助,這個選項會在生成文件中添加 sourcemap,來讓事情變得更加簡單。

我們在package.json代碼下 添加如下腳本。

"scripts": {
  "build": "rollup -c"
}

因此我們只要在命令行中 輸入命令:npm run build 即可完成打包;

我們再看下各個文件下的代碼:

src/js/a.js 代碼如下:

複製代碼

export function a(name) {
  const temp = `Hello, ${name}!`;
  return temp;
}
export function b(name) {
  const temp = `Later, ${name}!`;
  return temp;
}

複製代碼

src/js/b.js代碼如下:

複製代碼

/**
 * Adds all the values in an array.
 * @param  {Array} arr an array of numbers
 * @return {Number}    the sum of all the array values
 */
const addArray = arr => {
  const result = arr.reduce((a, b) => a + b, 0);
  return result;
};
export default addArray;

複製代碼

src/main.js代碼如下:

複製代碼

import { a } from './js/a';
import addArray from './js/b';

const res1 = a('kongzhi');
const res2 = addArray([1, 2, 3, 4]);

console.log(res1);
console.log(res2);

複製代碼

最終會在項目的根目錄下生成文件 dist/js/main.min.js, 代碼如下:

複製代碼

(function () {
'use strict';

function a(name) {
  const temp = `Hello, ${name}!`;
  return temp;
}

/**
 * Adds all the values in an array.
 * @param  {Array} arr an array of numbers
 * @return {Number}    the sum of all the array values
 */
const addArray = arr => {
  const result = arr.reduce((a, b) => a + b, 0);
  return result;
};

const res1 = a('kongzhi');
const res2 = addArray([1, 2, 3, 4]);

console.log(res1);
console.log(res2);

}());

複製代碼

如上可以看到 在 src/js/a.js 下的 b函數沒有被使用到,所以打包的時候沒有被打包進來。

注意:在上面代碼打包後,只有現代瀏覽器會正常工作,如果要讓不支持ES2015的舊版本瀏覽器下也正常工作的話,我們需要添加一些插件。

回到頂部

三:設置Babel來使舊瀏覽器也支持ES6的代碼

如上打包後的代碼,我們可以在現代瀏覽器下運行了,但是如果我們使用老版本的瀏覽器的話,就會產生錯誤。幸運的是,Babel已經提供了支持。
我們首先需要安裝一些依賴項如下命令:

npm install --save-dev 
babel-core babel-preset-env babel-plugin-external-helpers 
babel-plugin-transform-runtime babel-preset-stage-2 
babel-register rollup-plugin-babel

注意:Babel preset 是一個有關Babel插件的集合,它會告訴Babel我們需要轉譯什麼。

3.2 創建 .babelrc文件

接下來需要在項目的根目錄下創建 .babelrc的新文件了,它內部添加如下JSON代碼:

複製代碼

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-runtime", "external-helpers"]  // 配置runtime,不設置會報錯
}

複製代碼

它會告訴Babel應該使用哪種preset來轉譯代碼。

因此我們再更新下 rollup.config.js,我們需要Babel插件,將它添加到一個新的配置選項plugins中,他會管控一個數組形式的插件列表,代碼如下:

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    babel({
      exclude: 'node_modules/**'  // 排除node_module下的所有文件
    })
  ]
}

複製代碼

爲了避免轉譯第三方腳本,我們需要設置一個 exclude 的配置選項來忽略掉 node_modules 目錄下的所有文件。安裝完成後,我們重新運行命令;然後打包後代碼變成如下:

複製代碼

(function () {
'use strict';

function a(name) {
  var temp = "Hello, " + name + "!";
  return temp;
}

/**
 * Adds all the values in an array.
 * @param  {Array} arr an array of numbers
 * @return {Number}    the sum of all the array values
 */
var addArray = function addArray(arr) {
  var result = arr.reduce(function (a, b) {
    return a + b;
  }, 0);
  return result;
};

var res1 = a('kongzhi');
var res2 = addArray([1, 2, 3, 4]);

console.log(res1);
console.log(res2);

}());

複製代碼

我們對比下代碼,可以看到 addArray 的箭頭函數解析成真正的函數了。 在轉譯運行完成後,代碼也差不多一樣的,只是代碼已經支持
了IE9之前的瀏覽器了。

注意: Babel也提供了 babel-polyfill, 也可以讓IE8之前的瀏覽器能夠順利執行。

回到頂部

四:添加一個debug包來記錄日誌

 爲了查看日誌,我們將在代碼中添加一個debug包來記錄下日誌信息。通過如下命令安裝:

npm install --save debug

然後我們可以在 src/main.js中,添加一些簡單的日誌記錄:如下代碼:

複製代碼

import { a } from './js/a';
import addArray from './js/b';
import debug from 'debug';
const log = debug('app:log');

// Enable the logger.
debug.enable('*');
log('Logging is enabled!');

const res1 = a('kongzhi');
const res2 = addArray([1, 2, 3, 4]);

// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${res1}\n\n`;
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${res2}`;

複製代碼

index.html 代碼變成如下:

複製代碼

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport"
        content="width=device-width,minimum-scale=1,initial-scale=1">
  <title>Learning Rollup</title>
</head>
<body>

  <h1>Learning Rollup</h1>
  <p>
    Let’s learn how to use <a href="http://rollupjs.org/">Rollup</a>.
  </p>

  <!-- JS-generated output will be added here. -->
  <pre class="debug"><code class="debug__output"></code></pre>

  <!-- This is the bundle generated by rollup.js -->
  <script src="./dist/js/main.min.js"></script>

</body>
</html>

複製代碼

然後我們直接訪問index.html後,瀏覽器控制檯報錯了,錯誤信息如下:
Uncaught ReferenceError: debug is not defined,然後我們可以繼續查看,打包後的main.min.js的代碼變爲如下:

複製代碼

(function (debug) {
'use strict';

debug = debug && debug.hasOwnProperty('default') ? debug['default'] : debug;

function a(name) {
  var temp = "Hello, " + name + "!";
  return temp;
}

/**
 * Adds all the values in an array.
 * @param  {Array} arr an array of numbers
 * @return {Number}    the sum of all the array values
 */
var addArray = function addArray(arr) {
  var result = arr.reduce(function (a, b) {
    return a + b;
  }, 0);
  return result;
};

var log = debug('app:log');

// Enable the logger.
debug.enable('*');
log('Logging is enabled!');

var res1 = a('kongzhi');
var res2 = addArray([1, 2, 3, 4]);

// Print the results on the page.
var printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = 'sayHelloTo(\'Jason\') => ' + res1 + '\n\n';
printTarget.innerText += 'addArray([1, 2, 3, 4]) => ' + res2;

}(debug));

複製代碼

也就是說 瀏覽器報錯是因爲打包後的debug是 undefined,這是因爲一般的情況下,第三方node模塊並不會被Rollup正確加載。
Node模塊使用的是CommonJS, 它不會被Rollup兼容因此不能直接被使用,爲了解決這個問題,我們需要添加一些插件來
處理Node依賴和CommonJS模塊。
爲了解決上面的兩個問題,我們需要在Rollup中添加如下兩個插件:
1. rollup-plugin-node-resolve 該插件會允許加載在 node_modules中的第三方模塊。
2. rollup-plugin-commonjs 它會將CommonJS模塊轉換爲ES6來爲Rollup獲得兼容。

因此如下命令即可安裝:

npm install --save-dev rollup-plugin-node-resolve rollup-plugin-commonjs

然後我們繼續更新下 rollup.config.js 代碼如下:

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    resolve({
      jsnext: true,  // 該屬性是指定將Node包轉換爲ES2015模塊
      // main 和 browser 屬性將使插件決定將那些文件應用到bundle中
      main: true,  // Default: true 
      browser: true // Default: false
    }),
    commonjs(),
    json(),
    babel({
      exclude: 'node_modules/**'  // 排除node_modules 下的文件
    })
  ]
}

複製代碼

到目前爲止一切順利,但是當我們運行index.html時候, rollup 時我們會得到一個日誌信息:

在控制檯如下日誌信息:
app:log Logging is enabled! +0ms

index.html 頁面上顯示如下:

複製代碼

Learning Rollup
Let’s learn how to use Rollup.

sayHelloTo('Jason') => Hello, kongzhi!

addArray([1, 2, 3, 4]) => 10

複製代碼

如上代碼,我們看到引入了 rollup-plugin-json 插件了,該插件的作用是讀取json信息的,比如我讀取package.json的信息:

然後我把main.js中引入對應代碼。代碼如下:

複製代碼

import { a } from './js/a';
import addArray from './js/b';
import debug from 'debug';

// 添加json
import pkg from '../package.json';
console.log( `running version ${pkg.version}` ); // 控制檯輸出 running version 1.0.0

const log = debug('app:log');

// Enable the logger.
debug.enable('*');
log('Logging is enabled!');

const res1 = a('kongzhi');
const res2 = addArray([1, 2, 3, 4]);

// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${res1}\n\n`;
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${res2}`;

複製代碼

在控制檯輸出如下信息:
控制檯輸出 running version 1.0.0

回到頂部

五:添加插件來替代環境變量

 環境變量能爲我們的開發流程提供很大的幫助,我們可以通過它來執行關閉或開啓日誌,注入開發環境腳本等功能。
因此我們可以在main.js中添加基礎配置的ENV。讓我們添加一個環境變量來使我們的日誌腳本只在非 production環境下才會執行
。如下main.js代碼:

複製代碼

import { a } from './js/a';
import addArray from './js/b';
import debug from 'debug';

// 添加json
import pkg from '../package.json';
console.log( `running version ${pkg.version}` ); // 控制檯輸出 running version 1.0.0

const log = debug('app:log');

// 如果是正式環境的話,不輸出日誌信息
if (ENV !== 'production') {
  // Enable the logger.
  debug.enable('*');
  log('Logging is enabled!');
} else {
  debug.disable();
}

const res1 = a('kongzhi');
const res2 = addArray([1, 2, 3, 4]);

// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${res1}\n\n`;
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${res2}`;

複製代碼

然後打包完成後,在瀏覽器查看 發現報錯了,如下錯誤信息:
Uncaught ReferenceError: ENV is not defined
這也很正常,因爲我們並沒有定義它,現在我們還需要一個插件來將我們的環境變量用到bundle中。

5-1 先安裝 rollup-plugin-replcae,該插件是一個用來查找和替換的工作,我們只需要找到目前的環境變量並且使用實際
的值替代就可以了。先安裝如下:
npm install --save-dev rollup-plugin-replace

然後我們再來更新一下 rollup.config.js, 配置是我們可以添加一個 key:value 的配對錶,key值是準備被替換的鍵,而value是將要被替換的值。

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    resolve({
      jsnext: true,  // 該屬性是指定將Node包轉換爲ES2015模塊
      // main 和 browser 屬性將使插件決定將那些文件應用到bundle中
      main: true,  // Default: true 
      browser: true // Default: false
    }),
    commonjs(),
    json(),
    babel({
      exclude: 'node_modules/**'  // 排除node_modules 下的文件
    }),
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV || 'development')
    })
  ]
}

複製代碼

當我們現在運行 npm run build 的時候還是有日誌信息的,因爲默認的環境就是 development, 但是當我們在命令
行中使用如下命令:`NODE_ENV=production ./node_modules/.bin/rollup -c`(mac系統下的命令), 然後打包
後,刷新瀏覽器 就不會有日誌記錄信息了。
注意:在winodw環境下,運行如下命令: SET NODE_ENV=production ./node_modules/.bin/rollup -c

回到頂部

六:添加 UglifyJS來壓縮我們js的代碼

 安裝插件 rollup-plugin-uglify

命令如下安裝:
npm install --save-dev rollup-plugin-uglify

再在 rollup.config.js 配置代碼,爲了在開發中使代碼更具可讀性,我們只在生產環境壓縮代碼:
rollup.config.js配置代碼如下:

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify';

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    resolve({
      jsnext: true,  // 該屬性是指定將Node包轉換爲ES2015模塊
      // main 和 browser 屬性將使插件決定將那些文件應用到bundle中
      main: true,  // Default: true 
      browser: true // Default: false
    }),
    commonjs(),
    json(),
    babel({
      exclude: 'node_modules/**'  // 排除node_modules 下的文件
    }),
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV || 'development')
    }),
    (process.env.NODE_ENV === 'production' && uglify())
  ]
}

複製代碼

當我們在mac系統下運行命令 `NODE_ENV=production ./node_modules/.bin/rollup -c` 後,代碼被壓縮了,當我們運行
npm run build 的時候,代碼未被壓縮。

回到頂部

七:監聽文件變化的插件 --- rollup-watch

如下安裝命令:
npm install --save-dev rollup-watch

然後在package.json 中設置 scripts屬性即可:

"scripts": {
  "dev": "rollup -c -w",
  "build": "rollup -c"
}

當我們在 src/main.js 代碼下 加入一句代碼後 : console.log(1122); 然後在瀏覽器下刷新下即可在控制檯可以看到打印輸出 1122這樣的就可以監聽到了。不需要重新打包即可。

回到頂部

八:開啓本地服務的插件 --- rollup-plugin-serve

 安裝命令如下:

npm install --save-dev rollup-plugin-serve

在rollup.config.js 配置代碼如下:

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify';
import serve from 'rollup-plugin-serve';
export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    resolve({
      jsnext: true,  // 該屬性是指定將Node包轉換爲ES2015模塊
      // main 和 browser 屬性將使插件決定將那些文件應用到bundle中
      main: true,  // Default: true 
      browser: true // Default: false
    }),
    commonjs(),
    json(),
    babel({
      exclude: 'node_modules/**'  // 排除node_modules 下的文件
    }),
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV || 'development')
    }),
    (process.env.NODE_ENV === 'production' && uglify()),
    serve({
      open: true, // 是否打開瀏覽器
      contentBase: './', // 入口html的文件位置
      historyApiFallback: true, // Set to true to return index.html instead of 404
      host: 'localhost',
      port: 10001
    })
  ]
}

複製代碼

然後重啓命令 npm run build 就可以會自動打開 http://localhost:10001/ 頁面了。
注意: 這邊port配置的端口號是五位數,不是四位數。

回到頂部

九:實時刷新頁面 --- rollup-plugin-livereload

命令安裝如下:
npm install --save-dev rollup-plugin-livereload

注入LiveReload腳本
在LiveReload工作前,需要向頁面中注入一段腳本用於和LiveReload的服務器建立連接。
在src/main.js 中加入如下一段代碼:

// Enable LiveReload
document.write(
  '<script src="http://' + (location.host || 'localhost').split(':')[0] +
  ':35729/livereload.js?snipver=1"></' + 'script>'
);

src/main.js所有代碼如下:

複製代碼

import { a } from './js/a';
import addArray from './js/b';
import debug from 'debug';

// 添加json
import pkg from '../package.json';
console.log( `running version ${pkg.version}` ); // 控制檯輸出 running version 1.0.0

const log = debug('app:log');
// 如果不是正式環境的話,不輸出日誌信息
if (ENV !== 'production') {
  // Enable the logger.
  debug.enable('*');
  log('Logging is enabled!');
  // Enable LiveReload
  document.write(
    '<script src="http://' + (location.host || 'localhost').split(':')[0] +
    ':35729/livereload.js?snipver=1"></' + 'script>'
  );
} else {
  debug.disable();
}

const res1 = a('kongzhi');
const res2 = addArray([1, 2, 3, 4]);
console.log(1122)
// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${res1}\n\n`;
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${res2}`;

複製代碼

運行 LiveReload
LiveReload安裝好並且腳本注入到文檔中後,我們可以運行它去監聽build目錄:
如下命令:
./node_modules/.bin/livereload 'build/'

運行完成後 發現報錯了 Error: listen EADDRINUSE :::35729;通過百度才發現端口被佔用了,需要換端口,因此我直接把這個進程殺掉不就可以了,
首先我們先使用如下命令來查看下進程:
lsof -n -i4TCP:35729
看到信息如下:

COMMAND  PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node    1452 tugenhua   15u  IPv6 0xb0e27d409cc55a1b      0t0  TCP *:35729 (LISTEN)

運行如下命令殺掉:

kill -9 1452
再在命令行輸入 ./node_modules/.bin/livereload 'src/' 即可看到如下:

$ ./node_modules/.bin/livereload 'src/'
Starting LiveReload v0.6.3 for /Users/tugenhua/個人demo/vue1204/rollup-build/src on port 35729.

注意:./node_modules/.bin/livereload 'src/' 這句代碼的含義是 監聽src文件夾的文件,因此index.html內會
監聽到,我們可以打開 src/index.html後,然後在index.html修改內容後,保存一下就可以看到頁面會自動刷新內容了。

如上雖然改變 src/index.html的內容後會自動刷新頁面,但是感覺每次 都需要輸入 ./node_modules/.bin/livereload 'src/' 這麼一段命令,有點麻煩,因此我們可以在 package.json 腳本中來簡化這個過程,在package.json下scripts加上如下代碼:

"scripts": {
  "dev": "rollup -c -w",
  "build": "rollup -c",
  "reload": "livereload 'src/'"
},

當我們在命令行中 運行 npm run reload 也可以監聽到了。但是我們監聽不到 src/js 或 src/css 下的文件的變化,
因爲它不會自動打包,而只是監聽src下的文件變化而已。但是我們又不能同時打開 watcher 和 Livereload,會報錯端口被佔用的情況。
因此我們需要看第10條來解決這個問題哦;

回到頂部

十. 安裝同時運行watcher 和 Livereload的工具

 爲了能同時執行 Rollup和LiveReload, 我們需要使用一個叫做 npm-run-all 的工具。它的含義是一個終端可以執行多個任務。

安裝命令如下:
npm install --save-dev npm-run-all

然後我們要在package.json中再加入一條調用npm-run-all的腳本。在scripts代碼塊內,添加如下內容:

複製代碼

"scripts": {
  "dev": "rollup -c -w",
  "build": "rollup -c",
  "reload": "livereload 'src/'",
  "watch": "npm-run-all --parallel dev"
},

複製代碼

watch 就是新增的。因此我們可以在終端運行 npm run watch命令了,然後刷新瀏覽器(http://localhost:10002/src/index.html),改變一下js或者css,瀏覽器會自動加載更新後的代碼了。

回到頂部

十一. rollup+PostCSS打包樣式文件並添加 LiveReload

 1. 在main.js中加載樣式: 在main.js 中加入如下代碼:

複製代碼

// Import styles (automatically injected into <head>).
import './css/index.css';
所有的代碼如下:
import './css/index.css';

import { a } from './js/a';
import addArray from './js/b';
import debug from 'debug';

// 添加json
import pkg from '../package.json';
console.log( `running version ${pkg.version}` ); // 控制檯輸出 running version 1.0.0

const log = debug('app:log');
// 如果不是正式環境的話,不輸出日誌信息
if (ENV !== 'production') {
  // Enable the logger.
  debug.enable('*');
  log('Logging is enabled!');
  // Enable LiveReload
  document.write(
    '<script src="http://' + (location.host || 'localhost').split(':')[0] +
    ':35729/livereload.js?snipver=1"></' + 'script>'
  );
} else {
  debug.disable();
}

const res1 = a('kongzhi222');
const res2 = addArray([1, 2, 3, 4]);
console.log(11222211)
// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${res1}\n\n`;
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${res2}`;

複製代碼

2. 安裝PostCss插件
首先需要安裝Rollup版本的PostCss插件,使用命令如下安裝:
npm install --save-dev rollup-plugin-postcss
然後 添加插件到 rollup.config.js中去:
添加代碼如下:

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify';
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';

// 新增的postcss
import postcss from 'rollup-plugin-postcss';

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    // 新增的postcss
    postcss({
      extensions: ['.css']
    }),
    resolve({
      jsnext: true,  // 該屬性是指定將Node包轉換爲ES2015模塊
      // main 和 browser 屬性將使插件決定將那些文件應用到bundle中
      main: true,  // Default: true 
      browser: true // Default: false
    }),
    commonjs(),
    json(),
    babel({
      exclude: 'node_modules/**'  // 排除node_modules 下的文件
    }),
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV || 'development')
    }),
    (process.env.NODE_ENV === 'production' && uglify()),
    serve({
      open: true, // 是否打開瀏覽器
      contentBase: './', // 入口html的文件位置
      historyApiFallback: true, // Set to true to return index.html instead of 404
      host: 'localhost',
      port: 10002
    }),
    livereload()
  ]
}

複製代碼

運行npm run build 後,可以看到生成的 dist/js/main.min.js 中的代碼,在文件開頭幾行,可以看到一個名叫__$styleInject()的新函數;
代碼如下:

複製代碼

function __$styleInject(css, returnValue) {
  if (typeof document === 'undefined') {
    return returnValue;
  }
  css = css || '';
  var head = document.head || document.getElementsByTagName('head')[0];
  var style = document.createElement('style');
  style.type = 'text/css';
  head.appendChild(style);
  
  if (style.styleSheet){
    style.styleSheet.cssText = css;
  } else {
    style.appendChild(document.createTextNode(css));
  }
  return returnValue;
}

複製代碼

這個函數創建了一個<style>元素並設置樣式,然後添加到文檔的<head>標籤中。
但現在這些樣式並沒有真正地被處理;PostCSS只是直接地傳輸了我們的樣式。讓我們添加一些需要的PostCSS插件,使得樣式能在目標瀏覽器上工作。

3. 安裝必要的 PostCSS插件
下面需要安裝四個插件,如下插件:

postcss-simple-vars 可以使用Sass風格的變量(e.g. myColor: #fff;,color:myColor: #fff;,color:myColor;)而不是冗長的CSS語法(e.g. :root {--myColor: #fff},color: var(--myColor))。
postcss-nested 允許使用嵌套規則。實際上我不用它寫嵌套規則;
postcss-cssnext 這個插件集使得大多數現代CSS語法(通過最新的CSS標準)可用,編譯後甚至可以在不支持新特性的舊瀏覽器中工作。
cssnano — 壓縮,減小輸出CSS文件大小。相當於JavaScript中對應的UglifyJS。

使用如下命令安裝即可:
npm install --save-dev postcss-simple-vars postcss-nested postcss-cssnext cssnano

我們再來更下 rollup.config.js 
現在我們可以在rollup.config.js 中引入 postcss插件了,在配置對象的plugins屬性上添加一個postcss。
如下代碼:

複製代碼

// Rollup plugins
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify';
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
// 新增 rollup-plugin-postcss 插件
import postcss from 'rollup-plugin-postcss';

// 新增 postcss plugins
import simplevars from 'postcss-simple-vars';
import nested from 'postcss-nested';
import cssnext from 'postcss-cssnext';
import cssnano from 'cssnano';

export default {
  input: './src/main.js',
  output: {
    file: './dist/js/main.min.js',
    format: 'iife'
  },
  plugins: [
    // 新增的
    postcss({
      extensions: ['.css'],
      plugins: [
        simplevars(),
        nested(),
        cssnext({ warnForDuplicates: false, }),
        cssnano()
      ]
    }),
    resolve({
      jsnext: true,  // 該屬性是指定將Node包轉換爲ES2015模塊
      // main 和 browser 屬性將使插件決定將那些文件應用到bundle中
      main: true,  // Default: true 
      browser: true // Default: false
    }),
    commonjs(),
    json(),
    babel({
      exclude: 'node_modules/**'  // 排除node_modules 下的文件
    }),
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV || 'development')
    }),
    (process.env.NODE_ENV === 'production' && uglify()),
    serve({
      open: true, // 是否打開瀏覽器
      contentBase: './', // 入口html的文件位置
      historyApiFallback: true, // Set to true to return index.html instead of 404
      host: 'localhost',
      port: 10002
    }),
    livereload()
  ]
}

複製代碼

現在我們再來運行 npm run build, 後再打開瀏覽器就可以看到了head裏面新增樣式了,並且已經壓縮的。

注意:在cssnext()中配置了{ warnForDuplicates: false }是因爲它和cssnano()都使用了Autoprefixer,會導致一個警告。 我們只需要知道它被執行了兩次(在這個例子中沒什麼壞處)並且取消了警告。

同理我們運行命令 npm run watch 後,修改css,也能實時加載到最新的css了。

更多可以查看rollup中文文檔

github項目rollup打包查看

 

ps:

 

rollup學習整理-1-api詳解(https://blog.csdn.net/mjzhang1993/article/details/78502154)

rollup學習整理-2-插件詳解(https://blog.csdn.net/mjzhang1993/article/details/78502168)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章