ES6 모듈의 깊이 - Lee-hyuna/33-js-concepts-kr GitHub Wiki
ES6에 오신 것을 환영합니다 - 유니코드에 관한 또 다른 기사는 아닙니다. - Depth 시리즈.
이전에 한번도 본적이 없다면 ES6 Tooling(세공, 압형)의 간략한 역사를 시작하시오.
그런 다음 구조화, 템플릿 리터럴, 화살표 함수, 스프레드 연산자 및 나머지 매개 변수, 객체 리터럴에 대한 개선,
프로토 타입 위에 새로운 클래스 , let, const 및 "Temporal Dead Zone", iterators, generators, Map, WeakMaps,
Sets 및 WeakSets, 프록시, 프록시 트랩, 프록시 트랩 추가, 리플렉션, 숫자, 수학, 배열, 객체 및 문자열과 같은
다양한 유형의 데이터를 처리 할 수 있습니다. 오늘 아침은 ES6의 모듈 시스템에 관한 것입니다.
이 시리즈의 이전 기사에서 했던 것처럼, 저는 Babel을 설정하고 예제를 따라 REPL 또는 바벨 노드 CLI와 파일을 따라야한다고 지적하고 싶습니다.
그러면 시리즈에서 논의 된 개념을 내재화하는 것이 훨씬 쉬워 질 것입니다. "내 컴퓨터에 설치하십시오" 종류가 아닌 경우 CodePen에서 호핑하고 JavaScript 용 기어 아이콘을 클릭하는 것이 더 좋을 수 있습니다. Babel 전처리기를 사용하면 ES6을 쉽게 찾을 수 있습니다.
또 다른 대안은 Babel의 온라인 REPL을 사용하는 것입니다. 빠른 비교를 위해 ES6 코드의 오른쪽에 컴파일 된 ES5 코드가 표시됩니다.
기에 들어가기 전에 깊이있는 ES6 시리즈를 즐기고 있다면 부끄러워하지 말고 지원을 요청하십시오. 기부금은 스케줄,
서버 청구서, 피드 보관 및 Pony Foo를 자바 스크립트 제품의 진실 된 소스로 유지하는 데 도움이 될 것입니다.
이를 읽어 주셔서 감사 드리며 ES6 모듈 시스템을 자세히 살펴보십시오.
ES6 모듈 시스템
ES6 이전에는 자바 스크립트로 모듈을 얻는 방법이 없었습니다. RequireJS, Angular의 의존성 주입 메커니즘 및 CommonJS와 같은 시스템은 Browserify 및 Webpack과 같은 유용한 도구와 함께 오랫동안 모듈 식 요구 사항을 해결해 왔습니다.
그럼에도 불구하고, 올해는 2015 년이며 표준 모듈 시스템은 오랫동안 지연되었습니다. 곧 보게 되겠지만,
ES6 모듈이 CommonJS의 영향을 크게 받았다는 것을 곧 알게 될 것입니다. 우리는이 기사 전체에서 살펴볼 것처럼
ES6 모듈이 CommonJS와 어떻게 호환되는지 확인하고 수출 및 수입 명세서를 살펴볼 것입니다.
오늘 우리는 ES6 모듈 시스템의 몇 가지 영역을 다룰 예정입니다.
- 엄격 모드 (Strict Mode)
- export
- 기본 바인딩 내보내기
- 명명 된 Exports
- 바인딩이 아닌 값
- 목록 내보내기
- 모범 사례 및 export
- import
- 기본 Exports 가져오기
- 명명된 Exports 가져오기
- 모든 것 import
Strict Mode
ES6 모듈 시스템에서는 엄격 모드가 기본적으로 설정됩니다.
엄격한 모드가 무엇인지 모르는 경우 언어의 많은 부분을 허용하지 않는 엄격한 언어 버전 일뿐입니다.
컴파일러는 사용자 코드에서 비 감각적 인 동작을 허용하지 않음으로써 성능을 향상시킬 수 있습니다.
다음은 MDN의 엄격 모드 조항에 문서화 된 변경 사항에서 추출한 요약입니다.
- 변수는 선언되지 않은 상태로 둘 수 없습니다.
- 함수 매개 변수는 고유 한 이름을 가져야합니다 (또는 구문 오류로 간주됩니다)
- ~는 금지되어 있다.
- 읽기 전용 속성에 대한 할당시 오류가 발생합니다.
- 00840과 같은 8 진수는 구문 오류입니다.
- 삭제 불가능한 속성을 삭제하려고하면 오류가 발생합니다.
- delete prop은 구문 오류입니다. delete global [prop]
- eval은 주변 변수에 새로운 변수를 추가하지 않습니다
- eval과 인수는 바인딩되거나 할당 될 수 없습니다.
- 인수는 메소드 매개 변수의 변경 사항을 마술처럼 추적하지 않습니다.
- arguments.callee는 더 이상 지원되지 않는 TypeError를 던집니다.
- arguments.caller가 더 이상 지원되지 않는 TypeError를 던집니다.
- 메소드 호출에서 전달 된 컨텍스트는 객체가되기 위해 "박스형"(강제)되지 않습니다.
- 더 이상 fn.caller 및 fn.arguments를 사용하여 JavaScript 스택에 액세스 할 수 없습니다.
- 예약어 (예 : protected, static, interface 등)는 바인딩 할 수 없습니다.
경우에 즉시 명백하지 않다 - 당신은 모든 장소에서 '엄격한'사용해야합니다. ES6에서는 사실상 사실이되고 있지만
ES6에서는 '엄격한 사용'을 사용하는 것이 좋습니다. 나는 오랫동안 그것을 해왔고 결코 되돌아 보지 않았다!
이제 ES6 모듈의 첫 번째 키워드인 export를 시작하겠습니다!
export
CommonJS에서는 값을 module.exports에 노출하여 값을 내 보냅니다. 아래의 스 니펫에서 볼 수 있듯이 값 유형에서 객체,
배열 또는 함수로 모든 것을 노출 할 수 있습니다.
module.exports = 1
module.exports = NaN
module.exports = 'foo'
module.exports = { foo: 'bar' }
module.exports = ['foo', 'bar']
module.exports = function foo () {}
ES6 모듈은 CommonJS 모듈과 마찬가지로 API를 내보내는 파일입니다. ESX 모듈의 선언은 CommonJS와 마찬가지로 해당 모듈에 적용됩니다. 즉, 모듈 내부에서 선언 된 변수는 모듈의 API의 일부로 명시 적으로 내보내지지 않으면 (그리고 모듈에 액세스하려는 모듈에서 가져온 경우가 아니면) 다른 모듈에서 사용할 수 없습니다.
Exporting a Default Binding
module.exports 를 export default로 변경하여 보았던 CommonJS 코드를 모방 할 수 있습니다.
export default 1
export default NaN
export default 'foo'
export default { foo: 'bar' }
export default ['foo', 'bar']
export default function foo () {}
CommonJS와는 반대로 ES6 모듈의 최상위 레벨에 내보내기 명령문을 배치 할 수 있습니다. 모듈을로드 할 때 메소드가 즉시 호출되는 경우에도 마찬가지입니다. 아마도이 제한은 컴파일러가 ES6 모듈을 쉽게 해석 할 수 있도록하기 위해 존재하지만, 메소드 호출을 기반으로 API를 동적으로 정의하고 공개해야하는 많은 이유가 없기 때문에 한계가 있습니다.
function foo () {
export default 'bar' // SyntaxError
}
foo()
단순한 내보내기 기본값이 아니며 명명 된 내보내기를 사용할 수도 있습니다.
Named Exports
CommonJS에서는 먼저 module.exports에 객체를 할당 할 필요조차 없습니다. 당신은 단지 그것에 속성을 집어 넣을 수 있습니다.
module.exports 객체의 모든 속성이 끝나면 여전히 하나의 바인딩이 내보내집니다.
module.exports.foo = 'bar'
module.exports.baz = 'ponyfoo'
named exports 구문을 사용하여 ES6 모듈에서 위의 내용을 복제 할 수 있습니다.
CommonJS와 같이 module.exports에 할당하는 대신 ES6에서 내보내려는 바인딩을 선언 할 수 있습니다.
아래의 코드는 변수 선언을 독립 실행 형 문으로 추출한 다음 구문 오류 일 수 있으므로 foo 만 내보내는 방식으로 리팩토링 할 수 없습니다.
다시 말하지만 ES6 모듈이 선언적 모듈 시스템 API가 작동하는 방식을 엄격하게함으로써 정적 분석을 선호하는 방식을 다시 살펴 봅니다.
export var foo = 'bar'
export var baz = 'ponyfoo'
우리가 바인딩을 내보내는 것을 명심하는 것이 중요합니다.
Bindings, Not Values
중요한 점은 ES6 모듈이 값 또는 참조가 아닌 바인딩을 내 보냅니다. 즉, 내보내는 foo 변수는 모듈의 foo 변수에 바인드되며
그 값은 foo에 대한 변경 사항의 적용을받습니다. 모듈을 처음로드 한 후에 공용 인터페이스를 변경하지 말 것을 권합니다.
아래에있는 것과 같은 ./a 모듈이 있다면 foo 내보내기는 500ms 동안 'bar'에 바인드되고 'baz'로 변경됩니다.
export var foo = 'bar'
setTimeout(() => foo = 'baz', 500)
"기본"바인딩 및 개별 바인딩 외에 바인딩 목록을 내보낼 수도 있습니다.
Exporting Lists
아래의 스니펫에서 볼 수 있듯이 ES6 모듈을 사용하면 명명 된 최상위 수준 멤버의 목록을 내보낼 수 있습니다.
var foo = 'ponyfoo'
var bar = 'baz'
export { foo, bar }
다른 이름으로 무언가를 내보내려면 다음과 같이 export {foo as bar} 구문을 사용할 수 있습니다.
export { foo as ponyfoo }
명명 된 멤버 목록 내보내기 선언 Flavor를 사용할 때 기본값으로 지정할 수도 있습니다.
아래의 코드는 기본 foo 및 내보내기 bar를 나중에 내보내는 것과 동일하지만 단일 명령문에서 사용합니다.
export { foo as default, bar }
export 기본값 만 사용하면 모듈 파일의 맨 아래에만 많은 이점이 있습니다.
Best Practices and export
named exports를 정의하고, 별칭과 겹침없는 목록을 내보내고, "기본"내보내기를 노출하는 기능은 대부분 혼란을 가져올 것이며,
대부분의 경우 수출 기본값을 사용하는 것이 좋습니다. 모듈 파일의 끝. API 객체 api를 호출하거나 모듈 자체 뒤에 이름을 붙일 수 있습니다.
var api = {
foo: 'bar',
baz: 'ponyfoo'
}
export default api
-
모듈의 내 보낸 인터페이스가 즉시 명확 해집니다. 모듈 주위를 크롤링하고 조각을 모아서 API를 파악하는 대신 끝에 스크롤하십시오.
API를 내 보낸 위치를 명확하게 정의하면 모듈이 내보내는 메소드와 속성에 대해 쉽게 추론 할 수 있습니다. -
특정 모듈에서 내보내기 기본값이나 명명 된 내보내기 또는 명명 된 내보내기 목록 (또는 별칭을 사용하여 명명 된 내보내기 목록)을
사용해야하는지 혼동하지 않습니다. 이제 가이드 라인이 있습니다. 모든 곳에서 기본값 내보내기를 사용하고 완료하십시오. -
일관성. CommonJS 세계에서는 모듈에서 하나의 메소드를 내보내는 것이 일반적입니다. 그게 전부입니다.
이름이 지정된 내보내기를 사용하면 내보내기 목록의 기본 글꼴로 기본 장식을 사용하지 않는 한 메서드를 사용하여
개체를 효과적으로 표시 할 수 없으므로 불가능합니다. 내보내기 기본 접근 방식은 한 가지만 내보낼 수 있기 때문에 더욱 다양합니다. -
이것은 실제로 이전에 만들어진 포인트의 축소입니다. 모듈의 맨 아래에있는 내보내기 기본 명령문은 내 보낸 API가 무엇인지,
메소드가 무엇인지, 모듈 소비자가 API를 가져 오는 것이 일반적인지 쉽게 알 수 있습니다.
항상 내보내기 기본값을 사용하고 항상 모듈 끝에서 항상 수행하는 규칙과 함께 사용할 경우 ES6 모듈 시스템을 사용하면 문제가 없음을 알 수 있습니다.
이제 export API와 경고에 대해 살펴 보았습니다. 이제 import 문으로 건너 뛰십시오.
import
이 문장은 export의 대응 부분이며, 무엇보다도 먼저 다른 모듈에서 모듈을 로드하는 데 사용될 수 있습니다.
모듈로드 방식은 구현에 따라 다르며 현재로서는 브라우저가 모듈로드를 구현하지 않습니다.
스마트 사용자가 브라우저에서 모듈 로딩을 처리하는 방법을 파악하는 동안이 방법으로 스펙 호환 ES6 코드를 작성할 수 있습니다.
Babel과 같은 변환기는 CommonJS와 같은 모듈 시스템을 사용하여 모듈을 연결할 수 있습니다.
즉, Babel의 import 문은 CommonJS의 require 문과 동일한 의미를 사용합니다.
잠깐 동안 lodash를 예로 들어 봅시다. 다음 명령문은 모듈에서 Lodash 모듈을로드하기 만합니다.
하지만 변수를 만들지는 않습니다. 하지만 lodash 모듈의 최상위 레벨에있는 모든 코드를 실행합니다.
import 'lodash'
바인딩 가져 오기에 들어가기 전에 import 문 (내보내기와 비슷 함)이 모듈 정의의 최상위 수준에서만 허용된다는 사실을 메모 해 두십시오.
이것은 transpilers가 모듈 로딩 기능을 구현할뿐만 아니라 다른 정적 분석 도구가 코드베이스를 구문 분석 할 수있게 도와줍니다.
Importing Default Exports
CommonJS에서는 require 문을 사용하여 가져올 수 있습니다.
var _ = require('lodash')
ES6 모듈에서 기본 exported 바인딩을 가져 오려면 이름을 선택하기 만하면됩니다.
이 구문은 바인딩을 가져 오기 때문에 변수를 선언하는 것과 조금 다르며 정적 분석 도구에서도 쉽게 사용할 수 있습니다.
import _ from 'lodash'
named exports를 가져 와서 별칭을 지정할 수도 있습니다.
Importing Named Exports
여기의 구문은 방금 기본 exports 사용한 구문과 매우 유사합니다. 원하는 중괄호를 추가하고 이름이 지정된 내보내기를 선택하면됩니다.
이 구문은 구조화 할당 구문과 비슷하지만 약간 다릅니다.
import {map, reduce} from 'lodash'
소멸과 다른 또 다른 방법은 별칭을 사용하여 가져온 바인딩의 이름을 바꿀 수 있다는 것입니다. 앨리어싱 된 앨리어스와 앨리어스가 아닌 앨리어스 이름이 지정된 내보내기를 적절하게 혼합하여 사용할 수 있습니다.
import {cloneDeep as clone, map} from 'lodash'
named export와 기본 exports를 혼합하고 일치시킬 수도 있습니다.
대괄호 안에 넣으려면 별명을 지정할 수있는 기본 이름을 사용해야합니다.
또는 기본 가져 오기를 이름이 지정된 가져 오기 목록과 함께 사용할 수도 있습니다.
import {default, map} from 'lodash'
import {default as _, map} from 'lodash'
import _, {map} from 'lodash'
import All The Things
또한 모듈에 대한 네임 스페이스 객체를 가져올 수도 있습니다. named export 또는 기본값을 가져 오는 대신 모든 항목을 가져옵니다.
import * 구문 뒤에는 모든 바인딩이 위치 할 별칭이 와야합니다. 기본 내보내기가 있으면 alias.default에 배치됩니다.
import * as _ from 'lodash'
결론
CommonJS 모듈을 활용하면서 현재 Babel 컴파일러를 통해 ES6 모듈을 사용할 수 있습니다.
이 점에서 큰 점은 CommonJS와 ES6 모듈을 실제로 상호 운용 할 수 있다는 것입니다.
즉, CommonJS로 작성된 모듈을 가져 오더라도 실제로 작동합니다.
S6 모듈 시스템은 멋지게 보이며 JavaScript에서 누락 된 가장 중요한 요소 중 하나입니다.
조만간 API 및 브라우저 구현을 완료하는 모듈을 완성 할 수 있기를 바랍니다.
모듈에서 바인딩을 내보내거나 가져올 수있는 여러 가지 방법은 약간의 이득을 위해 복잡성을 추가하는만큼 다재 다능 한 기능을 도입하지 않지만
시간이 갈수록 모든 추가 API 표면이 대형만큼 편리한지 여부를 알 수 있습니다.