एक एनपीएम पैकेज से कई ईएस 6 मॉड्यूल कैसे निर्यात करें


16

मैंने एक अपेक्षाकृत छोटे एनपीएम पैकेज का निर्माण किया है जिसमें एक फाइल में लगभग 5 अलग-अलग ईएस 6 कक्षाएं शामिल हैं, वे सभी इस तरह से बहुत सुंदर दिखते हैं:

export default class MyClass {
    // ...
}

फिर मैंने अपने पैकेज के लिए एक एंट्री पॉइंट सेटअप किया है जो इस तरह दिखता है:

export { default as MyClass } from './my-class.js';
export { default as MyOtherClass } from './my-other-class.js';

फिर मैंने वेबपैक और बेबल के माध्यम से प्रवेश बिंदु को चलाया है और एक ट्रांसप्लड और मिनिमाइज्ड इंडेक्स.जेएस के साथ समाप्त हो रहा है

पैकेज को स्थापित करना और आयात करना ठीक काम करता है, लेकिन जब मैं अपने क्लाइंट कोड से निम्न कार्य करता हूं:

import { MyClass } from 'my-package';

यह सिर्फ "MyClass" आयात नहीं करता है यह पूरी फाइल को आयात करता है जिसमें हर वर्ग की सभी निर्भरताएं शामिल हैं (मेरी कुछ कक्षाओं में बहुत बड़ी निर्भरताएं हैं)।

मुझे लगा कि जब आप पहले से ही बंडल पैकेज के कुछ हिस्सों को आयात करने का प्रयास करते हैं तो वेबपैक कैसे काम करता है? इसलिए मैंने अपने स्थानीय वेबपैक विन्यास को बाबेल के node_modules/my-packageमाध्यम से चलाने के लिए स्थापित किया और फिर कोशिश की:

import { MyClass } from 'my-package/src/index.js';

लेकिन यहां तक ​​कि यह index.js द्वारा निर्यात किए गए हर एक वर्ग को आयात करता है। केवल एक चीज जो मुझे लगता है कि यदि मैं चाहता हूं तो काम करना लगता है:

import MyClass from 'my-package/src/my-class.js';

लेकिन मैं इसके बजाय:

  1. Transpiled और minified फ़ाइल आयात करने में सक्षम हों, ताकि मुझे नोड_मॉड्यूस और के अंदर बेबल को चलाने के लिए वेबपैक को बताने की जरूरत न पड़े
  2. प्रत्येक फ़ाइल में पथ दर्ज करने के बजाय मेरे प्रविष्टि बिंदु से प्रत्येक व्यक्तिगत वर्ग को सीधे आयात करने में सक्षम हो

यहां सबसे अच्छा अभ्यास क्या है? अन्य लोग समान सेटअप कैसे प्राप्त करते हैं? मैंने देखा है कि GlideJS के पास इसके पैकेज का ESM संस्करण है, जो आपको उदाहरण के लिए इसके माध्यम से बेबल चलाने के बिना केवल उन चीजों को आयात करने की अनुमति देता है, जिनकी आपको आवश्यकता है।

प्रश्न में पैकेज: https://github.com/powerbuoy/sleek-ui

webpack.config.js

const path = require('path');

module.exports = {
    entry: {
        'sleek-ui': './src/js/sleek-ui.js'
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
        library: 'sleek-ui', // NOTE: Before adding this and libraryTarget I got errors saying "MyClass() is not a constructor" for some reason...
        libraryTarget: 'umd'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env']
                        }
                    }
                ]
            }
        ]
    }
};

package.json

  "name": "sleek-ui",
  "version": "1.0.0",
  "description": "Lightweight SASS and JS library for common UI elements",
  "main": "dist/sleek-ui.js",
  "sideEffects": false, // NOTE: Added this from Abhishek's article but it changed nothing for me :/
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/powerbuoy/sleek-ui.git"
  },
  "author": "Andreas Lagerkvist",
  "license": "GPL-2.0-or-later",
  "bugs": {
    "url": "https://github.com/powerbuoy/sleek-ui/issues"
  },
  "homepage": "https://github.com/powerbuoy/sleek-ui#readme",
  "devDependencies": {
    "@babel/core": "^7.8.6",
    "@babel/preset-env": "^7.8.6",
    "babel-loader": "^8.0.6",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11"
  },
  "dependencies": {
    "@glidejs/glide": "^3.4.1",
    "normalize.css": "^8.0.1"
  }
}

1
क्या आपने mainअपने परिवाद के पैकेज में (एंट्री पॉइंट) विशेषता जोड़ी थी। json? अपने बिल्ड में जांचें। और आप अपने परिवाद पैकेज को कैसे बांध रहे हैं?
अभिषेक

Package.json की मुख्य संपत्ति मॉड्यूल के प्रवेश बिंदु के लिए एक दिशा है जो package.json का वर्णन कर रही है। Node.js एप्लिकेशन में, जब मॉड्यूल को एक आवश्यक विवरण के माध्यम से कॉल किया जाता है, तो मुख्य संपत्ति में नामित फ़ाइल से मॉड्यूल का निर्यात हो जाएगा जो कि Node.js एप्लिकेशन को वापस आ जाएगा।
अभिषेक

हां, मुख्य संपत्ति मेरे index.js को इंगित करती है जो अन्य सभी वर्गों को निर्यात करती है। मैं वेबपैक और बैबल का उपयोग करके मुख्य / index.js फ़ाइल को बंडल कर रहा हूं। यह सब सवाल में समझाया गया है।
पावरबॉय

यह आपकी मदद कर सकता है - danielberndt.net/blog/2018/…
अभिषेक

आप उनके निर्माण कार्यान्वयन - github.com/mui-org/material-ui/blob/master/packages/material-ui/… पर भी कर सकते हैं ताकि कम से कम बिल्ड का आकार बेहतर हो import { MyClass } from 'my-package/src/MyClass';। आप फ़ाइल पथ को छोटा करने के लिए src बिल्ड पैकेजिंग को भी हटा सकते हैं।
अभिषेक

जवाबों:


1

मुझे लगा कि जब आप पहले से ही बंडल पैकेज के कुछ हिस्सों को आयात करने का प्रयास करते हैं तो वेबपैक कैसे काम करता है?

हां, जिस तरह से आपने इसे स्थापित किया है वह हर वर्ग को index.js में आयात कर रहा है, जिसे तब एक फाइल में ट्रांसप्लड किया जाता है (यदि यह ES5 को लक्षित कर रहा है, जो कि सबसे आम है *)। इसका मतलब यह है कि जब वह फ़ाइल किसी अन्य फ़ाइल में आयात की जाती है, तो वह उन सभी वर्गों के साथ, संपूर्णता में आती है।

यदि आप उचित ट्री-शेकिंग चाहते हैं, तो आपको इसे कॉमनजस (ES5) बंडल में ट्रांसप्लांट करने से बचना चाहिए। मेरा सुझाव ES6 मॉड्यूल रखने के लिए है, या तो खुद से या ES5 बंडल से एक अलग स्थान पर। इस लेख से आपको इसे समझने में मदद मिलेगी और निर्देशों की सिफारिश करनी चाहिए। मूल रूप से यह प्रीसेट-एनवी (अत्यधिक अनुशंसित यदि आप पहले से ही इसका उपयोग नहीं कर रहे हैं!) ईएस 6 सिंटैक्स को संरक्षित करने के लिए बैबल वातावरण की स्थापना के लिए उबालते हैं । यदि आप ES5 को ट्रांसपाइल नहीं करना चाहते हैं तो यहां प्रासंगिक बैबल कॉन्फ़िगरेशन है:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "esmodules": true
        }
      }
    ]
  ]
}

आलेख में 2 बंडलों को सेट करने का विवरण है, प्रत्येक एक अलग मॉड्यूल सिंटैक्स का उपयोग कर रहा है।

इसके अलावा ध्यान देने योग्य है, और इस तरह के लेख में उल्लेख किया गया है, आप पैकेज में ईएस मॉड्यूल प्रविष्टि बिंदु सेट कर सकते हैं । जेसन। वह वेबपैक / बैबेल बताता है जहां ईएस 6 मॉड्यूल पाए जा सकते हैं, जो आपके उपयोग के मामले के लिए आवश्यक हो सकते हैं। ऐसा लगता है कि पारंपरिक ज्ञान ऐसा करने के लिए कहता है:

{
  "main": "dist/sleek-ui.js",
  "module": "src/main.js"
}

लेकिन नोड प्रलेखन के रूप में यह है:

{
  "type": "module",
  "main": "dist/sleek-ui.js",
  "exports": {
    ".": "dist/sleek-ui.js",
    "./module": "src/main.js"
  }
}

अगर मेरे पास समय होता तो मैं इसके साथ खेलता और देखता कि कौन सा काम सही तरीके से होता है, लेकिन यह आपको सही रास्ते पर स्थापित करने के लिए पर्याप्त होना चाहिए।


* ES5- लक्षित बंडलों CommonJS प्रारूप में हैं, जिसमें सभी संबंधित फ़ाइलों को शामिल करना है, क्योंकि ES5 में मूल मॉड्यूल समर्थन नहीं है। वह ES2015 / ES6 में आया था।


मैंने जोड़ने की कोशिश की targets.esmodules: trueऔर जबकि बनी स्क्रिप्ट में बदलाव किए, इसने कोई बदलाव नहीं किया जैसा कि अंत में आयात किया गया था। एक एकल वर्ग का my-packageआयात अभी भी सब कुछ आयात करता है। मैंने package.json(अन्य परिवर्तन के साथ) बदलावों की भी कोशिश की और वह भी कुछ नहीं बदला। खैर, जोड़ने के साथ type: moduleवास्तव में मेरे निर्माण को तोड़ दिया "ईएस मॉड्यूल को लोड करने के लिए आयात का उपयोग करना चाहिए: /sleek-ui/webpack.config.js ईएस मॉड्यूल की आवश्यकता है () समर्थित नहीं है।" इसलिए मुझे उस बिट को हटाना पड़ा। मैं लिंक किए गए लेख पर एक नज़र डालूंगा।
पॉवरबॉय

ठीक है, इसलिए लेख ने मुझे वास्तव में सेट करने के लिए कहा modules: false(अंदर नहीं targets) लेकिन यह भी काम नहीं किया ... मुझे लगता है कि मैं सीधे स्रोत फ़ाइल से आयात करूंगा और नोडल के माध्यम से तब तक बैबिल को चालू रखूंगा जब तक कि हम इस सामान का उपयोग मूल रूप से नहीं कर सकते।
पावरबॉय

स्रोत फ़ाइल काम से @powerbuoy आयात करना। शायद यह मेरे पोस्ट से स्पष्ट नहीं था, और अगर ऐसा है तो मैं इसे संपादित कर सकता हूं, लेकिन आप केवल वर्ग को आयात करना चाहते हैं import MyClass from 'my-package/myClass';। इसका एक अच्छा रेपो उदाहरण है, रेकॉर्ड-एस
केटलीनवेब

-1

यह एक वैध उपयोग मामला है। अंतिम लक्ष्य यह करने के लिए किया जा रहा है, import { MyClass } from 'my-package'लेकिन ऐसा करने का एक साफ तरीका है।

अपने में एक एग्रीगेटर इंडेक्स फ़ाइल बनाएँ my-package। मूल रूप से my-package/index.jsऔर यह इस तरह दिखना चाहिए:

import MyClass from './my-class.js'
import MyOtherClass from './my-other-class.js'

export { MyClass, MyOtherClass }

तब आप कर सकते हैं import { MyClass } from 'my-package'। बहुत आसान।

मज़े करो!


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