ES6 모듈 가져 오기에 옵션 전달


144

옵션을 ES6 가져 오기로 전달할 수 있습니까?

이것을 어떻게 번역합니까?

var x = require('module')(someoptions);

ES6에?


당신이 할 수 있는지 확실하지 않거나, 모듈 로더 API가 있는지, 또는 적어도 언젠가는, 무언가를 사용 System.import(module)했는지, 인수를 허용하는지 확실하지 않은지, ES6에 대해 더 잘 아는 사람은 아마도?
adeneo

이를 위해 제안 된 솔루션이 있습니다. (플러그인을 통해) node.js 및 웹 팩에 이미 구현되어 있습니다 : 2ality.com/2017/01/import-operator.html
Matt Browne

답변:


104

단일 import명령문으로이를 수행 할 수 있는 방법이 없으며 호출을 허용하지 않습니다.

따라서 직접 호출하지는 않지만 기본적으로 기본 내보내기에서 commonjs와 동일한 작업을 수행 할 수 있습니다.

// module.js
export default function(options) {
    return {
        // actual module
    }
}

// main.js
import m from 'module';
var x = m(someoptions);

또는 monadic promise 를 지원하는 모듈 로더를 사용하면 다음과 같은 작업을 수행 할 수 있습니다.

System.import('module').ap(someoptions).then(function(x) {
    
});

새로운으로 import운영자 가 될 수도

const promise = import('module').then(m => m(someoptions));

또는

const x = (await import('module'))(someoptions)

그러나 동적 가져 오기를 원하지 않고 정적 가져 오기를 원할 것입니다.


7
감사합니다. import x from 'module' use someoptions;일종의 문법이 필요합니다
Fabrizio Giordano

1
@Fabrizio : 더 생각해 보면 실제로 도움이되지 않을 것입니다. 모듈이 함수를 내보내는 경우에만 작동하며 이름을 imports (예 :)로 지정한 경우에는 허용되지 않아야합니다 import {x, y} from 'module'. 여러 인수를 전달하려면 구문은 무엇입니까? 아니면 인수의 배열을 확산? 좁은 유스 케이스이며 기본적으로 함수 호출에 다른 구문을 추가하려고하지만 이미 다른 모든 경우를 처리 할 수있는 함수 호출이 있습니다.
Felix Kling

3
@FelixKling 나는 당신과 완전히 동의합니다. 나는 오래된 express webapp을 변환하고 var session = require('express-session'); var RedisStore = require('connect-redis')(session);있었고 한 줄 솔루션이 있는지 궁금합니다. 난 완전히 분할로 : 2 개 라인의 RedisStore 할당 살아남을 수
파브리 지오 지오다노

@ FabrizioGiordano : import {default(someoptions) as x} from 'module'정말로 이것이 필요하다면 ES7 과 같은 것을 상상할 수 있습니다.
Bergi

2
session/ connect-redis예제의 경우 다음 과 같은 구문을 상상했습니다 import session from 'express-session'); import RedisStore(session) from 'connect-redis'.
Jeff Handley

24

개념

ES6을 사용하는 솔루션은 다음과 같습니다.

@Bergi의 응답과 매우 흡사 한, 이것은 class선언을 위해 전달 된 매개 변수가 필요한 가져 오기를 만들 때 사용하는 "템플릿" 입니다. 이것은 내가 쓰고 있어요 동형 프레임 워크를 사용되므로 브라우저와 Node.js를 (내가 사용에 transpiler와 함께 작동합니다 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();
}
// ...

이게 도움이 되길 바란다!


가져온 모든 모듈이 클래스이므로 클래스를 인스턴스화 할 때 매개 변수를 전달하지 않는 이유는 무엇입니까?
jasonszhao

1
@jasonszhao 여기서 주목해야 할 가장 중요한 점은 클래스 MyView가 프레임 워크의 네임 스페이스에서 사용 가능한 특정 항목을 확장 한다는 것 입니다. 단순히 클래스에 매개 변수로 전달하는 것이 절대적으로 가능하지만 클래스가 언제 어디서 인스턴스화되는지에 따라 다릅니다. 그런 다음 이식성이 영향을받습니다. 실제로, 이러한 클래스는 다른 인스턴스를 생성 할 수있는 다른 프레임 워크 (예 : 사용자 지정 React 구성 요소)로 전달 될 수 있습니다. 클래스가 프레임 워크 범위를 벗어나는 경우에도이 방법론으로 인해 인스턴스화 될 때 프레임 워크에 대한 액세스를 유지할 수 있습니다.
스위블

@Swivel 비슷한 문제에 도움이 필요하십니까? stackoverflow.com/questions/55214957/…
TSR

12

es6 을 사용하여 디버그 모듈 을 사용하는 @ Bergi의 대답 을 바탕으로 다음과 같습니다.

// 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!');

4

es6 모듈 로더를 사용할 수 있다고 생각합니다. http://babeljs.io/docs/learn-es6/

System.import("lib/math").then(function(m) {
  m(youroptionshere);
});

3
그러나 결과는 어디에 m(youroptionshere)있습니까? 나는 당신이 쓸 수 있다고 생각 System.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})하지만 ...별로 명확하지 않습니다.
Stijn de Witt

2
와우 나는 E6에서 이것을 할 수있는 우아한 방법이 없다고 믿을 수 없습니다. 이것이 제가 주로 모듈을 작성하는 방식입니다.
Robert Moskal

3

이 두 줄만 추가하면됩니다.

import xModule from 'module';
const x = xModule('someOptions');

1
그것은 단순히 가져오고 호출하는 함수에 매개 변수를 전달하는 것입니다. 가져 오는 모듈에 옵션 전달하지 않습니다 . xModule여기 오해의 소지가 있습니다. 당신이 실제로 가지고있는 것은 import func from 'module'; func('someOptions');입니다.
Dan Dascalescu

1

나는이 스레드를 다소 유사하게 찾고 적어도 어떤 경우에는 일종의 해결책을 제안하고 싶습니다 (그러나 아래의 설명 참조).

사용 사례

로드하는 즉시 인스턴스화 논리를 실행하는 모듈이 있습니다. 나는 할 수 없습니다 (호출과 동일한 모듈 외부에서이 초기화 로직 전화처럼 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

비고 :이 방법을 많이 연습하지 말고 최후의 수단으로 남겨 두라고 조언합니다. 왜? 모듈을 두 번 이상 가져 오면 규칙보다 예외가 발생하기 때문에 다소 예상치 못한 동작이므로 소비자를 혼동 시키거나 자체 '단일'패러다임이있을 수 있습니다 (있는 경우).


0

다음은 디버그 모듈을 예로 사용하여이 질문에 대해 설명합니다.

이 모듈의 npm 페이지에는 다음이 있습니다.

var debug = require ( '디버그') ( 'http')

위 줄에서 문자열은 가져온 모듈로 전달되어 구성됩니다. ES6에서 동일한 작업을 수행하는 방법은 다음과 같습니다.


'debug'에서 import {디버그로 디버그} const debug = Debug ( 'http');


이것이 누군가를 도울 수 있기를 바랍니다.


이미 게시 된 답변과 중복되는 답변을 게시해야하는 이유는 무엇 입니까?
Dan Dascalescu

1
내 잘못이야. 언급 된 게시물을 본 적이 없습니다. 그냥 질문을보고 찔렀습니다. 통지 해 주셔서 감사합니다.
Akinwale Folorunsho Habib

천만에요. 원하는 경우 중복 답변을 삭제할 수도 있습니다.
Dan Dascalescu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.