साझा घटक पुस्तकालय सर्वोत्तम प्रथाओं


12

मैं एक साझा प्रतिक्रिया घटक पुस्तकालय बना रहा हूं।

लाइब्रेरी में कई घटक होते हैं लेकिन अंतिम उपयोगकर्ता को उनमें से कुछ का उपयोग करने की आवश्यकता हो सकती है।

जब आप वेबपैक (या पार्सल या रोलअप) के साथ कोड को बंडल करते हैं तो यह सभी कोड के साथ एक सिंगल फाइल बनाता है ।

प्रदर्शन कारणों से मैं उस सभी कोड को ब्राउज़र द्वारा डाउनलोड नहीं करना चाहता जब तक कि यह वास्तव में उपयोग नहीं किया जाता है। क्या मैं यह सोचने में सही हूं कि मुझे घटकों को बंडल नहीं करना चाहिए? क्या बंडल को घटकों के उपभोक्ता को छोड़ दिया जाना चाहिए? क्या मैं घटकों के उपभोक्ता के लिए कुछ और छोड़ सकता हूं? क्या मैं सिर्फ JSX को ट्रांसपाइल करता हूं और वह है?

यदि एक ही रेपो में बहुत सारे अलग-अलग घटक होते हैं, तो main.js में क्या होना चाहिए?


1
आप इस तरह से एक दृष्टिकोण के लिए देख रहे हैं मैं आपके सवाल का सही ढंग से समझ में आ एक उनके स्रोत कोड पर एक नज़र डालें और आप देखेंगे कि वे सभी घटकों और साथ ही व्यक्तिगत लोगों और निर्यात जब एक ग्राहक एप्लिकेशन उनके घटकों (और व्यक्तिगत आयात का उपयोग करता है पूरे मॉड्यूल के बजाय घटक) वेबपैक केवल उन फाइलों को खींचेगा importedजो कोड में थे इस प्रकार बंडल का आकार घट रहा है।
एडवर्ड चोपुरियन

जवाबों:


5

यह एक बहुत लंबा उत्तर है क्योंकि यह प्रश्न एक बहुत लंबा और विस्तृत उत्तर देता है क्योंकि "सबसे अच्छा अभ्यास" तरीका सिर्फ कुछ लाइन प्रतिक्रिया की तुलना में अधिक जटिल है।

Iv'e ने उस समय में 3.5+ वर्षों के लिए हमारे घर के पुस्तकालयों में बनाए रखा, iv'e दो तरीकों से बसा हुआ है, मुझे लगता है कि पुस्तकालयों को व्यापार बंद किया जाना चाहिए यह निर्भर करता है कि आपका पुस्तकालय कितना बड़ा है और व्यक्तिगत रूप से हम दोनों उपसमुच्चय को खुश करने के लिए दोनों तरीकों को संकलित करते हैं। उपभोक्ताओं।

विधि 1: सब कुछ के साथ एक index.ts फ़ाइल बनाएँ जिसे आप एक्सपोज़ किए गए निर्यात करें और उसके इनपुट के रूप में इस फ़ाइल पर रोलअप को लक्षित करें। अपनी पूरी लाइब्रेरी को एक index.js फ़ाइल और index.css फ़ाइल में बंडल करें; पुस्तकालय कोड के दोहराव से बचने के लिए उपभोक्ता परियोजना से विरासत में मिली बाहरी निर्भरता के साथ। (उदाहरण के विन्यास के निचले भाग में शामिल)

  • पेशेवरों: उपभोग करने में आसान परियोजना उपभोक्ता रूट सापेक्ष पुस्तकालय पथ से सब कुछ आयात कर सकते हैं import { Foo, Bar } from "library"
  • विपक्ष: यह कभी पेड़ का शाक नहीं होगा; और इससे पहले कि लोग कहते हैं कि ईएसएम के साथ ऐसा करें और यह वृक्षों के रहने योग्य होगा। NextJS इस मौजूदा स्तर पर ESM का समर्थन नहीं करता है और न ही प्रोजेक्ट सेटअपों का एक बहुत कुछ है, यही कारण है कि अभी भी इस निर्माण को सिर्फ CJS को संकलित करने का एक अच्छा विचार है। यदि कोई आपके 1 घटक को आयात करता है तो उन्हें आपके सभी घटकों के लिए सभी सीएसएस और सभी जावास्क्रिप्ट मिलेंगे।

विधि 2: यह उन्नत उपयोगकर्ताओं के लिए है: प्रत्येक निर्यात के लिए एक नई फ़ाइल बनाएं और विकल्प "preserveModules: true" के साथ रोलअप-प्लगइन-मल्टी-इनपुट का उपयोग करें, इस बात पर निर्भर करता है कि आप किस css प्रणाली का उपयोग कर रहे हैं, यह भी सुनिश्चित करने की आवश्यकता है कि आपकी सीएसएस को एक एकल फ़ाइल में विलय नहीं किया गया है, लेकिन प्रत्येक सीएसएस फ़ाइल को रोलअप के बाद आउटपुट फ़ाइल के अंदर ("सीएसएस") विवरण की आवश्यकता होती है और उस सीएसएस फ़ाइल मौजूद है।

  • पेशेवरों: जब उपयोगकर्ता "लाइब्रेरी / डिस्ट / फू" से {Foo} आयात करते हैं, तो उन्हें केवल Foo के लिए कोड मिलेगा, और Foo के लिए css और इससे अधिक कुछ नहीं होगा।
  • विपक्ष: इस सेटअप में उपभोक्ता को शामिल करने के लिए नोड_मॉडल की आवश्यकता है ("। Css") स्टेटमेंट उनके बिल्ड कॉन्फ़िगरेशन में NextJS के साथ यह npm next-transpile-modulesपैकेज के साथ किया गया है।
  • कैविएट: हम अपने स्वयं के बेबल प्लगइन का उपयोग करते हैं जो आप यहां पा सकते हैं: https://www.npmjs.com/package/babel-plugin-qubic लोगों को अनुमति देने के लिए import { Foo,Bar } from "library"और फिर बैबल के साथ इसे बदलने के लिए ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"

हमारे पास कई रोलअप कॉन्फ़िगरेशन हैं जहां हम वास्तव में दोनों विधियों का उपयोग करते हैं; पुस्तकालय उपभोक्ताओं के लिए जो पेड़ हिलाने की परवाह नहीं करते हैं, वे सिर्फ "Foo from "library"एक सीएसएस फ़ाइल आयात और आयात कर सकते हैं ; और लाइब्रेरी उपभोक्ताओं के लिए जो पेड़ के हिलने की देखभाल करते हैं और केवल महत्वपूर्ण सीएसएस का उपयोग करके वे हमारे बबेल प्लगइन को चालू कर सकते हैं।

सर्वोत्तम अभ्यास के लिए रोलअप गाइड:

चाहे आप टाइपस्क्रिप्ट का उपयोग कर रहे हों या नहीं, हमेशा "rollup-plugin-babel": "5.0.0-alpha.1" सुनिश्चित करें कि आपके .babelrc इस तरह का हो।

{
  "presets": [
    ["@babel/preset-env", {
      "targets": {"chrome": "58", "ie": "11"},
      "useBuiltIns": false
    }],
    "@babel/preset-react",
    "@babel/preset-typescript"
  ],
  "plugins": [
    ["@babel/plugin-transform-runtime", {
      "absoluteRuntime": false,
      "corejs": false,
      "helpers": true,
      "regenerator": true,
      "useESModules": false,
      "version": "^7.8.3"
    }],
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-classes",
    ["@babel/plugin-proposal-optional-chaining", {
      "loose": true
    }]
  ]
}

और रोलअप में बेबेल प्लगइन के साथ इस तरह दिख रहा है ...

        babel({
            babelHelpers: "runtime",
            extensions,
            include: ["src/**/*"],
            exclude: "node_modules/**",
            babelrc: true
        }),

और आपका पैकेज। इस तरह से देख रहे हैं:

    "dependencies": {
        "@babel/runtime": "^7.8.3",
        "react": "^16.10.2",
        "react-dom": "^16.10.2",
        "regenerator-runtime": "^0.13.3"
    },
    "peerDependencies": {
        "react": "^16.12.0",
        "react-dom": "^16.12.0",
    }

और अंत में रोलअप में अपने बाहरी इस तरह लग रहे हैं।

const makeExternalPredicate = externalArr => {
    if (externalArr.length === 0) return () => false;
    return id => new RegExp(`^(${externalArr.join('|')})($|/)`).test(id);
};

//... rest of rollup config above external.
    external: makeExternalPredicate(Object.keys(pkg.peerDependencies || {}).concat(Object.keys(pkg.dependencies || {}))),
// rest of rollup config below external.

क्यों?

  • यह आपकी गंदगी को स्वचालित रूप से प्रतिक्रिया / प्रतिक्रिया-डोम और उपभोक्ता परियोजना से आपके अन्य सहकर्मी / बाहरी आश्रितों को विरासत में देगा, जिसका अर्थ है कि वे आपके बंडल में नकल नहीं करेंगे।
  • यह ईएस 5 को बंडल करेगा
  • यह स्वचालित रूप से ("..") सभी आवश्यक बबल हेल्पर कार्यों में ऑब्जेक्टस्प्रेड, कक्षाओं आदि के लिए आवश्यक होगा। उपभोक्ता प्रोजेक्ट से जो आपके बंडल आकार से एक और 15-25KB मिटा देगा और इसका मतलब है कि ऑब्जेक्टस्प्रेड के लिए सहायक फ़ंक्शन आपके लाइब्रेरी में डुप्लिकेट नहीं है आउटपुट + खपत परियोजनाओं ने आउटपुट को बंडल किया।
  • Async फ़ंक्शंस अभी भी काम करेंगे
  • बाह्य कुछ भी जो उस सहकर्मी-निर्भरता प्रत्यय के साथ शुरू होता है यानी बैबेल-हेल्पर्स, बैबल-हेल्पर्स / हेल्पर्स / ऑब्जेक्ट-स्प्रेड के लिए बाहरी से मेल खाएगा

अंत में यहाँ एक उदाहरण है एक उदाहरण के लिए एक index.js फ़ाइल आउटपुट रोलअप कॉन्फ़िग फ़ाइल। https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3 जहां लक्ष्य src / export / index.ts इस तरह दिखता है ...

export { Button } from "../components/Button/Button";
export * from "../components/Button/Button.styles";

export { Checkbox } from "../components/Checkbox/Checkbox";
export * from "../components/Checkbox/Checkbox.styles";

export { DatePicker } from "../components/DateTimePicker/DatePicker/DatePicker";
export { TimePicker } from "../components/DateTimePicker/TimePicker/TimePicker";
export { DayPicker } from "../components/DayPicker/DayPicker";
// etc etc etc

मुझे बताएं कि क्या आपको बैबल, रोलअप के साथ कोई समस्या है या बंडल / लाइब्रेरीज़ के बारे में कोई प्रश्न हैं।


3

जब आप Webpack (या पार्सल या रोलअप) के साथ कोड को बंडल करते हैं तो यह सभी कोड के साथ एक सिंगल फाइल बनाता है।

प्रदर्शन कारणों से मैं उस सभी कोड को ब्राउज़र द्वारा डाउनलोड नहीं करना चाहता जब तक कि यह वास्तव में उपयोग नहीं किया जाता है

प्रत्येक घटक के लिए अलग-अलग फ़ाइलों को उत्पन्न करना संभव है। वेबपैक में कई प्रविष्टियों और आउटपुट को परिभाषित करके ऐसी क्षमता है। मान लीजिए कि आपके पास किसी प्रोजेक्ट की निम्नलिखित संरचना है

- my-cool-react-components
  - src // Folder contains all source code
    - index.js
    - componentA.js
    - componentB.js
    - ...
  - lib // Folder is generated when build
    - index.js // Contains components all together
    - componentA.js
    - componentB.js
    - ...

वेबपैक फ़ाइल कुछ इस तरह दिखाई देगी

const path = require('path');

module.exports = {
  entry: {
    index: './src/index.js',
    componentA: './src/componentA.js',
    componentB: './src/componentB.js',
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'lib'),
  },
};

"कोड विभाजन" के बारे में अधिक जानकारी यहां वेबपैक डॉक्स में दी गई है

यदि एक ही रेपो में बहुत सारे अलग-अलग घटक होते हैं, तो main.js में क्या होना चाहिए?

package.jsonफ़ाइल में एक एकल फ़ील्ड है जिसका नाम है main, lib/index.jsऊपर दिए गए प्रोजेक्ट संरचना के अनुसार इसका मूल्य डालना अच्छा है । और index.jsफ़ाइल में सभी घटकों का निर्यात होता है। यदि उपभोक्ता एकल घटक का उपयोग करना चाहता है, तो यह केवल करने योग्य है

const componentX = require('my-cool-react-components/lib/componentX');

क्या मैं यह सोचने में सही हूं कि मुझे घटकों को बंडल नहीं करना चाहिए? क्या बंडल को घटकों के उपभोक्ता को छोड़ दिया जाना चाहिए? क्या मैं घटकों के उपभोक्ता के लिए कुछ और छोड़ सकता हूं? क्या मैं सिर्फ JSX को ट्रांसपाइल करता हूं और वह है?

यह आप पर निर्भर करता है। मैंने पाया है कि कुछ रिएक्ट लाइब्रेरी मूल तरीके से प्रकाशित हैं, अन्य - बंडल तरीके से हैं। यदि आपको कुछ बिल्ड प्रक्रिया की आवश्यकता है, तो इसे परिभाषित करें और बंडल किए गए संस्करण को निर्यात करें।

आशा है, आपके सभी सवालों के जवाब दिए गए हैं :)


जवाब देने के लिए धन्यवाद। जब भी मैं आपके उदाहरण में एक नया घटक जोड़ता हूं, तो मुझे हर बार अपने वेबपैक कॉन्फिगर को अपडेट करना नहीं चाहिए। "यह आपके ऊपर है। मैंने पाया है कि कुछ रिएक्ट लाइब्रेरी मूल तरीके से प्रकाशित होती हैं, अन्य - बंडल तरीके से होती हैं।" यह मामला साबित नहीं हो रहा है। Create React App ने मेरे असम्बद्ध घटकों के साथ काम किया ठीक है, लेकिन नेक्स्ट जेएस एक त्रुटि फेंक रहा है और स्पष्ट रूप से केवल बंडल घटकों के साथ काम करता है, निर्णय मेरे हाथों से ले रहा है।
OTW

मैंने शोध के लिए अपनी पूरी कोशिश की है :) "मैं हर बार जब मैं एक नया घटक जोड़ता हूं तो मुझे अपने वेबपैक कॉन्फिगरेशन को अपडेट नहीं करना पड़ता है" - सभी घटकों को सूचीबद्ध नहीं करने के लिए कुछ ग्लोब-वाइल्डकार्ड का उपयोग करना संभव है, यह समस्या का हल करता है हर नए घटक के लिए वेबपैक का अद्यतन करना। "अगला जेएस एक त्रुटि फेंक रहा है" - ठीक है, फिर अपना पैकेज बंडल करें :) जाहिर है कि कच्चा पैकेज काम करेगा यदि केवल उपभोक्ता परियोजना से बंडल में शामिल किया गया हो। बंडल किया गया संस्करण 100% काम करेगा।
राशद इब्राहिमोव

1

आप अपने घटकों को विभाजित कर सकते हैं जैसे कि लॉश अपने तरीकों के लिए कर रहे हैं।

आपके पास संभवतः अलग घटक हैं जिन्हें आप अलग से या मुख्य घटक के माध्यम से आयात करने की अनुमति दे सकते हैं।

तब उपभोक्ता पूरे पैकेज का आयात कर सकता था

import {MyComponent} from 'my-components';

या इसके अलग-अलग हिस्से

import MyComponent from 'my-components/my-component';

उपभोक्ता अपने स्वयं के बंडल का निर्माण उन घटकों के आधार पर करेंगे जो वे आयात करते हैं। यह आपके पूरे बंडल को डाउनलोड होने से रोकना चाहिए।


1

आपको Bit पर एक नज़र डालनी चाहिए , मुझे लगता है कि यह घटकों को साझा करने, पुन: उपयोग करने और कल्पना करने का एक अच्छा समाधान है।

इसे सेटअप करना बहुत आसान है। आप अपनी बिट लाइब्रेरी या इसके साथ बस एक घटक स्थापित कर सकते हैं:

npm i @bit/bit.your-library.components.buttons

तब आप अपने ऐप में घटक को आयात कर सकते हैं:

import Button3 from '@bit/bit.your-library.components.buttons';

अच्छी बात यह है कि आपको वेबपैक और उस सभी जैज़ को कॉन्फ़िगर करने के बारे में चिंता करने की ज़रूरत नहीं है। बिट भी आपके घटकों के संस्करण का समर्थन करता है। यह उदाहरण एक शीर्षक-सूची प्रतिक्रिया घटक दिखाता है ताकि आप देख सकें कि यह आपकी आवश्यकताओं को पूरा करता है या नहीं


0

चंक फ़ाइलों को बनाने के लिए वेबपैक में एक कॉन्फ़िगरेशन है। इसके साथ शुरू करने के लिए कई बंडल में मुख्य बंडल बनाएंगे और इसे आवश्यकतानुसार लोड करेंगे। यदि आपकी परियोजना में अच्छी तरह से संरचित मॉड्यूल हैं, तो यह किसी भी कोड को लोड नहीं करेगा, जिसकी आवश्यकता नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.