rollup упаковывает библиотеку компонентов реакции на основе antd

rollup.js

причина

  • Некоторое время назад компания занималась извлечением публичных компонентов и планировала сделать публичную библиотеку компонентов.Первоначальная идея заключалась в том, чтобы напрямую внедрить упакованные публичные компоненты в проект и использовать их.Позже выяснилось, что прямая ссылка будет сообщить об ошибке, что, вероятно, означает прямое введение нераспознанногоjsxсинтаксические ошибки.
  • Затем обратитесь к каждой готовой библиотеке классовantd,elementUIПрактика ожидания библиотеки пользовательского интерфейса упаковывается и генерируется для других проектов для внедрения и использования.es,lib,umdФормат.
  • Решено ввести один и тот же механизм упаковки для автоматической генерации форматов кода, используемых в разных средах.

процесс решения

Изучите, какую схему упаковки использоватьwebpackorrollup

Webpack

  • WebpackСоздано Тобиасом Копперсом в 2012 году для решения проблемы, с которой не могли справиться современные инструменты: создание сложных одностраничных приложений (SPA).
  • разделение кода:WebpackВы можете разделить свое приложение на множество управляемых фрагментов, которые можно загружать по требованию, когда пользователи используют ваше приложение. Это означает, что ваши пользователи могут получить более быстрый интерактивный опыт.
  • статический импорт ресурсов: статические ресурсы, такие как изображения и CSS, можно напрямую импортировать в ваше приложение, и ими можно управлять так же, как другими модулями и узлами. Таким образом, нам больше не нужно тщательно размещать отдельные статические файлы в определенных папках, а затем использовать сценарии для хеширования URL-адресов файлов. Webpack уже делает все это за вас.

rollup

  • Tree Shaking:ЭтоrollupПредлагаемая функция, которая используетes6Статическая функция модуля анализирует импортированный модуль и извлекает только используемые методы, тем самым уменьшая размер пакета.
  • Конфигурация проста в использовании, а сгенерированный код относительноWebpackБолее лаконично.
  • Для использования в сборке можно указать множество различных модулей (amd,commonjs,es,umd).

Сходства и различия

  • WebpackОн больше подходит для упаковки наших реальных бизнес-проектов, упаковки, разделения и динамического внедрения кода и статических ресурсов без нашей ручной обработки.
  • rollupНебольшой и простой в использовании и настройкеlibБиблиотека классов упакована, и код работает более эффективно.vue,reactИспользуйте другие популярные оправыrollupВы можете видеть подсказки.
  • WebpackКонфигурация упаковки относительно громоздка, объем упакованного кода относительно велик, и будет выполняться поиск зависимостей между различными зависимостями, что не так эффективно, какrollup
  • Дайте примерный вывод: для повседневных одностраничных приложений есть код и разные статические ресурсыWebpackБолее подходит для некоторых проектов чистой библиотеки классов js/tsrollupБолее подходящий,rollupУпакованный ввод может указывать разные форматы (amd,commonjs,es,umd) следует ввести и использовать в каждом сценарии.

Реализация пакета

  • Таким образом, этот пакет представляет собой библиотеку пользовательского интерфейса, применяемую к другим проектам.Хотя в этом проекте есть статические ресурсы, такие как файлы стилей и файлы изображений, накопительный пакет использует@rollup/plugin-imageа такжеrollup-plugin-postcssДва плагина для обработкиcss/lessа такжеimgдля обработки.
  • Шаги настройки следующие (комментарий будет сделан в соответствии с фактической конфигурацией, чтобы объяснить роль каждой конфигурации и зависимости):
    • Установитьrollupи зависимости
    yarn add -D rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-replace  @rollup/plugin-image rollup-plugin-terser rollup-plugin-uglify rollup-plugin-postcss cssnano postcss-cssnext postcss-nested postcss-simple-vars
    
    • установленыrollupнужно настроить позжеbabel, также необходимо установитьbabelНастройте необходимые зависимости плагина
    yarn add -D @babel/cli @babel/core @babel/plugin-external-helpers @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread @babel/plugin-transform-react-display-name @babel/plugin-transform-react-jsx @babel/plugin-transform-runtime @babel/preset-env
    
    • После установки вышеуказанных зависимостей разработкиrollupа такжеbabelконфигурации, создайте новую в корневом каталоге проектаrollup.config.jsа также.babelrc.jsДва конфигурационных файла используются дляrollupа такжеbabelЧитать во время выполнения.
    • rollup.config.jsКонфигурация выглядит следующим образом:
      // Rollup plugins
      // babel插件用于处理es6代码的转换,使转换出来的代码可以用于不支持es6的环境使用
      import babel from 'rollup-plugin-babel';
      // resolve将我们编写的源码与依赖的第三方库进行合并
      import resolve from 'rollup-plugin-node-resolve';
      // 解决rollup.js无法识别CommonJS模块
      import commonjs from 'rollup-plugin-commonjs';
      // 全局替换变量比如process.env
      import replace from 'rollup-plugin-replace';
      // 使rollup可以使用postCss处理样式文件less、css等
      import postcss from 'rollup-plugin-postcss';
      // 可以处理组件中import图片的方式,将图片转换成base64格式,但会增加打包体积,适用于小图标
      import image from '@rollup/plugin-image';
      // 压缩打包代码(这里弃用因为该插件不能识别es的语法,所以采用terser替代)
      // import { uglify } from 'rollup-plugin-uglify';
      // 压缩打包代码
      import { terser } from 'rollup-plugin-terser';
      // import less from 'rollup-plugin-less';
      // PostCSS plugins
      // 处理css定义的变量
      import simplevars from 'postcss-simple-vars';
      // 处理less嵌套样式写法
      import nested from 'postcss-nested';
      // 可以提前适用最新css特性(已废弃由postcss-preset-env替代,但还是引用进来了。。。)
      // import cssnext from 'postcss-cssnext';
      // 替代cssnext
      import postcssPresetEnv from 'postcss-preset-env';
      // css代码压缩
      import cssnano from 'cssnano';
      
      const env = process.env.NODE_ENV;
      
      export default {
        // 入口文件我这里在components下统一导出所有自定义的组件
        input: 'src/components/index.js',
        // 输出文件夹,可以是个数组输出不同格式(umd,cjs,es...)通过env是否是生产环境打包来决定文件命名是否是.min
        output: [{
          file: `dist/dna-ui-react-umd${env === 'production' ? '.min' : ''}.js`,
          format: 'umd',
          name: 'geneUI',
        }, {
          file: `dist/dna-ui-react-es${env === 'production' ? '.min' : ''}.js`,
          format: 'es'
        }],
        // 注入全局变量比如jQuery的$这里只是尝试 并未启用
        // globals: {
        //   react: 'React',                                         // 这跟external 是配套使用的,指明global.React即是外部依赖react
        //   antd: 'antd'
        // },
        // 自定义警告事件,这里由于会报THIS_IS_UNDEFINED警告,这里手动过滤掉
        onwarn: function (warning) {
          if (warning.code === 'THIS_IS_UNDEFINED') {
            return;
          }
        },
        // 将模块视为外部模块,不会打包在库中
        external: ['antd', '@ant-design/icons', 'react', 'prop-types', 'gojs'],
        // 插件
        plugins: [
          image(),
          postcss({
            plugins: [
              simplevars(),
              nested(),
              // cssnext({ warnForDuplicates: false, }),
              postcssPresetEnv(),
              cssnano(),
            ],
            // 处理.css和.less文件
            extensions: [ '.css', 'less' ],
          }),
          resolve(),
          // babel处理不包含node_modules文件的所有js
          babel({
            exclude: '**/node_modules/**',
            runtimeHelpers: true,
            plugins: [
              "@babel/plugin-external-helpers"
            ]
          }),
          // 这里有些引入使用某个库的api但报未导出改api通过namedExports来手动导出
          commonjs({
            'namedExports': {
              'node_modules/react-is/index.js': ['isFragment'],
              'node_modules/react/index.js': ['Fragment', 'cloneElement', 'isValidElement', 'Children', 'createContext', 'Component', 'useRef', 'useImperativeHandle', 'forwardRef', 'useState', 'useEffect', 'useMemo'],
              'node_modules/react-dom/index.js': ['render', 'unmountComponentAtNode', 'findDOMNode'],
              'node_modules/gojs/release/go.js': ['Diagram', 'GraphLinksModel', 'Overview', 'Spot']
            }
          }),
          // 全局替换NODE_ENV,exclude表示不包含某些文件夹下的文件
          replace({
            // exclude: 'node_modules/**',
            'process.env.NODE_ENV':  JSON.stringify(env || 'development'),
          }),
          // 生产环境执行terser压缩代码
          (env === 'production' && terser()),
        ],
      }
    
    • .babelrc.jsКонфигурация выглядит следующим образом:
      // 这里通过cross-env注入不同执行变量来确定babel转码成不同的格式es和commonjs
      const { NODE_ENV, BABEL_ENV } = process.env
      const cjs = NODE_ENV === 'test' || BABEL_ENV === 'commonjs'
      const loose = true
      
      module.exports = {
        // 设置modules:false来避免babel转换成commonjs之后rollup执行会报错
        presets: [['@babel/env', { loose, modules: false }]],
        plugins: [
          ['@babel/proposal-decorators', { legacy: true }],
          ['@babel/proposal-object-rest-spread', { loose }],
          // 对jsx语法进行转换
          '@babel/transform-react-jsx',
          cjs && ['@babel/transform-modules-commonjs', { loose }],
          [
            '@babel/transform-runtime',
            {
              useESModules: !cjs,
              version: require('./package.json').dependencies[
                '@babel/runtime'
              ].replace(/^[^0-9]*/, '')
            }
          ],
          ["@babel/plugin-proposal-class-properties"]
        ].filter(Boolean)
      }
    
    • Установлен вышеrollupа такжеbabelЗависимость, после настройки соответствующей конфигурации можно настроить команду выполнения вpackage.jsonсередина:
     "rollup-build": "cross-env BABEL_ENV=rollup rollup -c",
     "rollup-production-build": "cross-env NODE_ENV=production rollup -c",
    

    rollup -cОтносится к корневому каталогу выполнения по умолчанию.rollup.config.js

    • Выполните указанную выше командуyarn rollup-buildа такжеyarn rollup-production-buildпозже какrollup.config.jsизoutputнастроен вdistСоответствующий файл пакета создается в каталоге. Сгенерированные файлы можно использовать для прямого импорта и использования библиотеки компонентов в соответствующей среде.

интермедия

  1. Вышеупомянутая конфигурация может упаковать код в файл js для ознакомления и использования.В то же время, внимательные студенты должны быть в состоянии обнаружить, что некоторые библиотеки классов имеютlib,esпапка используется для представленияcommonjsправописание иes6письмо, мы можем использоватьbabelГенерируется непосредственно путем транскодирования.
  • У нас есть один в корневом каталоге.babelrc.jsКонфигурация используется для выполненияbabelКонфигурация.
  • нам просто нужноpackage.jsonизscriptsДобавьте следующую команду:
  "build:commonjs": "rimraf lib  && cross-env BABEL_ENV=commonjs babel src --out-dir lib",
  "build:es": "rimraf es && cross-env BABEL_ENV=es babel src --out-dir es",
  • Выполните приведенную выше команду, чтобы сгенерировать соответствующий код модуля.
  1. Видетьantdа такжеelementUIСтанция документа библиотеки пользовательского интерфейса объединяет исходный код, чтобы обнаружить, что станция документа представляет собой документ, написанный в уценке, а затем преобразованный в станцию ​​статического документа с помощью соответствующего инструмента преобразования. Вот два рекомендуемых генератора статических сайтов, которые собирают документацию:
  • doczнаправлен наreactСтанция сбора документов, разработчики могут вводить свои собственные компоненты в соответствующиеmarkdownиз.mdxфайл, используется нижний слойgatsbyгенератор статических сайтов, но с использованиемdoczизreactПодмости слегка изъедены, поэтому нужно быть морально готовым.
  • storybookявляется более мощным генератором документации, который поддерживаетjsx,.vueи другие компоненты, также поддерживает.mdxзапись файла.

Перемещение кирпичей