मैं सशर्त रूप से एक ES6 मॉड्यूल कैसे आयात कर सकता हूं?


193

मुझे कुछ ऐसा करने की आवश्यकता है:

if (condition) {
    import something from 'something';
}
// ...
if (something) {
    something.doStuff();
}

उपरोक्त कोड संकलन नहीं करता है; यह फेंकता है SyntaxError: ... 'import' and 'export' may only appear at the top level

मैंने यहांSystem.import दिखाए अनुसार उपयोग करने की कोशिश की , लेकिन मुझे नहीं पता कि कहां से आता है। क्या यह ES6 का प्रस्ताव है जिसे स्वीकार नहीं किया गया है? उस लेख से "प्रोग्रामेटिक एपीआई" का लिंक मुझे एक हटाए गए डॉक्स पृष्ठ पर ले जाता हैSystem


बस इसे सामान्य रूप से आयात करें। आपके मॉड्यूल को इसकी आवश्यकता है।
एंडी

मैं वास्तव में किसी भी कारण से नहीं देखता कि आप सिर्फ शर्त की परवाह किए बिना आयात क्यों नहीं करेंगे। यह ऐसा नहीं है कि कुछ प्रकार के ओवरहेड हैं। कुछ परिदृश्य में आपको फ़ाइल की आवश्यकता होती है, इसलिए ऐसा नहीं है कि ऐसा कोई मामला है जहां इसे पूरी तरह से छोड़ दिया जा सके। उस मामले में, बस बिना शर्त आयात करें।
धन्यवाद

8
मेरा उपयोग मामला: मैं एक वैकल्पिक निर्भरता रखना आसान बनाना चाहता हूं। यदि dep की आवश्यकता नहीं है, तो उपयोगकर्ता इसे हटा देता है package.json; मेरी gulpfileतब जाँच करता है कि कुछ निर्माण करने से पहले निर्भरता मौजूद है।
एरिकिक्सो

1
एक और उपयोग मामला: परीक्षण के प्रयोजनों के लिए। मैं उपयोग कर रहा हूं webpackऔर babeles6 को es5 में ट्रांसपाइल कर रहा हूं । इस तरह की परियोजनाएँ webpack-rewireऔर समान यहाँ मदद करने के लिए नहीं हैं - github.com/jhnns/rewire-webpack/issues/12 । परीक्षण सेट करने का एक तरीका या समस्याग्रस्त निर्भरता को दूर करने के लिए सशर्त आयात हो सकता है।
Amio.io

3
+1। कई वातावरणों में एक मॉड्यूल का उपयोग करने में सक्षम होना जहां निर्भरता काम नहीं कर सकती है या महत्वपूर्ण है, खासकर जब मॉड्यूल निर्भरता को संदर्भित कर सकते हैं जो केवल ब्राउज़र में काम करेगा (जैसे कि webpackस्टाइलशीट को मॉड्यूल में बदलने के लिए उपयोग किया जाता है जो प्रासंगिक शैलियों को सम्मिलित करता है DOM जब वे आयात किए जाते हैं), लेकिन मॉड्यूल को ब्राउज़र के बाहर चलाने की भी आवश्यकता होती है (जैसे इकाई परीक्षण के लिए)।
जूल्स

जवाबों:


143

हमारे पास ईसीएमए के साथ अब गतिशील आयात प्रस्ताव है। यह चरण 3 में है। यह बेबल-प्रीसेट के रूप में भी उपलब्ध है ।

निम्नलिखित आपके मामले के अनुसार सशर्त प्रतिपादन करने का तरीका है।

if (condition) {
    import('something')
    .then((something) => {
       console.log(something.something);
    });
}

यह मूल रूप से एक वादा वापस करता है। वादे के समाधान में मॉड्यूल होने की उम्मीद है। प्रस्ताव में कई अन्य विशेषताएं भी हैं जैसे कई गतिशील आयात, डिफ़ॉल्ट आयात, जेएस फ़ाइल आयात आदि। आप यहाँ गतिशील आयात के बारे में अधिक जानकारी प्राप्त कर सकते हैं ।


13
अंत में, एक वास्तविक, ES6 उत्तर! साभार @thecodejack अब इस लेख के अनुसार, इस लेख के अनुसार चरण 3 पर।
एरिक्सोको

5
या अगर आपने निर्यात को नाम दिया है तो आप विनाश कर सकते हैं:if (condition) { import('something') .then(({ somethingExported }) => { console.log(somethingExported); }); }
ivn

4
Firefox पर और जबकि चल रहा है npm run buildमैं अभी भी त्रुटि मिलती है:SyntaxError: ... 'import' and 'export' may only appear at the top level
काएं

1
@stackjlei: यह सुविधा अभी तक जावास्क्रिप्ट मानक का हिस्सा नहीं है, यह सिर्फ एक चरण 3 का प्रस्ताव है! हालाँकि यह पहले से ही कई नए ब्राउज़रों में लागू है, caniuse.com/#feat=es6-module-dynamic-import देखें ।
कोनराड हॉफनर

1
यह सशर्त गतिशील आयात फ़ंक्शन में केवल विशेष तत्वों को आयात करने की बारीक क्षमता नहीं है जो "Y से X आयात करता है"। वास्तव में, गतिशील भार में ठीक दाने की क्षमता और भी महत्वपूर्ण हो सकती है (जैसा कि प्रीप्रोसेस बंडलिंग के विपरीत)
क्रेग हिक्स

101

यदि आप चाहें, तो आप आवश्यकता का उपयोग कर सकते हैं। यह सशर्त आवश्यकता वाले बयान का एक तरीका है।

let something = null;
let other = null;

if (condition) {
    something = require('something');
    other = require('something').other;
}
if (something && other) {
    something.doStuff();
    other.doOtherStuff();
}

1
मुझे लगता है कि कुछ और अन्य वैरिएबल कास्ट का उपयोग करके डिक्लेयर कर दिए गए हैं जो ब्लॉक स्कूप्ड है, इसलिए दूसरा अगर हालत फेंक देगा कि कुछ परिभाषित नहीं है
मोहम्मद एसेमी

बेहतर होगा कि 'वेर' का उपयोग करने के बजाय ब्लॉक के बाहर दो वैरिएबल का उपयोग करें और घोषित करें और ब्लॉक स्कोप को पूरी तरह से बचें।
वोरकॉन

क्या इस मामले में उत्थापन कुछ भी प्रभावित करता है? मैंने कुछ समस्याओं में भाग लिया है, जहां उत्थापन का मतलब है कि स्मृति के कार्य करने के दौरान एक पैटर्न के करीब होने पर मैंने एक पुस्तकालय का आयात किया है।
थॉमस

11
यह इंगित करने की आवश्यकता है कि require()मानक जावास्क्रिप्ट का हिस्सा नहीं है - यह Node.js में एक अंतर्निहित फ़ंक्शन है, इसलिए केवल उस वातावरण में उपयोगी है। ओपी Node.js. के साथ काम करने का कोई संकेत नहीं देता है
वेलोजेट

55

आप सशर्त आयात नहीं कर सकते, लेकिन आप इसके विपरीत कर सकते हैं: सशर्त रूप से कुछ निर्यात करें। यह आपके उपयोग के मामले पर निर्भर करता है, इसलिए यह कार्य आपके लिए नहीं हो सकता है।

तुम कर सकते हो:

api.js

import mockAPI from './mockAPI'
import realAPI from './realAPI'

const exportedAPI = shouldUseMock ? mockAPI : realAPI
export default exportedAPI

apiConsumer.js

import API from './api'
...

मैं इसका उपयोग एनालिटिक्स जैसे कि मिक्सपैन, आदि ... के लिए मज़ाक उड़ाने के लिए करता हूँ क्योंकि मेरे पास इस समय कई बिल्ड या हमारे सामने नहीं हो सकते हैं। सबसे सुरुचिपूर्ण नहीं है, लेकिन काम करता है। मेरे पास पर्यावरण के आधार पर यहां और वहां कुछ 'अगर' है, क्योंकि मिक्सडेल के मामले में, इसे आरंभीकरण की आवश्यकता है।


39
यह समाधान अवांछित मॉड्यूल को लोड करने का कारण बनता है, इसलिए एक इष्टतम समाधान नहीं है, मुझे लगता है।
इमेलारिलिक

5
जैसा कि उत्तर में कहा गया है, यह एक काम है। उस समय, बस कोई समाधान नहीं था। ES6 आयात गतिशील नहीं हैं, यह डिजाइन द्वारा है। ES6 डायनामिक इंपोर्ट फंक्शन प्रपोजल, जो वर्तमान में स्वीकृत उत्तर में वर्णित है, वह कर सकता है। जेएस विकसित हो रहा है :)
केव

9

ऐसा लगता है कि इसका उत्तर यह है कि अभी तक आप ऐसा नहीं कर सकते हैं।

http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api

मुझे लगता है कि आशय यह है कि स्थैतिक विश्लेषण को अधिक से अधिक सक्षम किया जाए, और सशर्त रूप से आयातित मॉड्यूल को तोड़ दिया जाए। यह भी उल्लेख के लायक है - मैं बैबल का उपयोग कर रहा हूं , और मैं अनुमान लगा रहा हूं कि Systemबेबल द्वारा समर्थित नहीं है क्योंकि मॉड्यूल लोडर एपीआई ईएस 6 मानक नहीं बन गया है।


@FelixKling इसे अपना उत्तर बनाता है और मैं इसे खुशी से स्वीकार करूंगा!
एरिकिक्सो

4

require()रन टाइम पर कुछ मॉड्यूल आयात करने का एक तरीका है और यह समान रूप से स्थैतिक विश्लेषण के लिए योग्य है जैसे importकि स्ट्रिंग शाब्दिक रास्तों के साथ प्रयोग किया जाता है। बंडल के लिए निर्भरता लेने के लिए बंडल के लिए यह आवश्यक है।

const defaultOne = require('path/to/component').default;
const NamedOne = require('path/to/component').theName;

पूर्ण स्थैतिक विश्लेषण समर्थन के साथ डायनेमिक मॉड्यूल रिज़ॉल्यूशन के लिए, इंडेक्सर (index.js) में पहला इंडेक्स मॉड्यूल और होस्ट मॉड्यूल में इंपोर्ट इंडेक्सर।

// index.js
export { default as ModuleOne } from 'path/to/module/one';
export { default as ModuleTwo } from 'path/to/module/two';
export { SomeNamedModule } from 'path/to/named/module';

// host.js
import * as indexer from 'index';
const moduleName = 'ModuleOne';
const Module = require(indexer[moduleName]);

7
यह इंगित करने की आवश्यकता है कि require()मानक जावास्क्रिप्ट का हिस्सा नहीं है - यह Node.js में एक अंतर्निहित फ़ंक्शन है, इसलिए केवल उस वातावरण में उपयोगी है। ओपी Node.js. के साथ काम करने का कोई संकेत नहीं देता है
वेलोजेट

2

महत्वपूर्ण अंतर यदि आप डायनेमिक आयात वेबपैक मोड का उपयोग करते हैं eager:

if (normalCondition) {
  // this will be included to bundle, whether you use it or not
  import(...);
}

if (process.env.SOMETHING === 'true') {
  // this will not be included to bundle, if SOMETHING is not 'true'
  import(...);
}

लेकिन importएक वादा वापस करता है।
newguy 8

0

यह मेरे लिए काम करने के लिए अस्पष्ट है, इसे स्थिर विश्लेषक से छिपाकर ...

if (typeof __CLI__ !== 'undefined') {
  eval("require('fs');")
}

3
किसी को भी समझा सकते हैं कि यह जवाब क्यों दिया गया? क्या कोई वास्तविक कमियां हैं या यह केवल बुरे कीवर्ड 'ईवैल' के लिए स्वचालित नकारात्मक प्रतिक्रिया थी?
यूरी गोर

3
छिपाने योग्य कीवर्ड का उपयोग करने के लिए स्वचालित डाउनवोट। दूर रहो।
टॉरमॉड ह्यूजेन

1
क्या आप बता सकते हैं कि evalयहाँ, @TormodHaugene के उपयोग में वास्तव में क्या गलत है ?
एडम बार्न्स

एमडीएन का evalउपयोग न किए जाने के कुछ कारण हैं । सामान्य तौर पर: यदि आप उपयोग करने की आवश्यकता पाते हैं eval, तो आप शायद इसे गलत कर रहे हैं और अपने विकल्पों पर विचार करने के लिए एक कदम वापस लेना चाहिए। संभवत: कुछ परिदृश्य ऐसे हैं जहां उपयोग evalकरना सही है, लेकिन आप सबसे अधिक संभावना है कि उन स्थितियों में से एक का सामना नहीं किया है।
टॉरमॉड ह्यूजेन

5
यह इंगित करने की आवश्यकता है कि require()मानक जावास्क्रिप्ट का हिस्सा नहीं है - यह Node.js में एक अंतर्निहित फ़ंक्शन है, इसलिए केवल उस वातावरण में उपयोगी है। ओपी Node.js. के साथ काम करने का कोई संकेत नहीं देता है
वेलोजेट

0

मैं इसे तुरंत लागू किए गए फ़ंक्शन का उपयोग करने और कथन की आवश्यकता के कारण प्राप्त करने में सक्षम था।

const something = (() => (
  condition ? require('something') : null
))();

if(something) {
  something.doStuff();
}

5
यह इंगित करने की आवश्यकता है कि require()मानक जावास्क्रिप्ट का हिस्सा नहीं है - यह Node.js में एक अंतर्निहित फ़ंक्शन है, इसलिए केवल उस वातावरण में उपयोगी है। ओपी Node.js. के साथ काम करने का कोई संकेत नहीं देता है
वेलोजेट

0

सशर्त आयात भी एक त्रिगुट और require()एस के साथ प्राप्त किया जा सकता है :

const logger = DEBUG ? require('dev-logger') : require('logger');

यह उदाहरण ईएस लिंट वैश्विक-आवश्यकता डॉक्स से लिया गया था: https://eslint.org/docs/rules/global-reire


5
यह इंगित करने की आवश्यकता है कि require()मानक जावास्क्रिप्ट का हिस्सा नहीं है - यह Node.js में एक अंतर्निहित फ़ंक्शन है, इसलिए केवल उस वातावरण में उपयोगी है। ओपी Node.js. के साथ काम करने का कोई संकेत नहीं देता है
वेलोजेट

0

गतिशील आयात कैसे काम करता है, इसकी स्पष्ट समझ के लिए इस उदाहरण को देखें।

डायनामिक मॉड्यूल आयात उदाहरण

मॉड्यूल आयात और निर्यात करने की बुनियादी समझ है।

जावास्क्रिप्ट मॉड्यूल Github

जावास्क्रिप्ट मॉड्यूल एमडीएन


0

नहीं, आप नहीं कर सकते!

हालाँकि, उस समस्या से टकराकर आपको अपने कोड को व्यवस्थित करने के तरीके पर पुनर्विचार करना चाहिए।

ईएस 6 मॉड्यूल से पहले, हमारे पास कॉमनजेएस मॉड्यूल थे जो आवश्यकता () सिंटैक्स का उपयोग करते थे। ये मॉड्यूल "गतिशील" थे, जिसका अर्थ है कि हम अपने कोड में शर्तों के आधार पर नए मॉड्यूल आयात कर सकते हैं। - स्रोत: https://bitsofco.de/what-is-tree-shaking/

मैं उन कारणों में से एक का अनुमान लगाता हूं जो ईएस 6 पर समर्थन को आगे बढ़ाते हैं, यह तथ्य है कि इसे संकलित करना बहुत मुश्किल या असंभव होगा।

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