Быстро освоить rollup.js за 10 минут — плагин rollup.js для предварительного обучения

внешний интерфейс JavaScript Vue.js rollup.js

предисловие

Эта статья«10 минут, чтобы быстро освоить rollup.js — углубленный анализ процесса упаковки исходного кода Vue.js»Учебное пособие на предварительное обучение, объясненные моменты знаний, направлены на понимание упакованного исходного кода Vue.js и не будут расширены слишком много. Учебное пособие будет поддерживать последовательный стиль уроков Rollupp.js. Большинство точек знаний будут предоставлять случаи знаний и фактические результаты выполнения, чтобы каждый мог видеть эффект осуществления через учебное пособие, сохраняя время для тестирования персональных компьютеров. Отказ

Чтобы изучить этот туториал, вам нужно понять назначение модулей buble, flow и terser.Для тех, кто еще не знает этого, вы можете проверить этот туториал:«Быстро освоить rollup.js за 10 минут — основы предварительного обучения»

1. Плагин сворачивания-плагина-бубле

Convert ES2015 with buble.

Плагин buble предназначен для компиляции кода в процессе упаковки rollup.js и компиляции кода ES6+ в стандарт ES 2015. Сначала в проект внедряется плагин buble:

npm i -D rollup-plugin-buble

Измените исходный код ./src/vue/buble/index.js и напишите следующее:

const a = 1 // ES6新特性:const
let b = 2 // ES6新特性:let
const c = () => a + b // ES6新特性:箭头函数
console.log(a, b, c())

Измените файл конфигурации rollup.plugin.config.js:

import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
import buble from 'rollup-plugin-buble'

export default {
  input: './src/vue/buble/index.js',
  output: [{
    file: './dist/index-plugin-cjs.js',
    format: 'cjs'
  }],
  plugins: [
    resolve(),
    commonjs(),
    buble()
  ]
}

Скомпилируйте с помощью rollup.js:

$ rollup -c rollup.plugin.config.js 
./src/vue/buble/index.js  ./dist/index-plugin-cjs.js...
created ./dist/index-plugin-cjs.js in 35ms

Просмотрите содержимое сгенерированного файла:

$ cat dist/index-plugin-cjs.js 
'use strict';

var a = 1;
var b = 2;
var c = function () { return a + b; };
console.log(a, b, c());

Выполните упакованный код через узел:

$ node dist/index-plugin-cjs.js 
1 2 3

2. Плагин rollup-plugin-alias

Provide an alias for modules in Rollup

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

npm i -D rollup-plugin-alias

Создайте каталог src/vue/alias и создайте локальную тестовую библиотеку lib.js и тестовый код index.js:

mkdir -p src/vue/alias
touch src/vue/alias/index.js
touch src/vue/alias/lib.js

Напишите в lib.js следующее:

export function square(n) {
  return n * n
}

Напишите в index.js следующее:

import { square } from '@/vue/alias/lib' // 使用别名

console.log(square(2))

Измените файл конфигурации для rollup.plugin.config.js:

import alias from 'rollup-plugin-alias'
import path from 'path'

const pathResolve = p => path.resolve(__dirname, p)

export default {
  input: './src/vue/alias/index.js',
  output: [{
    file: './dist/index-plugin-es.js',
    format: 'es'
  }],
  plugins: [
    alias({
      '@': pathResolve('src')
    })
  ]
}

Здесь мы предоставляем метод pathResolve для создания абсолютного пути. В плагине псевдонима мы передаем объект в качестве параметра. Ключ объекта — это псевдоним, используемый в модуле, а значение объекта — реальный путь, соответствующий к псевдониму. Упаковка с помощью rollup.js:

$ rollup -c rollup.plugin.config.js 

./src/vue/alias/index.js  ./dist/index-plugin-es.js...
created ./dist/index-plugin-es.js in 23ms

Глядя на упакованный код, вы можете видеть, что путь, соответствующий псевдониму, идентифицирован правильно:

$ cat dist/index-plugin-es.js 
function square(n) {
  return n * n
}

console.log(square(2));

3. плагин rollup-plugin-flow-no-whitespace

Плагин потока используется для очистки кода части проверки типа потока в процессе упаковки rollup.js Мы модифицируем свойство input rollup.plugin.config.js:

input: './src/vue/flow/index.js',

Попробуйте упаковать код потока напрямую:

$ rollup -c rollup.plugin.config.js 

./src/vue/flow/index.js  ./dist/index-plugin-cjs.js...
[!] Error: Unexpected token
src/vue/flow/index.js (2:17)
1: /* @flow */
2: function square(n: number): number {
                    ^
3:   return n * n
4: }
Error: Unexpected token

Вы можете видеть, что rollup.js выдает исключение.Чтобы решить эту проблему, мы вводим плагин потока:

npm i -D rollup-plugin-flow-no-whitespace

Измените файл конфигурации:

import flow from 'rollup-plugin-flow-no-whitespace'

export default {
  input: './src/vue/flow/index.js',
  output: [{
    file: './dist/index-plugin-cjs.js',
    format: 'cjs'
  }],
  plugins: [
    flow()
  ]
}

Повторная упаковка:

$ rollup -c rollup.plugin.config.js 
./src/vue/flow/index.js  ./dist/index-plugin-cjs.js...
created ./dist/index-plugin-cjs.js in 40ms

Просмотрите упакованный исходный код:

$ cat ./dist/index-plugin-cjs.js 
'use strict';

/*  */
function square(n) {
  return n * n
}

console.log(square(2));

Видно, что код потока успешно очищается, но/* @flow */был изменен на/* */, мы можем использовать плагин terser, чтобы решить эту проблему и удалить комментарии.

4. свернуть-плагин-заменить плагин

Replace content while bundling

Плагин замены предназначен для динамической замены содержимого в коде во время упаковки.Во-первых, вводится плагин замены:

npm i -D rollup-plugin-replace

Создайте папку src/vue/replace и тестовый файл index.js:

mkdir -p src/vue/replace
touch src/vue/replace/index.js

Напишите в файле index.js следующее:

const a = 1
let b = 2
if (__SAM__) { // 使用replace值__SAM__,注意这个值没有定义,如果直接运行会报错
  console.log(`__SAM__,${a},${b},${c}`) // 使用__SAM__,打包时会被替换
}

Измените файл конфигурации rollup.plugin.config.js:

import buble from 'rollup-plugin-buble'
import replace from 'rollup-plugin-replace'

export default {
  input: './src/vue/replace/index.js',
  output: [{
    file: './dist/index-plugin-cjs.js',
    format: 'cjs'
  }],
  plugins: [
    replace({
      __SAM__: true
    }),
    buble()
  ]
}

Передаем плагину замены объект, ключ __SAM__, значение true. Поэтому rollups.js заменит __SAM__ на true при упаковке. Стоит отметить, что в коде используются возможности ES6, поэтому для компиляции необходимо внедрить плагин bubble.Выполняем инструкции по упаковке:

$ rollup -c rollup.plugin.config.js 
./src/vue/replace/index.js  ./dist/index-plugin-cjs.js...
created ./dist/index-plugin-cjs.js in 28ms

Посмотрите результаты упаковки:

$ cat dist/index-plugin-cjs.js 
'use strict';

var a = 1;
var b = 2;
{
  console.log(("true," + a + "," + b + "," + c));
}

Вы можете видеть, что __SAM__ правильно заменено на true. Если вы используете редактор WebStorm, при использовании синтаксиса потока будет предупреждение, в это время нам нужно открыть настройки, перейти в «Языки и рамки» > «Javascript» и изменить версию языка Javascript на «Flow».

WebStorm flow配置
В дополнение к этому, использование __SAM__ также вызывает предупреждение.
类型错误
Решение этой проблемы — открыть flow/test.js и добавить пользовательскую переменную __SAM__ (объявить var), чтобы предупреждение исчезло:

declare type Test = {
  a?: number; // a的类型为number,可以为空
  b?: string; // b的类型为string,可以为空
  c: (key: string) => boolean; // c的类型为function,只能包含一个参数,类型为string,返回值为boolean,注意c不能为空
}

declare var __SAM__: boolean; // 添加自定义变量

5. Плагин rollup-plugin-terser

Rollup plugin to minify generated es bundle

Плагин terser помогает нам добиться сжатия кода в процессе упаковки rollup.js.Во-первых, представлен плагин terser:

npm i -D rollup-plugin-terser

Измените исходный код src/vue/replace/index.js Здесь мы проводим комплексное тестирование и применяем все плагины, которые мы изучили ранее:

/* @flow */
import { square } from '@/vue/alias/lib' // 通过别名导入本地模块
import { random } from 'sam-test-data' // 导入es模块
import { a as cjsA } from 'sam-test-data-cjs' // 导入commonjs模块

const a: number = 1 // 通过flow进行类型检查
let b: number = 2 // 使用ES6新特性:let
const c: string = '' // 加入非ascii字符
if (__SAM__) { // 使用replace字符串
  console.log(`__SAM__,${a},${b},${c}`) // 使用ES6新特性``模板字符串
}
export default {
  a, b, c, d: __SAM__, square, random, cjsA
} // 导出ES模块

Мы хотим проверить следующие функции с помощью приведенного выше кода:

  • заменить плагин: __SAM__ в коде правильно заменен;
  • Плагин потока: правильно удалить код проверки типа потока;
  • Плагин buble: компилирует код ES6+ в ES2015;
  • Плагин псевдонима: замените псевдоним «@» в модуле на каталог «src»;
  • плагин commonjs: поддерживает модули CommonJS;
  • resovle plugin: объединить код внешнего модуля;
  • Плагин terser: минимальная упаковка кода.

Измените файл конфигурации rollup.plugin.config.js:

import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
import buble from 'rollup-plugin-buble'
import replace from 'rollup-plugin-replace'
import flow from 'rollup-plugin-flow-no-whitespace'
import { terser } from 'rollup-plugin-terser'
import alias from 'rollup-plugin-alias'
import path from 'path'

const pathResolve = p => path.resolve(__dirname, p)

export default {
  input: './src/vue/replace/index.js',
  output: [{
    file: './dist/index-plugin-es.js',
    format: 'es'
  }],
  plugins: [
    replace({
      __SAM__: true
    }),
    flow(),
    buble(),
    alias({
      '@': pathResolve('src')
    }),
    commonjs(),
    resolve(),
    terser({
      output: {
        ascii_only: true // 仅输出ascii字符
      },
      compress: {
        pure_funcs: ['console.log'] // 去掉console.log函数
      }
    }),
  ]
}

Метод настройки плагина terser в основном такой же, как и режим API.Код упаковки:

$ rollup -c rollup.plugin.config.js 
./src/vue/replace/index.js  ./dist/index-plugin-es.js...
created ./dist/index-plugin-es.js in 308ms

Просмотрите упакованный файл кода:

$ cat dist/index-plugin-es.js 
function square(a){return a*a}function random(a){return a&&a%1==0?Math.floor(Math.random()*a):0}var a$1=Math.floor(10*Math.random()),b$1=Math.floor(100*Math.random());function random$1(a){return a&&a%1==0?Math.floor(Math.random()*a):0}var _samTestDataCjs_0_0_1_samTestDataCjs={a:a$1,b:b$1,random:random$1},_samTestDataCjs_0_0_1_samTestDataCjs_1=_samTestDataCjs_0_0_1_samTestDataCjs.a,a$2=1,b$2=2,c="\ud83d\ude00",index={a:a$2,b:b$2,c:c,d:!0,square:square,random:random,cjsA:_samTestDataCjs_0_0_1_samTestDataCjs_1};export default index;

Вы видите, что все функции работают, попробуйте запустить код через babel-node:

$ babel-node 
> require('./dist/index-plugin-es')
{ default:
   { a: 1,
     b: 2,
     c: '',
     d: true,
     square: [Function: square],
     random: [Function: random],
     cjsA: 4 } }

Код выполняется успешно, указывая на то, что процесс упаковки прошел успешно.

6. конфигурация интро и аутро

Свойства intro и outro аналогичны свойствам баннера и нижнего колонтитула, о которых мы говорили ранее, и используются для добавления комментариев к коду. Так в чем же разница между этими четырьмя свойствами? Во-первых, давайте посмотрим на объяснение этих четырех свойств на официальном сайте rollup.js:

  • intro: Вставьте часть содержимого вверху внутри блока упакованного файла (внутри оболочки)
  • outro: Вставьте кусок контента в самый низ блока упакованного файла (внутри обертки)
  • баннер: Вставьте часть контента в самом верху за пределами блока упакованного файла (за пределами обертки)
  • нижний колонтитул: Вставьте часть содержимого в самом низу снаружи блока упакованного файла (за пределами обертки)

Проще говоря, комментарии, добавляемые интро и аутро, находятся внутри блока кода, а баннер и футер — снаружи.Вот пример модификации кода src/plugin/main.js:

const a = 1
console.log(a)
export default a

Измените конфигурацию rollup.config.js:

export default {
  input: './src/plugin/main.js',
  output: [{
    file: './dist/index-cjs.js',
    format: 'cjs',
    banner: '// this is banner',
    footer: '// this is footer',
    intro: '// this is a intro comment',
    outro: '// this is a outro comment',
  }]
}

Код упаковки:

$ rollup -c

./src/plugin/main.js  ./dist/index-cjs.js...
created ./dist/index-cjs.js in 11ms

Выходной результат:

$ cat dist/index-cjs.js 
// this is banner
'use strict';

// this is a intro comment

const a = 1;
console.log(a);

module.exports = a;

// this is a outro comment
// this is footer

Вы можете видеть, что аннотации баннера и нижнего колонтитула находятся на самом внешнем слое, в то время как аннотации вступления и завершения находятся во внутреннем слое, а аннотации вступления находятся под «строгим использованием», поэтому, если вы хотите обернуть некоторые элементы в самый внешний слой кода, такой как module.exports или Например, необходимо использовать export default, intro и outro, а intro и outro используются для добавления модульности в код во время процесса упаковки исходного кода Vue.js. Мы также можем записать конфигурацию вступления и завершения в метод plugins для достижения этой функции:

export default {
  input: './src/plugin/main.js',
  output: [{
    file: './dist/index-cjs.js',
    format: 'cjs',
    banner: '// this is banner',
    footer: '// this is footer'
  }],
  plugins: [
    {
      intro: '// this is a intro comment',
      outro: '// this is a outro comment'
    }
  ]
}

Эффект, создаваемый этим файлом конфигурации, точно такой же, как и раньше.

Суммировать

В этом руководстве в основном объясняются следующие моменты знаний:

  • Плагин rollup-plugin-buble: компилирует синтаксис ES6+ в ES2015, не требует настройки, легче, чем Babel;
  • Плагин rollup-plugin-alias: заменить псевдонимы в путях к модулям;
  • Плагин rollup-plugin-flow-no-whitespace: удалить код проверки статического типа потока;
  • rollup-plugin-replace plugin: заменить переменную в коде на указанное значение;
  • Плагин rollup-plugin-terser: сжатие кода, замена uglify, поддержка модулей ES.
  • конфигурация вступления и выхода: добавьте комментарии к коду внутри блоков кода.