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.