сводка от начала до упаковки библиотеки компонентов по запросу

rollup.js

В предыдущей статье мы научились упаковывать библиотеку компонентов с помощью webpack. На этот раз мы узнаем, как упаковать библиотеку компонентов с помощью rollup.

Упакуйте библиотеку компонентов vue по требованию с помощью webpack

rollup — это сборщик модулей JavaScript, который делает то же самое, что и функция webpack in, то есть компилирует небольшие фрагменты кода в большие сложные фрагменты кода, такие как библиотеки или приложения. При разработке приложений мы в основном используем webpack, в то время как rollup.js больше используется для упаковки библиотек, а знакомые vue, react, vuex, vue-router и т. д. — все упакованы с помощью rollup.

установка и использование накопительного пакета

Первый — установить:

npm i rollup -g        # 全局安装
npm i rollup -D        # 项目本地安装

упаковать файл js

Создайте новый проект следующим образом, установите накопительный пакет и создайте два файла: hello.js и index.js.

Если это глобальная установка, выполните ее непосредственно в корневом каталоге проекта:

rollup -i src/index.js -o dist/bundle.js -f es**

Если проект установлен локально, добавьте в поле скрипта package.json:

"dev": "rollup -i src/index.js -o dist/bundle.js -f es", затем выполнитеnpm run dev

Здесь мы возьмем локальную установку в качестве примера. Как показано ниже, rollup выводит результаты упаковки в командную строку.

В этой команде:

  • -iуказать файл для упаковки,-iда--inputаббревиатура от.
  • src/index.jsда-iпараметр, то есть файл записи пакета.
  • -oУказывает выходной файл, да--output.fileили--fileаббревиатура от. (Если этого параметра нет, он будет выведен прямо в консоль)
  • dist/bundle.jsда-oпараметр, выходной файл.
  • -fУказывает формат упакованного файла,-fда--formatаббревиатура от.
  • esда-fПараметр указывает, что упакованный файл использует спецификацию модуля ES6.

Форматы файлов пакетов, поддерживаемые накопительным пакетом: amd, cjs, es\esm, iife, umd. Среди них amd — это стандарт AMD, cjs — стандарт CommonJS, esm\es — стандарт модуля ES, iife — функция немедленного вызова, а umd поддерживает как amd, cjs, так и iife.

накопительный файл конфигурации

При разработке проектов мы обычно используем конфигурационные файлы, что не только упрощает работу с командной строкой, но и позволяет использовать расширенные функции объединения.

Создан в корневом каталоге проектаrollup.config.js.

export default {
  input: "./src/index.js",
  output: [
    {
      file: './dist/my-lib-umd.js',
      format: 'umd',
      name: 'myLib'   
      //当入口文件有export时,'umd'格式必须指定name
      //这样,在通过<script>标签引入时,才能通过name访问到export的内容。
    },
    {
      file: './dist/my-lib-es.js',
      format: 'es'
    },
    {
      file: './dist/my-lib-cjs.js',
      format: 'cjs'
    }
  ]
}

Используя файл конфигурации Rollup, вы можете использоватьrollup --configилиrollup -cинструкция.

//修改package.json的script字段

"dev": "rollup -c"                 // 默认使用rollup.config.js
"dev": "rollup -c my.config.js"    //使用自定义的配置文件,my.config.js

src/index.jsсодержание:

import { hello } from './hello'
hello()
export const world = 'world'

Упакованный файл: Видно, что для одного и того же файла записи размер файла формата es наименьший.

накопительный плагин

Мы знаем базовое использование свертки выше.В практических приложениях будет много более сложных требований, таких как поддержка синтаксиса es6, как упаковывать файлы .vue, как сжимать наш код js и так далее. В роллапе мы делаем это с помощью плагинов.

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

Некоторые часто используемые плагины.

rollup-plugin-babel

rollup-plugin-babelИспользуется для преобразования синтаксиса es6.

Будуsrc/hello.jsПерепишите содержимое в:

export const hello = () => {
  console.log('hello world')
}

Без использования плагина babel упакуйте результат:

Использование плагина babel:

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

//rollup.dev.js
import babel from 'rollup-plugin-babel'
export default {
  input: ...,
  output: ...,
  plugins:[
    babel({
        exclude: 'node_modules/**'
    })
  ]
}

Создан в корневом каталоге проекта.babelrcдокумент.

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

Упакуйте снова:

rollup-plugin-commonjs

Rollup не поддерживает модули CommonJS по умолчанию. При написании собственного вы можете попытаться избежать использования синтаксиса модуля CommonJS. Однако некоторые внешние библиотеки являются cjs или umd (упакованы webpack), поэтому вам необходимо поддерживать модули CommonJS, чтобы использовать их. внешние библиотеки.

создать новыйsrc/util.jsфайл со следующим содержимым:

module.exports = {
  a: 1
}

существуетsrc/index.jsвведен вutil.js

import util from './util'
console.log(util.a)

npm run devУпаковка сообщит об ошибке:

Это требует использованияrollup-plugin-commonjs,первый,npm i rollup-plugin-commonjs --D.

существуетrollup.config,jsДобавить в:

import commonjs from 'rollup-plugin-commonjs'
export default {
  input: ...,
  output: ...,
  plugins:[
    commonjs()
  ]
}

Опять такиnpm run devУпаковано, ошибок нет.

Мы также можем импортировать модули, используя require в нашем коде:

// src/index.js
const util = require('./util')
console.log(util.a)

rollup-plugin-commonjsСинтаксис require можно распознать и упаковать в синтаксис модуля es.Содержимое упакованного my-lib-es.js выглядит следующим образом:

var util = {
  a: 1
};

console.log(util.a);

var src = {

};

export default src;

rollup-plugin-postcss

Плагины, необходимые для обработки css,rollup-plugin-postcss. Он поддерживает загрузку файлов css, префиксы css, сжатие css, поддержку scss/less и многое другое.

Сначала установите,npm i rollup-plugin-postcss postcss --D, затем вrollup.config.jsСредняя конфигурация:

import postcss from 'rollup-plugin-postcss'
export default {
  input: ...,
  output: ...,
  plugins:[
    postcss()
  ]
}

Затем создайте новый файл test.css и импортируйте его в index.js.umd-файл, полученный после упаковки:

(function (factory) {
  typeof define === 'function' && define.amd ? define(factory) :
  factory();
}((function () { 'use strict';

  function styleInject(css, ref) {
    if ( ref === void 0 ) ref = {};
    var insertAt = ref.insertAt;

    if (!css || typeof document === 'undefined') { return; }

    var head = document.head || document.getElementsByTagName('head')[0];
    var style = document.createElement('style');
    style.type = 'text/css';

    if (insertAt === 'top') {
      if (head.firstChild) {
        head.insertBefore(style, head.firstChild);
      } else {
        head.appendChild(style);
      }
    } else {
      head.appendChild(style);
    }

    if (style.styleSheet) {
      style.styleSheet.cssText = css;
    } else {
      style.appendChild(document.createTextNode(css));
    }
  }

  var css_248z = "body{\r\n  color: green;\r\n}";
  styleInject(css_248z);

})));

Импортированный файл css будет использоваться для создания тега стиля, который будет вставлен в заголовок.

Мы создаем новый тестовый файл и импортируем файл umd. Вы можете видеть, что мы в головеtest.cssписьменное содержание.

<body>
  test css
</body>
<script src="../dist/my-lib-umd.js"></script>

css-префикс

с помощьюautoprefixerПлагин для префикса некоторых свойств CSS3. Установитьnpm i autoprefixer@8.0.0 --D, настроить:

import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
export default {
  input: ...,
  output: ...,
  plugins:[
    postcss({
      plugins: [  
        autoprefixer()  
      ]
    })
  ]
}

использоватьautoprefixerВ дополнение к вышеуказанной конфигурации вам также необходимо настроить browserslist.Есть два способа.Первый – создать файл .browserslistrc, а второй – настроить его непосредственно в package.json.Добавим поле «browserslist» в package. .json.

"browserslist": [
  "defaults",
  "not ie < 8",
  "last 2 versions",
  "> 1%",
  "iOS 7",
  "last 3 iOS versions"
]

Исправлятьtest.cssСодержание:

body{
  color: green;
  display: flex;
}

Package, обновите тестовую страницу прямо сейчас.

css-сжатие

cssnano сжимает упакованный CSS. Он также очень прост в использовании, как и автопрефиксер, установитеcssnano, затем настройте.

plugins:[
  postcss({
    plugins: [
      autoprefixer(),
      cssnano()
    ]
  })
]

Извлечь отдельные файлы css

rollup-plugin-postcssНастраивается, отделять ли css отдельно, по умолчанию нетextract, генерация стиля cssstyleТег встраивается в шапку, настраиваетсяextract, css будет извлечен в отдельный файл.

postcss({
  plugins: [
    autoprefixer(),
    cssnano()
  ],
  extract: 'css/index.css'  
})

Разумеется, упакованный css-файл тоже нужно вводить отдельно на страницу.

Поддержка scss/меньше

В реальных проектах мы вряд ли будем писать css напрямую, а будем использовать прекомпиляторы вроде scss или меньше.rollup-plugin-postcssПо умолчанию встроена поддержка scss, less и стилуса, в нашем проекте пока конфигурацияrollup-plugin-postcss, вы можете использовать эти прекомпиляторы css напрямую, что очень удобно.

rollup-plugin-vue

rollup-plugin-vue используется для обработки файлов .vue.Версии rollup-plugin-vue, используемые в проектах vue2 и vue3, разные, и компиляторы vue тоже разные..

  • vue2:rollup-plugin-vue^5.1.9 + vue-template-compiler
  • vue3:rollup-plugin-vue^6.0.0 + @vue/compiler-sfc

Возьмите vue2 в качестве примера:

npm i rollup-plugin-vue@5.1.9 vue-template-compiler --D

существуетrollup.dev.jsПрисоединяйсяrollup-plugin-vue

import vue from 'rollup-plugin-vue'
export default {
  ...
  plugins:[
    vue()
  ]
}

Создайте новый файл vue и измените егоsrc/index.js

npm run devУпаковка, давайте взглянем на сгенерированныйumdдокумент.

Тестовый umd-файл:

<body>
  <div id="app">
    <hello></hello>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="../dist/my-lib-umd.js"></script>
<script>
  Vue.use(myLib)
  new Vue({
    el: '#app'
  })
</script>

Компонент успешно используется, что указывает на то, что наша конфигурация может скомпилировать и упаковать файл .vue.

rollup-plugin-vueОн также по умолчанию поддерживает scss, less и стилус, которые можно использовать непосредственно в проекте. Чтобы автоматически добавить префикс css в файл .vue, он должен быть вrollup-plugin-vueв конфигурации. Дополнительная информация о конфигурацииrollup-plugin-vue

import vue from 'rollup-plugin-vue'
import autoprefixer from 'autoprefixer'  //同样要配置browserslist
import cssnano from 'cssnano'
export default {
  ...
  plugins:[
    vue({
      style: {
        postcssPlugins: [
          autoprefixer(),
          cssnano()
        ]
      }
    })
  ]
}

rollup-plugin-terser

В производственной среде сжатие кода имеет важное значение. Мы используемrollup-plugin-terserСжатие кода.

import { terser } from 'rollup-plugin-terser'
export default {
  ...
  plugins:[
    terser()
  ]
}

В приведенном выше процессе мы все упаковали файлы, а затем импортировали их через скрипт или ссылку npm, а затем отладили в других проектах, что больше похоже на метод отладки библиотеки компонентов. Если мы упаковываем приложение с накопительным пакетом, можно ли его обновлять в горячем режиме, как веб-пакет? Ответ положительный. Нам нужна помощьrollup-plugin-serveа такжеrollup-plugin-livereload.

rollup-plugin-serve, rollup-plugin-livereload

Эти два плагина часто используются вместе,rollup-plugin-serveзапустить сервер,rollup-plugin-livereloadОн используется для обновления страницы в режиме реального времени при изменении файла.

import serve from 'rollup-plugin-serve'
import livereload from 'rollup-plugin-livereload'
export default {
  ...
  plugins:[
    serve({
      contentBase: '',  //服务器启动的文件夹,默认是项目根目录,需要在该文件下创建index.html
      port: 8020   //端口号,默认10001
    }),    
    livereload('dist')   //watch dist目录,当目录中的文件发生变化时,刷新页面
  ]
}

Нам нужно вручную добавить упакованный файл, js или css в index.html, потому что в настоящее время нет автоматического внедрения. затем посетитеhttp://localhost:8020Вы можете увидеть содержимое в index.html.

Однако, когда файлы в src будут изменены в это время, страница не будет обновляться в реальном времени, потому что файлы в каталоге dist не обновляются. Для роллапа очень просто следить за изменениями исходных файлов, то есть при выполнении команды упаковки добавить-wили--watch

//package.json
"scripts": {
   "dev": "rollup -wc"
},

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

Упаковка библиотек компонентов по требованию

Это все, что нужно сделать, слишком просто упаковать компоненты загрузки по требованию.

Для проектов библиотек компонентов необходимо обеспечить поддержку загрузки по требованию: библиотека компонентов экспортируется модульным способом ES.Rollup изначально поддерживает экспорт модулей ES.

Создайте два новых компонента vue, hello и test:

Исправлятьsrc/index.js:

import Hello from "./components/Hello"
import Test from "./components/Test"
function install(Vue){
  Vue.use(Hello)
  Vue.use(Test)
}

/***
在es模块中, 能被按需引入的变量需要用这些方式导出:
export const a = 1
export function a(){}
export { a, b }
而不能使用export default
***/

export {    
  Hello,
  Test
}

export default install  //umd

Исправлятьrollup.config.jsследующим образом:

import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import vue from 'rollup-plugin-vue'
import autoprefixer from 'autoprefixer'
export default {
  input: "./src/index.js",
  output: [
    {
      file: './dist/my-lib-umd.js',
      format: 'umd',
      name: 'myLib'
    },
    {
      file: './dist/my-lib-es.js',
      format: 'es'
    },
    {
      file: './dist/my-lib-cjs.js',
      format: 'cjs'
    }
  ],
  plugins:[
    babel({
        exclude: 'node_modules/**'
    }),
    vue({
      style: {
        postcssPlugins: [
          autoprefixer()
        ]
      }
    }),
    commonjs()
  ],
  external:[  //外部库, 使用'umd'文件时需要先引入这个外部库
    'vue'
  ]
}

После упаковки измените package.json:

"main": "dist/my-lib-cjs.js",
"module": "dist/my-lib-es.js",

Затем вы можете протестировать его в тестовом проекте. Для получения подробной информации см.Как отлаживать библиотеки компонентов локально

import { Hello } from "my-lib-new"
Vue.use(Hello)

На этом мы закончили упаковку библиотеки компонентов, загружаемую по требованию, с помощью rollup.Общее ощущение намного удобнее, чем веб-пакет.При загрузке компонентов по требованию нам не нужно использовать плагины, что отлично подходит для упаковки библиотеки классов. .