একটি এনপিএম প্যাকেজ থেকে কীভাবে একাধিক ইএস 6 মডিউল রপ্তানি করা যায়


16

আমি একটি অপেক্ষাকৃত একটি ছোট এনপিএম প্যাকেজ তৈরি করেছি যার মধ্যে প্রতিটি ফাইলে মোটামুটি 5 টি পৃথক ES6 ক্লাস রয়েছে, তারা সবাই দেখতে বেশ সুন্দর দেখাচ্ছে:

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';

এটি কেবল "মাইক্লাস" আমদানি করে না এটি প্রতিটি শ্রেণীর সমস্ত নির্ভরতা (আমার কিছু শ্রেণীর বিশাল নির্ভরশীলতা সহ) পুরো ফাইলটি আমদানি করে।

আমি অনুভব করেছি যে আপনি যখন ইতিমধ্যে বান্ডেলযুক্ত প্যাকেজের অংশগুলি আমদানির চেষ্টা করছেন তখন ওয়েবপ্যাকটি কীভাবে কাজ করে? সুতরাং আমি node_modules/my-packageখুব সহজেই বাবেল চালানোর জন্য আমার স্থানীয় ওয়েবপ্যাক কনফিগারেশন সেট আপ করেছি এবং তারপরে চেষ্টা করেছি:

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

এমনকি এটি সূচি.জেএস দ্বারা রফত প্রতিটি একক শ্রেণীর আমদানি করে। আমি চাইলে যেভাবে কাজ করতে পারে বলে মনে হয় কেবল তা হল:

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

তবে আমি এর চেয়ে অনেক বেশি চাই:

  1. স্থানান্তরিত এবং সংশোধিত ফাইলটি আমদানি করতে সক্ষম হবেন যাতে নোড_মডিউলগুলির মধ্যে বাবেল চালানোর জন্য আমাকে ওয়েবপ্যাকটি বলতে হবে না এবং
  2. প্রতিটি ফাইলের পাথ প্রবেশের পরিবর্তে আমার এন্ট্রি পয়েন্ট থেকে প্রতিটি পৃথক শ্রেণিকে সরাসরি আমদানি করতে সক্ষম করুন

এখানে সেরা অনুশীলন কি? অন্যরা কীভাবে অনুরূপ সেটআপগুলি অর্জন করতে পারে? আমি লক্ষ্য করেছি যে গ্লাইডজেএস এর প্যাকেজের একটি 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লাইবের প্যাকেজ.জসনে (এন্ট্রি পয়েন্ট) বৈশিষ্ট্য যুক্ত করেছেন? আপনার বিল্ড চেক করুন। এবং আপনি কীভাবে আপনার lib প্যাকেজটি বান্ডিল করছেন?
অভিষেক

একটি প্যাকেজ.জসনের মূল সম্পত্তিটি প্যাকেজ.জসন বর্ণনা করছে এমন মডিউলটিতে প্রবেশের দিকের দিক। কোনও নোড.জেএস অ্যাপ্লিকেশনে, যখন মডিউলটিকে প্রয়োজনীয় বিবৃতি দিয়ে ডাকা হয়, মূল সম্পত্তিটির নামকৃত ফাইল থেকে মডিউলটির রফতানি নোড.জেএস অ্যাপ্লিকেশনটিতে ফিরে আসবে।
অভিষেক

হ্যাঁ, আমার ইন্ডেক্স.জেজে মূল সম্পত্তিটি নির্দেশ করে যা অন্য সমস্ত শ্রেণীর রফতানি করে। আমি ওয়েবপ্যাক এবং ব্যাবেল ব্যবহার করে মূল / index.js ফাইলটি বান্ডিল করছি। এগুলি সব প্রশ্নের মধ্যে ব্যাখ্যা করা হয়েছে।
পাওয়ারবয়

এটি আপনাকে সাহায্য করতে পারে - danielberndt.net/blog/2018/…
অভিষেক

আপনি তাদের বিল্ড বাস্তবায়নেও পারবেন - github.com/mui-org/matory-ui/blob/master/packages/matory-ui/… সংক্ষিপ্ত বিল্ড আকারের জন্য আরও ভাল করার জন্য import { MyClass } from 'my-package/src/MyClass';। আপনি ফাইলের পথটি সংক্ষিপ্ত করতে src বিল্ড প্যাকেজিংটিও সরাতে পারেন।
অভিষেক

উত্তর:


1

আমি অনুভব করেছি যে আপনি যখন ইতিমধ্যে বান্ডেলযুক্ত প্যাকেজের অংশগুলি আমদানির চেষ্টা করছেন তখন ওয়েবপ্যাকটি কীভাবে কাজ করে?

হ্যাঁ, আপনি যেভাবে এটি সেট আপ করেছেন তা হ'ল সূচি.জেজে প্রতিটি শ্রেণি আমদানি করে যা পরে একটি ফাইলে স্থানান্তরিত হয় (যদি এটি ES5 টার্গেট করে, যা সবচেয়ে সাধারণ * হয়)। এর অর্থ হ'ল সেই ফাইলটি যখন অন্য কোনও ফাইলে আমদানি করা হয় তখন সমস্ত শ্রেণীর সাথে এটি সম্পূর্ণরূপে আসে।

আপনি যদি যথাযথ গাছ কাঁপতে চান তবে আপনার এটি একটি সাধারণ জেএস (ইএস 5) বান্ডেলে স্থানান্তর করা এড়ানো উচিত। আমার পরামর্শ হ'ল ES6 মডিউলগুলি নিজে থেকে বা ES5 বান্ডেল থেকে পৃথক স্থানে রাখা। এই নিবন্ধটি আপনাকে এটি পুরোপুরি বুঝতে সহায়তা করবে এবং নির্দেশাবলীর সুপারিশ করেছে। মূলত এটি ES6 সিনট্যাক্স সংরক্ষণের জন্য প্রিসেট-এনভ (আপনি ইতিমধ্যে এটি ব্যবহার করছেন না যদি উচ্চ প্রস্তাবিত!) ব্যবহার করে বাবেল পরিবেশ নির্ধারণে ফোটে । আপনি যদি ইএস 5 এ স্থানান্তর করতে না চান তবে এখানে প্রাসঙ্গিক বাবেল কনফিগারেশন রয়েছে:

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

নিবন্ধে 2 টি বান্ডিল কীভাবে সেটআপ করা যায় তার প্রতিটি বিশদ আলাদা মডিউল বাক্য গঠন ব্যবহার করে details

এছাড়াও লক্ষণীয়, এবং নিবন্ধে যেমন উল্লেখ করা হয়েছে, আপনি প্যাকেজ.জসনে ইএস মডিউল এন্ট্রি পয়েন্ট সেট করতে পারেন । এটি ওয়েবপ্যাক / ব্যাবেলকে জানায় যেখানে ES6 মডিউলগুলি পাওয়া যায়, যা আপনার ব্যবহারের ক্ষেত্রে আপনার প্রয়োজন হতে পারে। মনে হয় প্রচলিত জ্ঞান যা করতে বলে:

{
  "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"
  }
}

আমার যদি সময় থাকে তবে আমি এটি নিয়ে ঘুরে দেখতাম এবং কোনটি সঠিকভাবে কাজ করে তা দেখতে পাবে তবে এটি আপনাকে সঠিক পথে চালিত করার জন্য যথেষ্ট should


* ES5- লক্ষ্যযুক্ত বান্ডিলগুলি কমনজেএস ফর্ম্যাটে রয়েছে, এতে সমস্ত সম্পর্কিত ফাইল অন্তর্ভুক্ত করতে হবে, কারণ ES5 এর নেটিভ মডিউল সমর্থন নেই। এটি ES2015 / ES6 এ এসেছিল।


আমি যুক্ত করার চেষ্টা করেছি targets.esmodules: trueএবং এটি নির্মিত স্ক্রিপ্টে পরিবর্তনগুলি করার সময়, শেষ পর্যন্ত কী আমদানি হয়েছিল তা কোনও পরিবর্তন হয়নি। my-packageএখনও একটি একক শ্রেণি থেকে আমদানি করা সবকিছু আমদানি করে। আমি package.json(অন্যান্য পরিবর্তনের পাশাপাশি) পরিবর্তনগুলিও চেষ্টা করেছিলাম এবং সেও কোনও পরিবর্তন হয়নি। ওয়েল, type: module"ইএস মডিউলটি লোড করতে অবশ্যই আমদানি ব্যবহার করতে হবে: / ই স্লিউইউইই / ওয়েবেপ্যাক.কনফিগ.জেস (ইএস মডিউলগুলির প্রয়োজনীয়) সমর্থন করে না, এটি সহ আমার বিল্ডটি ভেঙে দিয়েছে।" সুতরাং আমি যে বিট অপসারণ করতে হবে। আমি লিঙ্কিত নিবন্ধটি একবার দেখব।
পাওয়ারবয়

ঠিক আছে তাই নিবন্ধটি আসলে আমাকে সেট করার জন্য বলেছিল modules: false(অভ্যন্তরীণ নয় targets) তবে এটিও কার্যকর হয়নি ... আমি মনে করি কেবল উত্স ফাইল থেকে সরাসরি আমদানি করব এবং নোড_মডিউলগুলির মাধ্যমে বাবেল চালিয়ে যাব যতক্ষণ না আমরা এই জিনিসটি স্থানীয়ভাবে ব্যবহার করতে পারি।
পাওয়ারবয়

@ পাওয়ারবুয় উত্স ফাইল থেকে আমদানি কাজ করে। সম্ভবত এটি আমার পোস্ট থেকে পরিষ্কার ছিল না, এবং যদি এটি হয় তবে আমি এটি সম্পাদনা করতে পারি, তবে আপনি কেবল শ্রেণীর মতোই আমদানি করতে চান import MyClass from 'my-package/myClass';। এই একটি ভাল রেপো উদাহরণ lodash-স্প্যানিশ ভাষায়
ক্যাটলিন ওয়েব

-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'। সহজ কিছু.

আনন্দ কর!


আমি ঠিক ইতিমধ্যে এটি করছি যা আমি ভেবেছিলাম যে প্রশ্নে বেশ পরিষ্কার ছিল।
পাওয়ারবয়
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.