10-минутный быстрый старт Rollup.js

Node.js JavaScript Babel rollup.js

Зачем изучать rollup.js

rollup.js — это упаковщик модулей ES для Javascript.Многие известные фреймворки или библиотеки классов, такие как Vue и React, упаковываются с помощью rollup.js. В отличие от ориентации Webpack на упаковку приложений, rollup.js больше ориентирован на упаковку библиотеки Javascript (хотя rollup.js также может обеспечивать упаковку ресурсов, но, очевидно, это не его сильная сторона). Когда мы изучаем исходный код таких фреймворков, как Vue и React, или пишем свою собственную библиотеку Javascript, rollup.js — единственный путь.

Как работает rollup.js

rollup.js может упаковывать наш собственный код Javascript (с помощью плагинов, таких как Typescript, можно поддерживать больше языков) и сторонние модули для формирования файла, который может быть библиотекой или приложением. , в процессе упаковки , можно применять различные плагины для достижения определенных функций. На следующей диаграмме показано, как работает rollup.js:

rollup.js运行机制
rollup.js принимает стандарт модуля ES по умолчанию, и мы можем сделать так, чтобы он поддерживал стандарт CommonJS с помощью плагина rollup-plugin-commonjs.

Установите файл rollup.js

Установка rollup.js зависит от nodejs.В предыдущих заметках я подробно рассказал, как управлять версией nodejs через nvm.Для тех, кому нужно знать, вы можете нажатьздесь

Установите rollup.js глобально

Сначала установите накопительный пакет глобально:

npm i rollup -g

Пример упаковки rollup.js

После успешной установки мы пытаемся использовать rollup, чтобы сделать простой случай и создать каталог src:

mkdir src

Создайте a.js в каталоге src:

vim src/a.js

Напишите следующий код, этот модуль очень прост и предоставляет только переменную a:

const a = 1
export default a

Создайте main.js в каталоге src:

vim src/main.js

Напишите следующий код, этот модуль будет импортировать модуль a и предоставлять функцию:

import a from './a.js'
  
export default function() {
  console.log(a)
}

С помощью команды rollup мы можем быстро просмотреть упакованный исходный код, который очень похож на babel:

$ rollup src/main.js -f es

src/main.js  stdout...
const a = 1;

function main() {
  console.log(a);
}

export default main;
created stdout in 26ms

Следует отметить, что накопитель должен иметь-fпараметры, иначе будет сообщено об ошибке:

$ rollup src/main.js

src/main.js  stdout...
[!] Error: You must specify output.format, which can be one of 'amd', 'cjs', 'system', 'esm', 'iife' or 'umd'
https://rollupjs.org/guide/en#output-format-f-format

Отчет об ошибках свертки очень хорош, что очень помогает нам находить ошибки и устранять проблемы. Из приведенного выше сообщения об ошибке мы узнали, что-fЗначение может быть любым из 'amd', 'cjs', 'system', 'esm' (также работает 'es'), 'iife' или 'umd'.-fпараметр--formatАббревиатура , которая указывает формат сгенерированного кода, amd указывает на принятие стандарта AMD, cjs — это стандарт CommonJS, а esm (или es) — стандарт модуля ES. Затем мы выводим этот код в файл:

$ rollup src/main.js -f es -o dist/bundle.js

src/main.js  dist/bundle.js...
created dist/bundle.js in 29ms

параметр-oУказан выходной путь.Здесь мы выводим упакованный файл в bundle.js в каталог dist.Содержимое этого файла точно такое же, как и то, что мы просматривали ранее. Выведем другой код в формате CommonJS:

$ rollup src/main.js --format cjs --output.file dist/bundle-cjs.js

src/main.js  dist/bundle-cjs.js...
created dist/bundle-cjs.js in 27ms

параметр--output.fileда-oПолное название, они равнозначны, после вывода у нас будет дополнительный файл bundle-cjs.js в директории dist, проверяем содержимое этого файла:

'use strict';
  
const a = 1;

function main() {
  console.log(a);
}

module.exports = main;

Вы можете видеть, что код написан в стандарте CommonJS, а файлы a.js и main.js объединены.

Проверка результатов упаковки rollup.js

После успешной установки пакета пробуем запустить код dist/bundle-cjs.js:

$ node
> const m = require('./dist/bundle-cjs.js')
> m()
1 

Затем мы пытаемся запустить стандартный код ES dist/bundle.js перед выводом Поскольку nodejs не поддерживает стандарт ES, при прямом запуске будет сообщено об ошибке:

$ node
> require('./dist/bundle.js')()
/Users/sam/Desktop/rollup-test/dist/bundle.js:7
export default main;
^^^^^^

SyntaxError: Unexpected token export

Babel предоставляет нам инструмент: babel-node, который может конвертировать стандартный код ES в формат CommonJS во время выполнения, что позволяет запускать стандартный код ES.Во-первых, установите babel-node и связанные с ним инструменты глобально, @babel/ Node содержит babel- node, @babel/cli содержит babel, и оба инструмента зависят от @babel/core, поэтому рекомендуется установить оба:

npm i @babel/core @babel/node @babel/cli -g

Здесь следует отметить, что в babel 7 было изменено имя пакета npm, а предыдущие версии babel-core и babel-cli устарели, поэтому студенты, устанавливающие старую версию babel, предлагают сначала удалить ее:

npm uninstall babel-cli babel-core -g

Затем перейдите в корневой каталог кода и инициализируйте проект:

npm init

После всего пути входа создайте файл конфигурации babel .babelrc в корневом каталоге кода и напишите следующую конфигурацию

{
  "presets": ["@babel/preset-env"]
}

После завершения настройки Babel установите зависимости Babel:

npm i -D @babel/core @babel/preset-env

Попробуйте скомпилировать код через babel:

$ babel dist/bundle.js 
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var a = 1;

function main() {
  console.log(a);
}

var _default = main;
exports.default = _default;

Вы можете видеть, что код модуля ES скомпилирован в формат CommonJS под кодом запуска Babel-Node:

$ babel-node 
> require('./dist/bundle.js')
{ default: [Function: main] }
> require('./dist/bundle.js').default()
1

Обратите внимание, что Babel будет думатьexport default function()Это функция с именем default.Если вы хотите изменить имя этой функции, вы можете изменить main.js:

import a from './a.js'
  
export function test() {
  console.log(a)
}

Запускаем babel-node после перезаписи и упаковки:

$ rollup -f es --file dist/bundle.js src/main.js 

src/main.js  dist/bundle.js...
created dist/bundle.js in 26ms

$ babel-node 
> require('./dist/bundle.js').test()
1

Обратите внимание здесь--fileПо цене-oа также--output.file, В приведенном выше случае мы завершили основные операции по рулонной упаковке и проверили результаты упаковки. Но часто мы этого не делаем, потому что прямое использование командной строки единично, а плагин использовать нельзя, поэтому для работы нам нужно использовать конфигурационный файл.

Файл конфигурации rollup.js

Сначала создайте файл rollup.config.js в корневом каталоге кода:

touch rollup.config.js

Напишите следующую конфигурацию:

export default {
  input: './src/main.js',
  output: [{
    file: './dist/index-cjs.js',
    format: 'cjs',
    banner: '// welcome to imooc.com',
    footer: '// powered by sam'
  }, {
    file: './dist/index-es.js',
    format: 'es',
    banner: '// welcome to imooc.com',
    footer: '// powered by sam'
  }]
}

Файл конфигурации накопительного пакета очень прост для понимания, вот несколько моментов, на которые следует обратить внимание:

  • Файл конфигурации накопительного пакета должен быть написан в стандарте модуля ES.
  • input представляет собой путь к входному файлу (старая версия — это entry, от которой отказались)
  • output представляет содержимое выходного файла. Он позволяет передать объект или массив. Когда это массив, несколько файлов выводятся последовательно, и он содержит следующее содержимое:
    • output.file: путь к выходному файлу (старая версия — dest, которая устарела)
    • output.format: формат выходного файла
    • output.banner: контент, добавляемый в заголовок файла
    • output.footer: содержимое добавляется в конец файла

пройти черезrollup -cИнструкции упакованы, и rollup.js автоматически найдет файл конфигурации с именем rollup.config.js:

$ rollup -c

./src/main.js  ./dist/index-cjs.js, ./dist/index-es.js...
created ./dist/index-cjs.js, ./dist/index-es.js in 13ms

Проверьте файл dist/index-es.js:

// welcome to imooc.com
const a = 1;

function test() {
  console.log(a);
}

export { test };
// powered by sam

Содержимое кода такое же, как и в командной строке, но с добавлением пользовательских комментариев в начале и в конце. Затем мы изменяем имя файла конфигурации и передаем-cПараметр указывает файл конфигурации для упаковки:

$ mv rollup.config.js rollup.config.dev.js
$ rollup -c rollup.config.dev.js 

./src/main.js  ./dist/index-cjs.js, ./dist/index-es.js...
created ./dist/index-cjs.js, ./dist/index-es.js in 13ms

упаковка API rollup.js

Напишите конфигурацию rollup.js

Во многих случаях метод упаковки из командной строки и файла конфигурации не может удовлетворить требованиям, и нам нужен более персонализированный метод упаковки.В настоящее время мы можем рассмотреть возможность упаковки через API rollup.js и создать опции ввода-вывода. js, который является входной конфигурацией, мы инкапсулируем модуль отдельно, чтобы улучшить возможность повторного использования и масштабируемость:

touch rollup-input-options.js

Добавьте следующее содержимое во входной файл конфигурации.Следует отметить, что этот файл должен быть в формате CommonJS, потому что для выполнения необходимо использовать nodejs:

module.exports = {
  input: './src/main.js'
}

Добавьте еще один выходной файл конфигурации:

touch rollup-output-options.js

В выходном файле конфигурации мы по-прежнему используем массив для реализации вывода различных форматов файлов.Следует отметить, что формат umd должен указывать имя модуля, что достигается через атрибут name:

module.exports = [{
  file: './dist/index-cjs.js',
  format: 'cjs',
  banner: '// welcome to imooc.com',
  footer: '// powered by sam'
}, {
  file: './dist/index-es.js',
  format: 'es',
  banner: '// welcome to imooc.com',
  footer: '// powered by sam',
}, {
  file: './dist/index-amd.js',
  format: 'amd',
  banner: '// welcome to imooc.com',
  footer: '// powered by sam',
}, {
  file: './dist/index-umd.js',
  format: 'umd',
  name: 'sam-umd', // 指定文件名称
  banner: '// welcome to imooc.com',
  footer: '// powered by sam',
}]

Напишите код сборки rollup.js

Далее нам нужно установить накопительную библиотеку в текущем проекте:

npm i -D rollup

Создайте файл rollup-build и вызовите API-интерфейс rollup через этот файл:

touch rollup-build.js

Исходный код rollup-build выглядит следующим образом:

const rollup = require('rollup')
const inputOptions = require('./rollup-input-options')
const outputOptions = require('./rollup-output-options')

async function rollupBuild(input, output) {
  const bundle = await rollup.rollup(input) // 根据input配置进行打包
  console.log(`正在生成:${output.file}`)
  await bundle.write(output) // 根据output配置输出文件
  console.log(`${output.file}生成成功!`)
}

(async function () {
  for (let i = 0; i < outputOptions.length; i++) {
    await rollupBuild(inputOptions, outputOptions[i])
  }
})()

Ядро кода состоит из двух пунктов:

  • пройти черезrollup.rollup(input)получить объект пакета
  • пройти черезbundle.write(output)выходной файл пакета

Здесь мы также можем добиться синхронной работы через async и await, т.к.bundle.write(output)Он асинхронный и будет возвращать объект Promise.Мы можем использовать асинхронный механизм для реализации упаковки в порядке конфигурации. Запустите файл сборки-сборки:

$ node rollup-build.js 
正在生成:./dist/index-cjs.js
./dist/index-cjs.js生成成功!
正在生成:./dist/index-es.js
./dist/index-es.js生成成功!
正在生成:./dist/index-amd.js
./dist/index-amd.js生成成功!
正在生成:./dist/index-umd.js
./dist/index-umd.js生成成功!

Проверьте файл dist/index-umd.js:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (factory((global['sam-umd'] = {})));
}(this, (function (exports) {
	// ...
}

Вы можете видеть, что атрибут sam-umd добавлен в глобальную глобальную переменную в файле index-umd.js, поэтому нам нужно добавить атрибут name в конфигурацию umd раньше.

Суммировать

В этой статье представлены три метода упаковки rollup.js: командная строка, файл конфигурации и API. Назначение и использование различных плагинов будут подробно продемонстрированы, так что следите за обновлениями.