[英]ES6 variable import name in node.js?
是否可以在使用 ES6 導入時將某些內容導入提供變量名的模塊中?
即我想根據配置中提供的值在運行時導入一些模塊:
import something from './utils/' + variableName;
不帶import
語句。 import
和export
的定義方式使得它們可以靜態分析,因此它們不能依賴於運行時信息。
您正在尋找loader API (polyfill) ,但我對規范的狀態有點不清楚:
System.import('./utils/' + variableName).then(function(m) {
console.log(m);
});
雖然這實際上不是動態導入(例如,在我的情況下,我在下面導入的所有文件都將由 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()
輕松地回退到默認值,如果我嘗試導入不存在的構造模板路徑,則會引發錯誤。
可以在此處找到 require 和 import 之間的良好示例和比較: http ://www.2ality.com/2014/09/es6-modules-final.html
從@iainastacio 重新導出的優秀文檔: http ://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles
我很想聽聽關於這種方法的反饋:)
除了Felix 的回答之外,我還要明確指出ECMAScript 6 語法目前不允許這樣做:
進口聲明:
導入ImportClause FromClause ;
導入模塊說明符;
從句:
- 來自模塊說明符
模塊說明符:
- 字符串字面量
ModuleSpecifier只能是StringLiteral ,不能是AdditiveExpression等任何其他類型的表達式。
有一個新規范稱為 ES 模塊的動態導入。 基本上,您只需調用import('./path/file.js')
就可以了。 該函數返回一個promise,如果導入成功,該promise 將與模塊一起解析。
async function importModule() {
try {
const module = await import('./path/module.js');
} catch (error) {
console.error('import failed');
}
}
用例包括為 React、Vue 等導入基於路由的組件,以及在運行時需要時延遲加載模塊的能力。
這是對Google Developers的解釋。
據MDN稱,當前所有主流瀏覽器(IE 除外)都支持它,而caniuse.com在全球市場份額中的支持率為 87%。 同樣不支持 IE 或非 Chromium Edge。
我了解在 Node.js 中專門針對 ES6 import
提出的問題,但以下內容可能會幫助其他人尋找更通用的解決方案:
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;
你可以使用非 ES6 符號來做到這一點。 這對我有用:
let myModule = null;
if (needsToLoadModule) {
myModule = require('my-module').default;
}
我不太喜歡這種語法,但它有效:
而不是寫
import memberName from "path" + "fileName";
// this will not work!, since "path" + "fileName" need to be string literal
使用這個語法:
let memberName = require("path" + "fileName");
動態 import() (在 Chrome 63+ 中可用)將完成您的工作。 就是這樣:
let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
我在使用Vue.js
時遇到了類似的問題:當您在構建時在import(variableName)
中使用變量時,Webpack 不知道在哪里尋找。 因此,您必須將其限制為具有適當擴展名的已知路徑,如下所示:
let something = import("@/" + variableName + ".js")
github中針對同一問題的答案對我非常有幫助。
./utils/test.js
export default () => {
doSomething...
}
從文件調用
const variableName = 'test';
const package = require(`./utils/${variableName}`);
package.default();
我會這樣做
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
這取決於。 您可以在動態導入中使用模板文字來基於變量導入文件。
我使用動態導入將.vue
文件添加到 vue 路由器。 我已經排除了Home.vue
視圖導入。
const pages = [
'About',
['About', 'Team'],
]
const nodes = [
{
name: 'Home',
path: '/',
component: Home,
}
]
for (const page of pages) {
if (typeof page === 'string') {
nodes.push({
name: page,
path: `/${page}`,
component: import(`./views/${page}.vue`),
})
} else {
nodes.push({
name: _.last(page),
path: `/${page.join('/')}`,
component: import(`./views/${_.last(page)}.vue`)
})
}
}
這對我有用。 我在 repli 上使用了 yarn + vite + vue。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.