Имя импорта переменной ES6 в node.js?
Можно ли импортировать что-то в модуль, предоставляя имя переменной при использовании импорта ES6?
т.е. Я хочу импортировать некоторый модуль во время выполнения в зависимости от значений, представленных в config:
import something from './utils/' + variableName;
Ответы
Ответ 1
Не с инструкцией import
. import
и export
определяются таким образом, что они статически анализируются, поэтому они не могут зависеть от информации о времени выполнения.
Вы ищите API-интерфейс загрузчика (polyfill), но я немного неясен о состоянии спецификации:
System.import('./utils/' + variableName).then(function(m) {
console.log(m);
});
Ответ 2
В дополнение к ответу Феликса, я четко укажу, что в настоящее время это не разрешено грамматикой ECMAScript 6:
ImportDeclaration :
FromClause :
ModuleSpecifier :
Модуль ModuleSpecifier может быть только StringLiteral, а не любым другим выражением типа AdditiveExpression.
Ответ 3
Хотя на самом деле это не динамический импорт (например, в моих обстоятельствах все импортируемые мной файлы будут импортированы и упакованы с помощью webpack, не выбранных во время выполнения), шаблон, который я использовал, который может помочь в некоторые обстоятельства:
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
Мне интересно услышать отзывы об этом подходе:)
Ответ 4
Существует новая спецификация, которая называется динамическим импортом для модулей ES. По сути, вы просто вызываете import('./path/file.js')
и все import('./path/file.js')
. Функция возвращает обещание, которое разрешается с модулем, если импорт был успешным.
async function import() {
try {
const module = await import('./path/module.js');
} catch (error) {
console.error('import failed');
}
}
Случаи применения
Варианты использования включают импорт компонентов на основе маршрута для React, Vue и т.д., А также возможность отложенной загрузки модулей, если они необходимы во время выполнения.
Дальнейшая информация
Вот объяснение для разработчиков Google.
Совместимость браузера
Согласно MDN, он поддерживается каждым текущим браузером Chrome и в Firefox 66 за флагом.
Ответ 5
для этого вы можете использовать нотацию без ES6. это то, что сработало для меня:
let myModule = null;
if (needsToLoadModule) {
myModule = require('my-module').default;
}
Ответ 6
Мне меньше нравится этот синтаксис, но он работает:
вместо написания
import memberName from "path" + "fileName";
// this will not work!, since "path" + "fileName" need to be string literal
используйте этот синтаксис:
let memberName = require("path" + "fileName");
Ответ 7
Я бы сделал это так:
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
Ответ 8
Я понимаю вопрос, специально заданный для import
ES6 в 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;
Ответ 9
Динамический импорт() (доступен в Chrome 63+) сделает вашу работу. Вот как:
let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
Ответ 10
Использование строк шаблонов ES6 Мне удалось импортировать динамические переменные, вот мой boilerplate - это это универсальный Javascript, но он должен работать с различными конфигурациями:
const myImg = './cute.jpg'
<img src={require(`${myImg}`)} />