[英]Pass options to ES6 module imports
是否可以將選項傳遞給 ES6 導入?
你怎么翻譯這個:
var x = require('module')(someoptions);
ES6?
使用單個import
語句無法做到這一點,它不允許調用。
所以你不會直接調用它,但你基本上可以做與 commonjs 對默認導出所做的一樣的事情:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
或者,如果您使用支持單子承諾的模塊加載器,您可能可以執行類似的操作
System.import('module').ap(someoptions).then(function(x) {
…
});
有了新的import
操作符,它可能會變成
const promise = import('module').then(m => m(someoptions));
或者
const x = (await import('module'))(someoptions)
但是您可能不想要動態導入而是靜態導入。
這是我使用 ES6 的解決方案
與@Bergi 的響應非常一致,這是我在創建需要為class
聲明傳遞參數的導入時使用的“模板”。 這用於我正在編寫的同構框架,因此將在瀏覽器和 node.js 中使用轉譯器(我將Babel
與Webpack
一起使用):
./MyClass.js
export default (Param1, Param2) => class MyClass {
constructor(){
console.log( Param1 );
}
}
./main.js
import MyClassFactory from './MyClass.js';
let MyClass = MyClassFactory('foo', 'bar');
let myInstance = new MyClass();
以上將在控制台中輸出foo
編輯
對於一個真實的例子,我使用它來傳遞一個命名空間來訪問框架中的其他類和實例。 因為我們只是創建一個函數並將對象作為參數傳入,所以我們可以將它與我們的類聲明一起使用,如下所示:
export default (UIFramework) => class MyView extends UIFramework.Type.View {
getModels() {
// ...
UIFramework.Models.getModelsForView( this._models );
// ...
}
}
鑒於它是一個完整的框架,在我的情況下,導入有點復雜和automagical
,但基本上這就是正在發生的事情:
// ...
getView( viewName ){
//...
const ViewFactory = require(viewFileLoc);
const View = ViewFactory(this);
return new View();
}
// ...
我希望這有幫助!
我已經登陸這個線程,尋找一些類似的東西,並想提出一種解決方案,至少在某些情況下(但請參閱下面的備注)。
用例
我有一個模塊,它在加載后立即運行一些實例化邏輯。 我不喜歡在模塊外部調用這個初始化邏輯(這與 call new SomeClass(p1, p2)
或new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })
等)。
我確實喜歡這個初始化邏輯將運行一次,一種單一的實例化流程,但每個特定的參數化上下文運行一次。
例子
service.js
具有非常基本的范圍:
let context = null; // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));
模塊 A 可以:
import * as S from 'service.js'; // console has now "initialized in context root"
模塊 B 執行以下操作:
import * as S from 'service.js'; // console stays unchanged! module's script runs only once
到目前為止一切順利:兩個模塊都可以使用服務,但只初始化了一次。
問題
如何讓它作為另一個實例運行並在另一個上下文中再次初始化自己,比如在模塊 C 中?
解決方案?
這就是我正在考慮的:使用查詢參數。 在服務中,我們將添加以下內容:
let context = new URL(import.meta.url).searchParams.get('context');
模塊 C 會做:
import * as S from 'service.js?context=special';
模塊將被重新導入,它的基本初始化邏輯將運行,我們將在控制台中看到:
initialized in context special
備注:我自己建議不要過多地練習這種方法,而是把它作為最后的手段。 為什么? 多次導入的模塊更多的是例外而不是規則,因此它有些出乎意料的行為,因此可能會使消費者感到困惑甚至破壞它自己的“單例”范式(如果有的話)。
我相信你可以使用 es6 模塊加載器。 http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
您只需要添加這兩行。
import xModule from 'module';
const x = xModule('someOptions');
這是我以調試模塊為例對這個問題的看法;
在這個模塊的 npm 頁面上,你有這個:
var debug = require('debug')('http')
在上面的行中,一個字符串被傳遞給導入的模塊,以進行構造。 這是你在 ES6 中做同樣事情的方法
import { debug as Debug } from 'debug'
const debug = Debug('http');
希望這可以幫助那里的人。
我在嘗試將一些 CJS ( require()
) 代碼轉換為 ESM ( import
) 時遇到了一個類似的語法問題 - 這是我需要導入 Redis 時的工作:
CJS
const RedisStore = require('connect-redis')(session);
ESM 等效
import connectRedis from 'connect-redis';
const RedisStore = connectRedis(session);
您可以直接在模塊說明符中傳遞參數:
import * as Lib from "./lib?foo=bar";
參見: https://flaming.codes/en/posts/es6-import-with-parameters
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.