"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > بناء حزم NPM لـ CommonJS مع تبعيات ESM

بناء حزم NPM لـ CommonJS مع تبعيات ESM

تم النشر بتاريخ 2024-08-14
تصفح:292

Building NPM packages for CommonJS with ESM dependencies

TLDR

يجب عليك استخدام أداة تجميع مثل esbuild والتي ستقوم بتجميع مشروعك وتجميع كل تبعياته معه حتى لا يتم استيرادها. يؤدي هذا إلى تجاوز مشكلة عدم توافق ESM/CommonJS.

إذا كنت غير صبور، فيمكنك الانتقال مباشرة إلى الكود باستخدام هذا المثال للتنفيذ.

سياق

أثناء التحضير لإصدار مشروعي الجديد Token.js خلال عطلة نهاية الأسبوع، واجهت مشكلة محبطة للغاية. كنت أرغب في أن تدعم الحزمة الخاصة بي CommonJS بالإضافة إلى ESM، لكن كان لدي تبعيات ESM خالصة. قد يكون مناصرو ESM غير راضين تمامًا عن قولي ذلك، ولكن إذا كنت تقوم ببناء حزمة NPM وتريد استخدامها على نطاق واسع، فلا تزال بحاجة إلى دعم CommonJS في عام 2024.

Token.js عبارة عن TypeScript SDK بسيط يسمح لك بدمج 60 LLMs من 9 موفري خدمات مختلفين (OpenAI، وAnthropic، وCohere، وما إلى ذلك). المكونات وقح، التحقق من ذلك واسمحوا لي أن أعرف ما هو رأيك إذا كنت في الذكاء الاصطناعي التوليدي.

يوجد الآن عدد من الموارد عبر الإنترنت تناقش كيفية إنشاء مشاريع Javascript لـ ESM أو CommonJS أو كليهما. ومع ذلك، فقد واجهت مشكلة على وجه التحديد في التعامل مع حقيقة أن لدي تبعيات كانت عبارة عن أدوات ESM خالصة. لقد وجدت صعوبة كبيرة في التعامل مع هذا لأنني لست على دراية ببرامج الحزم (عملت في الغالب على الواجهات الخلفية لتطبيقات الويب)، ولم أتمكن من العثور على دليل جيد حول هذا الموضوع.

لذلك إذا واجه أي شخص آخر هذه المشكلة، فإليك الحل.

مرشد

قم بتثبيت Esbuild

سنستخدم esbuild للمجمع.

yarn add esbuild --save-dev

إنشاء برنامج نصي للبناء

سنحتاج إلى برنامج نصي بناء بسيط لتشغيل esbuild وإخراج النتائج.

import esbuild from 'esbuild'

const entrypoint = ""
const tsconfig = ""

const build = async () => {
  await Promise.all([
    // bundle for commonjs
    esbuild.build({
      entryPoints: [entrypoint],
      bundle: true,
      minify: true,
      format: 'cjs',
      outfile: `./dist/index.cjs`,
      platform: 'node',
      treeShaking: true,
      tsconfig,
    }),
  ])
}

build()

قم بإضافة برنامج نصي للبناء إلى package.json الخاص بك

التشغيل باستخدام وقت التشغيل المفضل لديك.

"scripts": {
  "build": "vite-node ./scripts/build.ts",
}

أنا شخصياً أحب عقدة Vite. لذلك إذا كنت تريد المتابعة بالضبط، فستحتاج إلى تثبيت ذلك:

yarn add vite-node --save-dev

قم ببناء مشروعك

yarn build

سيؤدي هذا إلى إنشاء مشروعك باستخدام esbuild وسترى ملفًا جديدًا، dist/index.cjs، وهو إصدار CommonJS لحزمتك.

تكوين نقطة الدخول

قم بتحديث ملف package.json الخاص بك للإشارة إلى نقطة دخول CommonJS.

"main": "dist/index.cjs",

بام! ها أنت ذا، لقد قمت الآن ببناء الحزمة الخاصة بك لـ CommonJS. سيعمل هذا حتى لو كان لديك تبعيات ESM لأنه سيتم تجميع التبعيات
جنبا إلى جنب مع الحزمة الخاصة بك.

يتم تضمين التبعيات في الإخراج بسبب حزمة الحقل: صحيح عند استدعاء esbuild.

إعلانات TypeScript

على الرغم من أن ذلك غير مطلوب من الناحية الفنية، فمن المحتمل جدًا أنك ستحتاج أيضًا إلى إعلانات TypeScript التي لا يتم إنشاؤها للأسف في الوقت الحالي. لذلك لتوليد
تلك، سوف تحتاج إلى استخدام tsc العادي.

قم بتحديث tsconfig.json الخاص بك

ستؤدي إضافة هذه الخيارات إلى ملف tsconfig.json إلى إخراج إعلانات TypeScript فقط. هذا هو بالضبط ما نريده منذ بقية الحزمة
يجري بناؤه مع esbuild.

"declaration": true,
"declarationDir": "./dist",
"emitDeclarationOnly": true

قم بتحديث البرنامج النصي للبناء الخاص بك

"scripts": {
  "build:tsc": "yarn tsc -p tsconfig.json",
  "build": "vite-node ./scripts/build.ts && yarn build:tsc",
}

نقاط الدخول المزدوجة

يوصي هذا الدليل بإخراج نقطة دخول CommonJS واحدة فقط لحزمتك. أنا شخصياً أعتقد أن هذا هو الخيار الأفضل لسببين:

  • تصغير حجم الحزمة
  • يتجنب خطر الحزمة المزدوجة

ومع ذلك، هذا ليس الخيار الوحيد. يمكنك أيضًا نشر الحزمة الخاصة بك بنقاط دخول مزدوجة لـ CommonJS وESM.

قم بتحديث البرنامج النصي للبناء الخاص بك ليشمل إصدار ESM

import esbuild from 'esbuild'

const entrypoint = ""
const tsconfig = ""

const build = async () => {
  await Promise.all([
    // bundle for commonjs
    esbuild.build({
      entryPoints: [entrypoint],
      bundle: true,
      minify: true,
      format: 'cjs',
      outfile: `./dist/index.cjs`,
      platform: 'node',
      treeShaking: true,
      tsconfig,
    }),
    // bundle for ESM
    esbuild.build({
      entryPoints: [entrypoint],
      bundle: true,
      minify: true,
      format: 'esm',
      outfile: `./dist/index.js`,
      platform: 'node',
      treeShaking: true,
      tsconfig,
    }),
  ])
}

build()

قم بتحديث ملف package.json الخاص بك ليشمل نقاط دخول مزدوجة

"main": "dist/index.cjs",
"module": "dist/index.js",
"type": "module",
"exports": {
  ".": {
    "import": "./dist/index.js",
    "require": "./dist/index.cjs",
    "types": "./dist/index.d.ts"
  }
},

كود المصدر

بيان الافراج تم إعادة نشر هذه المقالة على: https://dev.to/ryan_pate_f494c0931176673/how-to-build-npm-packages-for-commonjs-with-pure-esm-dependeency-38jm?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ Study_golang @163.com حذف
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3