নোড.জেজে ES6 পরিবর্তনশীল আমদানির নাম?


108

ES6 আমদানি ব্যবহার করার সময় পরিবর্তনশীল নাম সরবরাহ করে মডিউলটিতে কিছু আমদানি করা কি সম্ভব?

অর্থাৎ আমি কোনও রানটাইমের সময় কোনও মডিউল একটি কনফিগারে প্রদত্ত মানের উপর নির্ভর করে আমদানি করতে চাই:

import something from './utils/' + variableName;

1
@ বিগুড হ্যাঁ, সংকলকটি ছুড়ে ফেলেছে এবং ওয়েবস্টর্মও একটি ত্রুটি দেখায়
বুটকাস

উত্তর:


67

importবিবৃতি দিয়ে নয় । importএবং exportএমনভাবে সংজ্ঞায়িত করা হয় যে এগুলি স্থিতিশীলভাবে বিশ্লেষণযোগ্য, তাই তারা রানটাইম তথ্যের উপর নির্ভর করতে পারে না।

আপনি লোডার এপিআই (পলিফিল) সন্ধান করছেন তবে আমি স্পেসিফিকেশনটির স্থিতি সম্পর্কে কিছুটা অস্পষ্ট:

System.import('./utils/' + variableName).then(function(m) {
  console.log(m);
});

3
আমার কি "সিস্টেম" দরকার? এটি কোনও বৈশ্বিক পরিসরে নয় ... PS আমি ব্যাবেল জেএস ব্যবহার করছি
ভিটায়টাস বাটকস

এটি এএফআইকে এখনও কোথাও প্রয়োগ করা হয়নি। লিঙ্কটি থেকে আপনাকে পলিফিল ব্যবহার করতে হবে।
ফেলিক্স ক্লিং

1
কেবলমাত্র পরীক্ষা করা হয়েছে, এটি কিন্ডা কাজ করে (ফাইলটি লোড করার চেষ্টা করে) তবে অন্য মডিউলগুলির জন্য পথগুলি গণ্ডগোল করে ... খুব খারাপ এটি স্থানীয়ভাবে সমর্থিত নয় ..
ভাইটাস বুটকাস

3
এই সমস্যাটি কি এখনও আছে? আমাকে দিনব্যাপী ইএস 6 মডিউলগুলি লোড করতে হবে তবে আমার সফলতা নেই ..
ক্যালবার্টস

26

ফেলিক্সের উত্তর ছাড়াও , আমি স্পষ্টভাবে নোট করব যে এটি বর্তমানে ইসমাস্ক্রিপ্ট gram ব্যাকরণ দ্বারা অনুমোদিত নয় :

আমদানি ঘোষণা :

  • আমদানি ক্লাস ফ্রম ক্লাউজ;

  • আমদানি মডিউলস্পিফায়ার;

ক্লাস থেকে :

  • মডিউলস্পিফায়ার থেকে

মডিউলস্পিফায়ার :

  • StringLiteral

একজন ModuleSpecifier শুধুমাত্র একটি হতে পারে StringLiteral , কোনো মত প্রকাশের অন্য কোন ধরনের AdditiveExpression


2
এটি একটি আফসোস যা এসকে অন্তর্ভুক্ত করার জন্য বাড়ানো হয়নি const string literal। তারা স্ট্যাটিকালি এনালাইজেবল, তাই না? এটি নির্ভরতার অবস্থানটিকে পুনরায় ব্যবহার করার সম্ভাবনা তৈরি করে। (যেমন একটি টেম্পলেট আমদানি করুন এবং টেমপ্লেট এবং টেমপ্লেটের অবস্থান উভয়ই থাকুন)।
নিকোডেমাস 13

26

যদিও এটি আসলে গতিশীল আমদানি নয় (যেমন আমার পরিস্থিতিতে, আমি নীচে আমদানি করছি এমন সমস্ত ফাইল ওয়েবপ্যাক দ্বারা আমদানি করা এবং বান্ডিল করা হবে, রানটাইমের সময় নির্বাচিত নয়), এমন একটি প্যাটার্ন যা আমি ব্যবহার করছি যা কিছু পরিস্থিতিতে সহায়তা করতে পারে তা হ'ল :

import Template1 from './Template1.js';
import Template2 from './Template2.js';

const templates = {
  Template1,
  Template2
};

export function getTemplate (name) {
  return templates[name];
}

বা বিকল্পভাবে:

// index.js
export { default as Template1 } from './Template1';
export { default as Template2 } from './Template2';


// OtherComponent.js
import * as templates from './index.js'
...
// handy to be able to fall back to a default!
return templates[name] || templates.Template1;

আমি মনে করি না যে আমি সহজেই কোনও ডিফল্টে ফিরে যেতে পারি require(), যা যদি অস্তিত্বহীন একটি নির্মিত টেম্পলেট পথ আমদানির চেষ্টা করি তবে একটি ত্রুটি ছুঁড়ে দেয়।

প্রয়োজনীয় এবং আমদানির মধ্যে ভাল উদাহরণ এবং তুলনা এখানে পাওয়া যাবে: http://www.2ality.com/2014/09/es6-modules-final.html

উপর চমৎকার ডকুমেন্টেশন @iainastacio থেকে পুনরায় রপ্তানি: http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles

আমি এই পদ্ধতির প্রতিক্রিয়া শুনতে আগ্রহী :)


ভোট দিন। আমি "বা বিকল্পভাবে" পদ্ধতির ব্যবহার করেছি। আমার কাস্টম স্থানীয়করণ সমাধানের জন্য কবজির মতো কাজ করেছে।
গ্রাউন্ড0জি


1
আমার এই কথা ভাবা উচিত ছিল। দুর্দান্ত সমাধান, আপনি কীভাবে জিনিসগুলি আমদানি করছেন তা বিবেচ্য নয় (এবং আপনি যদি কিছু আমদানি নাও করেন)। আপনি যে আইটেমের নাম পেতে চান বা একটি নাম পরে পেতে চান তার একটি তালিকা আছে? এগুলি অ্যারে আক্ষরিকের পরিবর্তে কোনও বস্তুর আক্ষরিক মধ্যে রাখুন এবং তাদের স্থানীয় ধ্রুবক / পরিবর্তনশীল নামের উপর ভিত্তি করে অবজেক্ট সিন্টেক্স তাদের নামকরণের যত্ন নিতে দিন। যদি আপনার আবার তালিকা হিসাবে প্রয়োজন হয় তবে ঠিক করুন Object.values(templates)
অ্যান্ড্রু কোস্টার

15

একটি নতুন স্পেসিফিকেশন রয়েছে যা ইএস মডিউলগুলির জন্য ডায়নামিক আমদানি বলে । মূলত, আপনি কেবল কল করেছেন import('./path/file.js')এবং আপনি যেতে ভাল। ফাংশনটি একটি প্রতিশ্রুতি দেয়, যা আমদানি সফল হলে মডিউলটির সাথে সমাধান করে।

async function importModule() {
   try {
      const module = await import('./path/module.js');
   } catch (error) {
      console.error('import failed');
   }
}

ব্যবহারের ক্ষেত্রে

ব্যবহারের ক্ষেত্রে রিট, ভিউ ইত্যাদির জন্য রুট ভিত্তিক উপাদান আমদানি এবং রানটাইমের সময় একবার প্রয়োজন হলে অলস লোড মডিউলগুলির দক্ষতা অন্তর্ভুক্ত ।

আরো তথ্য

গুগল বিকাশকারীদের সম্পর্কে এখানে একটি ব্যাখ্যা দেওয়া আছে ।

ব্রাউজারের সামঞ্জস্যতা (এপ্রিল 2020)

এমডিএন অনুসারে এটি প্রতিটি বর্তমান প্রধান ব্রাউজার (আইই বাদে) দ্বারা সমর্থিত এবং ক্যানিজ ডট কম বিশ্বব্যাপী বাজারের শেয়ার জুড়ে ৮ 87% সমর্থন দেখায়। আবার আইই বা নন-ক্রোমিয়াম এজ তে কোনও সমর্থন নেই।


আপনি কি আপনার সম্পাদনা সম্পর্কে নিশ্চিত? প্রস্তাবটি একটি পরিবর্তনশীল পথ সহ একটি উদাহরণ দেখায়: github.com/tc39/proposal-dynamic-import#example
phil294

@ ব্লাউহিরন আমি ছিলাম, তবে আপনার লিঙ্কটি পরিষ্কারভাবে দেখায় যে এটি একটি সম্ভাবনা। যদিও ওয়েবপ্যাক কীভাবে আমার কোনও ধারণা নেই, উদাহরণস্বরূপ এই আমদানিগুলি সমাধান করবে
নিকোলাই শ্মিড

আমি ভুল হলে আমাকে সংশোধন করুন, কিন্তু ওয়েবপ্যাকগুলি এগুলি প্রক্রিয়া করে না, তাই না? আমি ভেবেছিলাম এটি গতিশীল আমদানির পয়েন্ট যা তারা ব্রাউজারে "যেমন আছে" চালায়।
ফিলি 294

হ্যাঁ, আপনি সেগুলি ব্রাউজারে চালাতে পারেন। তবে ওয়েবপ্যাকটি স্বয়ংক্রিয়ভাবে আমদানিগুলি আপনার অ্যাপ্লিকেশনটির বিভিন্ন অংশের জন্য একাধিক বান্ডেলে বিভক্ত করতে আমদানিগুলি ব্যবহার করে, উদাহরণস্বরূপ রুটের জন্য। আমি তাদের সব সময় ব্যবহার করি এবং তারা সত্যই সহায়ক। এবং "প্রসেসিং" যতদূর যায়; ওয়েবপ্যাকটি আমদানি বাবেলকে পাস করবে, যা পুরানো ব্রাউজারগুলির জন্য বৈশিষ্ট্যটি পলফিল করবে।
নিকোলাই শ্মিড

পরিষ্কার হওয়ার জন্য: গতিশীল আমদানি () পরিবর্তনশীলগুলির সাথে কাজ করবে এবং এটি স্ট্যাটিকালি বিশ্লেষণযোগ্য হতে হবে না (এটিই 'ডায়নামিক' এর পুরো পয়েন্ট, অবশ্যই?)। আমার উত্তর দেখুন।
ভেলোজেট

6

আমি বিশেষভাবে নোড.জেজে ES6 importএর জন্য জিজ্ঞাসা করা প্রশ্নটি বুঝতে পেরেছি , তবে নিম্নলিখিতগুলি আরও জেনেরিক সমাধান অনুসন্ধান করতে অন্যদের সহায়তা করতে পারে:

let variableName = "es5.js";
const something = require(`./utils/${variableName}`);

নোট আপনি যদি কোনও ES6 মডিউল আমদানি করে থাকেন এবং রফতানিটি অ্যাক্সেস করার defaultপ্রয়োজন হয় তবে আপনাকে নিম্নলিখিতগুলির একটি ব্যবহার করতে হবে:

let variableName = "es6.js";

// Assigning
const defaultMethod = require(`./utils/${variableName}`).default;

// Accessing
const something = require(`./utils/${variableName}`);
something.default();

আপনি এই পদ্ধতির সাথে ডেস্ট্রাকচারিং ব্যবহার করতে পারেন যা আপনার অন্যান্য আমদানির সাথে আরও সিনট্যাক্স পরিচিতি যুক্ত করতে পারে:

// Destructuring 
const { someMethod } = require(`./utils/${variableName}`);    
someMethod();

দুর্ভাগ্যক্রমে, আপনি যদি defaultধ্বংসের পাশাপাশি অ্যাক্সেস করতে চান তবে আপনাকে একাধিক পদক্ষেপে এটি সম্পাদন করতে হবে:

// ES6 Syntax
Import defaultMethod, { someMethod } from "const-path.js";

// Destructuring + default assignment
const something = require(`./utils/${variableName}`);

const defaultMethod = something.default;    
const { someMethod, someOtherMethod } = something;

4

আপনি এটি করার জন্য নন-ইএস 6 নোটেশনটি ব্যবহার করতে পারেন। এটিই আমার পক্ষে কাজ করেছে:

let myModule = null;
if (needsToLoadModule) {
  myModule = require('my-module').default;
}

3

আমি এই বাক্য গঠনটি কম পছন্দ করি তবে এটি কাজ করে:
লেখার পরিবর্তে

import memberName from "path" + "fileName"; 
// this will not work!, since "path" + "fileName" need to be string literal

এই বাক্য গঠনটি ব্যবহার করুন:

let memberName = require("path" + "fileName");

1
@ ইউলিসিবিএন কি খারাপ উপায়ে আলাদা? বা এমন উপায় যা আসলেই কিছু যায় আসে না?
স্যাম

@ জ্যাকব তারা সত্যিই সম্পূর্ণ আলাদা, তাই হ্যাঁ আপনি যা করছেন তার উপর নির্ভর করে তা বিবেচনাধীন হতে পারে। প্রথম বাক্য গঠনটি স্থিতিশীলভাবে মূল্যায়ন করা হয়, যেখানে দ্বিতীয়টি গতিশীলভাবে মূল্যায়ন করা হয়। সুতরাং উদাহরণস্বরূপ, আপনি যদি ওয়েবপ্যাক ব্যবহার করছেন তবে এটি দ্বিতীয়টির সাথে গাছের কাঁপানো সঠিকভাবে সম্পাদন করা হবে না। আরও অনেক পার্থক্য রয়েছে, আমি আপনাকে ডকটি পড়ার পরামর্শ দিচ্ছি এবং কোনটি আপনার পক্ষে উপযুক্ত তা দেখার জন্য!
ইউলিস বিএন

@ জ্যাকব - আসলেই কিছু যায় আসে না (বেশিরভাগ ক্ষেত্রে)। require()ফাইল লোড করার জন্য একটি নোড.জেএস পদ্ধতি, এটি প্রাথমিক সংস্করণ। importবিবৃতিটি নতুন সংস্করণ, যা এখন অফিশিয়াল ভাষা সিনট্যাক্সের অংশ। তবে অনেক ক্ষেত্রে ব্রাউজারটি আগেরটি (বিজ্ঞানের পিছনে) ব্যবহার করবে। প্রয়োজনীয় বিবৃতিটি আপনার ফাইলগুলি নগদও করবে, সুতরাং কোনও ফাইল যদি দ্বিতীয়বার লোড করা হয় তবে এটি মেমরি থেকে লোড হবে (আরও ভাল পারফরম্যান্স)। আমদানির উপায়টির নিজস্ব সুবিধা রয়েছে - যদি আপনি ওয়েবপ্যাক ব্যবহার করেন। তারপরে ওয়েবপ্যাকটি মৃত রেফারেন্সগুলি সরিয়ে ফেলতে পারে (এই স্ক্রিপ্টগুলি ক্লায়েন্টকে ডাউনলোড করা হবে না)।
গিল এপশেটেন

1

গতিশীল আমদানি () (ক্রোম 63+ এ উপলব্ধ) আপনার কাজ করবে job এখানে কীভাবে:

let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });

0

আমি এটি এইভাবে করতে হবে

function load(filePath) {
     return () => System.import(`${filePath}.js`); 
     // Note: Change .js to your file extension
}

let A = load('./utils/' + variableName)

// Now you can use A in your module

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