नोड 6 में ईएस 6 चर आयात नाम?


108

ES6 आयात का उपयोग करते हुए चर नाम प्रदान करने वाले मॉड्यूल में कुछ आयात करना संभव है?

यानी मैं एक विन्यास में दिए गए मूल्यों के आधार पर कुछ मॉड्यूल को रनटाइम पर आयात करना चाहता हूं:

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

1
@Bigood हाँ, संकलक ऊपर फेंकता है और Webstorm भी एक त्रुटि से पता चलता
वायटॉटस बटकस

जवाबों:


67

importबयान के साथ नहीं । importऔर exportइस तरह से परिभाषित किया गया है कि वे सांख्यिकीय रूप से विश्लेषण योग्य हैं, इसलिए वे रनटाइम जानकारी पर निर्भर नहीं हो सकते हैं।

आप लोडर API (पॉलीफ़िल) की तलाश कर रहे हैं , लेकिन मैं विनिर्देश की स्थिति के बारे में थोड़ा अस्पष्ट हूँ:

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

3
क्या मुझे "सिस्टम" की आवश्यकता है? यह वैश्विक स्कोप पर नहीं है .. Ps मैं बैबल js का उपयोग कर रहा हूं
व्युटुटास बटुकस

यह कहीं भी अभी तक लागू नहीं है AFAIK। आपको लिंक से पॉलीफिल का उपयोग करना होगा।
फेलिक्स क्लिंग

1
बस की जाँच की, यह थोड़े काम करता है (फ़ाइल लोड करने की कोशिश करता है), लेकिन फिर अन्य मॉड्यूल के लिए रास्तों को गड़बड़ कर देता है ... बहुत बुरा यह मूल रूप से समर्थित नहीं है ..
व्यतुतास बुटकस

3
क्या यह अभी भी एक मुद्दा है? मुझे
ईएस

26

फेलिक्स के उत्तर के अलावा , मैं स्पष्ट रूप से ध्यान दूंगा कि वर्तमान में ECMAScript 6 व्याकरण द्वारा इसकी अनुमति नहीं है :

आयात :

  • आयात ImportClause FromClause;

  • मॉड्यूल मॉड्यूल आयात करें;

FromClause :

  • से ModuleSpecifier

मॉड्यूल की संख्या :

  • शाब्दिक स्ट्रिंग

एक 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-fin.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');
   }
}

बक्सों का इस्तेमाल करें

उपयोग-मामलों में मार्ग आधारित घटक शामिल हैं जो रिएक्ट, वीयू आदि के लिए आयात करते हैं और एक बार लोड करने के दौरान आलसी लोड मॉड्यूल की क्षमता की आवश्यकता होती है।

अग्रिम जानकारी

यहाँ Google डेवलपर्स पर एक स्पष्टीकरण दिया गया है ।

ब्राउज़र संगतता (अप्रैल 2020)

MDN के अनुसार यह हर मौजूदा प्रमुख ब्राउज़र (IE को छोड़कर) द्वारा समर्थित है और caniuse.com वैश्विक बाजार में शेयर का 87% समर्थन दिखाता है। IE या गैर-क्रोमियम एज में फिर से कोई समर्थन नहीं।


क्या आप अपने संपादन के बारे में निश्चित हैं? प्रस्ताव एक चर मार्ग के साथ एक उदाहरण दिखाता है: github.com/tc39/proposal-dynamic-import#example
phil294

@ बेलौहिर मैं था, लेकिन आपके लिंक से स्पष्ट है कि यह एक संभावना है। हालांकि मुझे पता नहीं है कि वेबपैक, उदाहरण के लिए इन आयातों को कैसे हल करेगा
निकोलई श्मिट

सही है अगर मैं गलत हूँ, लेकिन वेबपैक इनको संसाधित नहीं करता है, क्या यह? मुझे लगा कि यह गतिशील आयात का बिंदु था जो वे ब्राउज़र में "जैसा है" चलाते हैं।
दर्शन २

हां, आप उन्हें ब्राउज़र में चला सकते हैं। लेकिन वेबपैक स्वचालित रूप से आपके ऐप के विभिन्न भागों के लिए आपके ऐप को कई बंडल में विभाजित करने के लिए आयात का उपयोग करता है, उदाहरण के लिए मार्गों के लिए। मैं हर समय उनका उपयोग करता हूं और वे वास्तव में मददगार हैं। और जहां तक ​​"प्रसंस्करण" जाता है; वेबपैक आयात को पारित करेगा, जो पुराने ब्राउज़रों के लिए फीचर को पॉलीफ़िल करेगा।
निकोलई श्मिट

स्पष्ट होने के लिए: डायनेमिक आयात () चर के साथ काम करेगा और सांख्यिकीय रूप से विश्लेषण करने योग्य होने की आवश्यकता नहीं है (यह 'डायनामिक' का पूरा बिंदु है, निश्चित रूप से?)। मेरा जवाब देखिए।
वेलोजेट

6

मैं विशेष रूप importसे Node.js में ES6 के लिए पूछे गए प्रश्न को समझता हूं , लेकिन निम्नलिखित अन्य लोगों को अधिक सामान्य समाधान खोजने में मदद कर सकते हैं:

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
@UlysseBN एक बुरे तरीके से अलग? या ऐसा तरीका जो वास्तव में मायने नहीं रखता?
सैम

@ जैकब वे वास्तव में पूरी तरह से अलग हैं, इसलिए हाँ यह इस बात पर निर्भर करता है कि आप क्या कर रहे हैं। पहले वाक्यविन्यास का सांख्यिकीय रूप से मूल्यांकन किया जाता है, जबकि दूसरे का गतिशील मूल्यांकन किया जाता है। उदाहरण के लिए, यदि आप वेबपैक का उपयोग कर रहे हैं, तो यह दूसरे के साथ सही ढंग से ट्री-शेकिंग करने के लिए नहीं होगा। कई अन्य अंतर हैं, मैं आपको सुझाव देता हूं कि डॉक्टर को पढ़ें और देखें कि आपके लिए कौन सा उपयुक्त है!
उलेसे बीएन

@ जैकब - वास्तव में कोई बात नहीं (ज्यादातर मामलों में)। require()फ़ाइलें लोड करने के लिए एक Node.JS विधि है, जो प्रारंभिक संस्करण है। importबयान नया संस्करण है, जो अब आधिकारिक भाषा वाक्य रचना का हिस्सा है। हालाँकि कई मामलों में ब्राउज़र पिछले एक (विज्ञान के पीछे) का उपयोग करेगा। आवश्यकता विवरण आपकी फ़ाइलों को भी कैश करेगा, इसलिए यदि कोई फ़ाइल 2 बार लोड होती है तो इसे मेमोरी (बेहतर प्रदर्शन) से लोड किया जाएगा। आयात के तरीके के अपने फायदे हैं - यदि आप वेबपैक का उपयोग कर रहे हैं। तब वेबपैक मृत संदर्भों को हटा सकता है (ये स्क्रिप्ट क्लाइंट को डाउनलोड नहीं की जाएगी)।
गिल एप्सटेन


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

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