it-roy-ru.com

Имя импорта переменной ES6 в node.js?

можно ли импортировать что-то в модуль с именем переменной при использовании импорта ES6?

То есть Я хочу импортировать некоторый модуль во время выполнения в зависимости от значений, представленных в конфигурации:

import something from './utils/' + variableName;
88
Vytautas Butkus

Не с заявлением import. import и export определены таким образом, что они статически анализируемы, поэтому они не могут зависеть от информации времени выполнения.

Вы ищете загрузчик API (polyfill) , но я немного неясен относительно статуса спецификации:

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

В дополнение к ответу Феликса , я прямо отмечу, что в настоящее время это не допускается грамматикой ECMAScript 6 :

ImportDeclaration:

  • import _ ​​ImportClause FromClause;

  • import _ ​​ModuleSpecifier;

FromClause:

  • from _ ​​ModuleSpecifier

ModuleSpecifier:

  • StringLiteral

ModuleSpecifier может быть только StringLiteral, но не выражением любого другого типа, например AdditiveExpression.

25
apsillers

Хотя это на самом деле не динамический импорт (например, в моих обстоятельствах все файлы, которые я импортирую ниже, будут импортированы и упакованы с помощью веб-пакета, а не выбраны во время выполнения), шаблон, который я использовал, может помочь в некоторых обстоятельствах: :

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

Мне интересно услышать отзывы об этом подходе :)

22
ptim

Существует новая спецификация, которая называется dynamic import для модулей ES . По сути, вы просто вызываете import('./path/file.js') и все готово. Функция возвращает обещание, которое разрешается с модулем, если импорт был успешным.

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

Случаи применения

Примеры использования включают импорт компонентов на основе route для React, Vue и т.д., А также возможность отложенной загрузки модулей, если они необходимы во время выполнения.

Дальнейшая информация

Вот объяснение на Google Developers .

Совместимость браузера

Согласно MDN он поддерживается каждым текущим браузером Chromium и в Firefox 66 за флагом.

7
Nicolai Schmid

вы можете использовать нотацию не-ES6, чтобы сделать это. вот что сработало для меня:

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

Мне меньше нравится этот синтаксис, но он работает:
вместо записи 

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

используйте этот синтаксис:

let memberName = require("path" + "fileName");
3
Gil Epshtain

Я бы сделал это так

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
0
april

Динамический импорт () (доступен в Chrome 63+) сделает вашу работу. Вот как:

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

Я понимаю вопрос, специально заданный для ES6 import в Node.js, но следующее может помочь другим в поиске более общего решения:

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;
0
MCTaylor17