เป็นไปได้ไหมที่จะส่งตัวเลือกต่าง ๆ ไปยังการนำเข้า ES6
คุณแปลสิ่งนี้ได้อย่างไร:
var x = require('module')(someoptions);
ถึง ES6?
เป็นไปได้ไหมที่จะส่งตัวเลือกต่าง ๆ ไปยังการนำเข้า 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);
อีกทางหนึ่งถ้าคุณใช้ตัวโหลดโมดูลที่รองรับสัญญาแบบ monadicคุณอาจทำสิ่งที่ต้องการได้
System.import('module').ap(someoptions).then(function(x) {
…
});
กับimport
ผู้ประกอบการใหม่มันอาจกลายเป็น
const promise = import('module').then(m => m(someoptions));
หรือ
const x = (await import('module'))(someoptions)
อย่างไรก็ตามคุณอาจไม่ต้องการนำเข้าแบบไดนามิก แต่เป็นแบบคงที่
import x from 'module' use someoptions;
ไวยากรณ์ของมัน
import {x, y} from 'module'
) แล้วไวยากรณ์ควรเป็นอย่างไรถ้าฉันต้องการผ่านอาร์กิวเมนต์หลาย ๆ หรือกระจายอาเรย์ของข้อโต้แย้ง? เป็นกรณีการใช้งานที่แคบและโดยทั่วไปคุณกำลังพยายามเพิ่มไวยากรณ์ที่แตกต่างกันสำหรับการเรียกใช้ฟังก์ชัน แต่เรามีการเรียกใช้ฟังก์ชันที่ทำให้เราสามารถจัดการกับกรณีอื่นทั้งหมดได้แล้ว
var session = require('express-session'); var RedisStore = require('connect-redis')(session);
ฉันแค่สงสัยว่ามีวิธีแก้ปัญหาหนึ่งบรรทัดหรือไม่ ฉันสามารถอยู่รอดได้อย่างสมบูรณ์ด้วยการแบ่งการมอบหมาย RedisStore เป็น 2 บรรทัด :)
import {default(someoptions) as x} from 'module'
ใน ES7 หากมีความต้องการจริงๆ
session
/ ตัวอย่างเช่นผมได้รับการจินตนาการไวยากรณ์เช่นนี้connect-redis
import session from 'express-session'); import RedisStore(session) from 'connect-redis'
นี่คือทางออกของฉันโดยใช้ ES6
สอดคล้องมากกับการตอบสนองของ @ Bergi นี่คือ "เทมเพลต" ที่ฉันใช้เมื่อสร้างการนำเข้าที่ต้องผ่านพารามิเตอร์เพื่อclass
การประกาศ สิ่งนี้ถูกใช้ในเฟรมเวิร์ก isomorphic ที่ฉันกำลังเขียนดังนั้นจะทำงานกับ transpiler ในเบราว์เซอร์และใน 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
ในคอนโซล
แก้ไข
สำหรับตัวอย่างโลกแห่งความจริงฉันใช้สิ่งนี้เพื่อส่งผ่านในเนมสเปซสำหรับการเข้าถึงคลาสและอินสแตนซ์อื่น ๆ ภายในกรอบงาน เพราะเราเพียงแค่สร้างฟังก์ชั่นและส่งผ่านวัตถุเป็นอาร์กิวเมนต์เราสามารถใช้กับการประกาศคลาสของเรา likeo:
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();
}
// ...
ฉันหวังว่านี่จะช่วยได้!
MyView
ขยายรายการบางรายการที่มีอยู่ในเนมสเปซของกรอบงาน ในขณะที่เป็นไปได้อย่างแน่นอนที่จะส่งผ่านมันเป็นพารามิเตอร์ให้กับคลาส แต่ก็ขึ้นอยู่กับเวลาและสถานที่ที่อินสแตนซ์ถูกสร้างขึ้น พกพาได้รับผลกระทบแล้ว ในทางปฏิบัติชั้นเรียนเหล่านี้อาจถูกส่งมอบให้กับกรอบงานอื่น ๆ ที่อาจยกตัวอย่างพวกเขาที่แตกต่างกัน (เช่นองค์ประกอบ React ที่กำหนดเอง) เมื่อคลาสพบว่าตัวเองอยู่นอกขอบเขตของเฟรมเวิร์กมันยังคงสามารถเข้าถึงเฟรมเวิร์กได้เมื่ออินสแตนซ์เนื่องจากวิธีการนี้
การสร้างคำตอบที่ @ Bergi เพื่อใช้โมดูล debugโดยใช้ es6 จะเป็นดังต่อไปนี้
// original
var debug = require('debug')('http');
// ES6
import * as Debug from 'debug';
const debug = Debug('http');
// Use in your code as normal
debug('Hello World!');
ฉันเชื่อว่าคุณสามารถใช้โมดูลตัก ES6 http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
m(youroptionshere)
สิ้นสุดอยู่ที่ไหน ฉันคิดว่าคุณสามารถเขียนSystem.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})
... แต่มันไม่ชัดเจน
คุณต้องเพิ่ม 2 บรรทัดนี้
import xModule from 'module';
const x = xModule('someOptions');
xModule
กำลังทำให้เข้าใจผิดที่นี่ import func from 'module'; func('someOptions');
สิ่งที่คุณจะมีคือ
ฉันได้อ่านบทความนี้แล้วดูคล้ายกันบ้างและต้องการเสนอวิธีการแก้ปัญหาอย่างน้อยในบางกรณี (แต่ดูหมายเหตุด้านล่าง)
ใช้กรณี
ฉันมีโมดูลที่ใช้ตรรกะการสร้างอินสแตนซ์บางอย่างทันทีที่โหลด ฉันไม่ชอบเรียกตรรกะเริ่มต้นนี้นอกโมดูล (ซึ่งเหมือนกับการโทร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
หมายเหตุ: ฉันขอแนะนำตัวเองว่าอย่าฝึกวิธีนี้มากนัก แต่ให้เป็นทางเลือกสุดท้าย ทำไม? โมดูลที่นำเข้ามากกว่าหนึ่งครั้งเป็นข้อยกเว้นมากกว่ากฎดังนั้นจึงเป็นพฤติกรรมที่ไม่คาดคิดและอาจทำให้ผู้บริโภคเกิดความสับสนหรือทำให้แตกเป็นกระบวน
นี่คือคำถามของฉันในการใช้โมดูล debug เป็นตัวอย่าง;
ในหน้า npm ของโมดูลนี้คุณมี:
var debug = ต้องการ ('debug') ('http')
ในบรรทัดด้านบนสตริงจะถูกส่งผ่านไปยังโมดูลที่นำเข้าเพื่อสร้าง นี่คือวิธีที่คุณจะทำเช่นเดียวกันใน ES6
นำเข้า {debug เป็น Debug} จาก 'debug' const debug = Debug ('http');
หวังว่านี่จะช่วยให้ใครบางคนที่นั่น
System.import(module)
ไม่แน่ใจว่าอนุญาตให้มีการขัดแย้งหรือไม่ใครที่รู้เกี่ยวกับ ES6 อาจทำอะไรบ้าง