簡體   English   中英

node.js 中的 ES6 變量導入名稱?

[英]ES6 variable import name in node.js?

是否可以在使用 ES6 導入時將某些內容導入提供變量名的模塊中?

即我想根據配置中提供的值在運行時導入一些模塊:

import something from './utils/' + variableName;

不帶import語句。 importexport的定義方式使得它們可以靜態分析,因此它們不能依賴於運行時信息。

您正在尋找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的解釋。

瀏覽器兼容性(2020 年 4 月)

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM