2016-04-01 4 views
74

мне нужно сделать что-то вроде:Как я могу условно импортировать модуль ES6?

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

Приведенный выше код не компилируется; он бросает SyntaxError: ... 'import' and 'export' may only appear at the top level.

Я пробовал использовать System.import как показано на рисунке here, но не знаю, где System. Это предложение ES6, которое не было принято? Ссылка на «программный API» из этой статьи сбрасывает меня до deprecated docs page.

+0

Просто импортировать его в обычном режиме. Ваш модуль нуждается в этом независимо. – Andy

+0

Я действительно не вижу причин, по которым вы не будете ввозить независимо от состояния. Это не похоже на какие-то накладные расходы. В каком-то сценарии вам нужен файл, поэтому он не похож на случай, когда он может быть полностью пропущен. В этом случае просто импортируйте его безоговорочно. – naomik

+3

Мой прецедент: я хочу, чтобы было легко иметь дополнительную зависимость. Если депка не нужна, пользователь удаляет ее из 'package.json'; мой 'gulpfile' затем проверяет, существует ли эта зависимость до выполнения некоторых шагов сборки. – ericsoco

ответ

32

Теперь у нас есть предложение динамического импорта с ECMA. Это в стадии 3. Это также доступно как babel-preset.

Ниже приведен способ выполнения условного рендеринга в соответствии с вашим случаем.

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

Это в основном возвращает обещание. Ожидается, что ожидается, что модуль обещания получит модуль. В предложении также есть другие функции, такие как множественный динамический импорт, импорт по умолчанию, импорт файла js и т. Д. Вы можете найти более подробную информацию о dynamic imports here.

+4

Наконец, реальный ответ ES6! Спасибо @ thecodejack. Фактически на этапе 3 на момент написания этой статьи, согласно этой статье сейчас. – ericsoco

+0

yep .. обновил ответ – thecodejack

9

Похоже, что ответ заключается в том, что на данный момент вы не можете.

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

Я думаю, что намерение состоит в том, чтобы включить статический анализ как можно больше, и условно импортированные модули сломаться, что. Также стоит упомянуть - я использую Babel, и я предполагаю, что System не поддерживается Babel, потому что API загрузчика модуля не стал стандартом ES6.

+1

Я думаю, вы ищете https://github.com/ModuleLoader/es6-module-loader. –

+0

@FelixKling делает это своим собственным ответом, и я с радостью приму это! – ericsoco

52

Если вы хотите, вы можете использовать require. Это способ иметь условное требование.

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

Вы не можете импортировать условно, но вы можете сделать обратное: экспортировать что-то условно. Это зависит от вашего варианта использования, поэтому эта работа может быть не для вас.

Вы можете сделать:

api.js

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

const exportedAPI = shouldUseMock ? mockAPI : realAPI 
export default exportedAPI 

apiConsumer.js

import API from './api' 
... 

Я использую, что макет аналитики ЛИЭС как mixpanel и т.д ... потому что я могу» t имеет несколько сборок или наш интерфейс. Не самый элегантный, но работает. У меня просто есть несколько «если» здесь и там в зависимости от среды, потому что в случае mixpanel ему нужна инициализация.

+5

Это решение вызывает загрузку нежелательных модулей, поэтому я не думаю, что это оптимальное решение. – ismailarilik

+1

Как указано в ответе, это обход. В то время решения просто не было. Импорт ES6 не является динамичным, это по дизайну. Предложение ES6 для динамического импорта, которое описано в принятом в настоящее время ответе, может это сделать. JS развивается :) – Amida

0

заслоняя его в Eval работал для меня, скрывая его от статического анализатора ...

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

Смежные вопросы