Недавно мне потребовалось создать общий пакет JavaScript npm для внутреннего разделения функций между приложениями, и я по наивности не учел влияние различных форматов конкурирующих модулей в целом в мире JS, но, к счастью, решение находится прямо с помощью «свертывания». '.

Требование состояло в том, чтобы создать общую библиотеку JavaScript для совместного использования многочисленными приложениями React/Node и сделать ее доступной для внутреннего использования через установку npm/yarn, опубликовав ее во внутреннем реестре. Теоретически все просто, однако существуют конкурирующие форматы модулей, и вам нужно либо выбрать один, либо поддерживать оба.

В основном используются различные форматы CommonJS (CJS) (исходная система модулей NodeJS), определение асинхронного модуля (AMD), определение универсального модуля (UMD) (сочетание CommonJS и AMD) и модули ES6 (ESM). Большинство из них требуют использования ключевого слова «require» для импорта модулей или, в случае модулей ES6, использования «import». Так почему я должен заботиться обо всем этом? Не было бы проще использовать только современный формат модуля ES6. Обычно вы выбираете одну из них для своего приложения и в основном игнорируете другие, но при создании общей библиотеки вам необходимо учитывать, что используется приложением-потребителем, чтобы оно могло использовать вашу новую библиотеку. Простое использование модулей ES6 затрудняет использование библиотеки приложениями, созданными с использованием CommonJS, и в моем случае я также обнаружил, что использование библиотеки из большинства приложений, основанных на модулях ES6, было проблематичным, и часто есть что-то, что требует формат CommonJS (я м смотрю на вас Node).

Так что со временем все будет стандартизировано (возможно) на модулях ES6, а пока я использовал накопительный пакет (https://rollupjs.org) для решения проблемы. Сборщик модулей Rollup позволяет кодировать в соответствии с современным стандартом ES6, а затем компилировать его в другие форматы (например, CommonJS) в одном пакете (или в разных пакетах, если хотите).

Чтобы сделать жизнь еще проще, я нашел это отличное репозиторий ts-library-template для JS-библиотеки TypeScript на основе накопительного пакета, которая идеально соответствовала моим потребностям. Rollup настроен для вывода в форматах CJS и ESM.

output: [
    {
      dir: `dist/${dirname(pkg.main)}`,
      entryFileNames: '[name].js',
      format: 'cjs'
    },
    {
      dir: `dist/${dirname(pkg.module)}`,
      entryFileNames: '[name].mjs',
      format: 'esm'
    }
  ]

Таким образом, когда библиотека будет скомпилирована, ее смогут использовать как приложения на основе CJS, так и приложения на основе ESM.

Первоначально опубликовано на http://richhewlett.com 5 ноября 2022 г.