답변:
하나를 다른 것보다 사용하면 성능상의 이점이 있습니까?
ES6 모듈을 기본적으로 지원하는 JavaScript 엔진은 아직 없습니다. 당신은 당신이 당신이 바벨을 사용하고 있다고 자신을 말했다. Babel 은 기본적 으로 CommonJS ( / ) 로 변환 import
하고 export
선언 합니다. 따라서 ES6 모듈 구문을 사용하더라도 Node에서 코드를 실행하면 기본적으로 CommonJS를 사용하게됩니다.require
module.exports
CommonJS와 ES6 모듈에는 기술적 인 차이가 있습니다. 예를 들어 CommonJS를 사용하면 모듈을 동적으로로드 할 수 있습니다. ES6에서는이를 허용하지 않지만 개발을위한 API가 있습니다.
ES6 모듈은 표준의 일부이므로 사용합니다.
ES6 import
함께 사용하려고했지만 require
다르게 작동했습니다. CommonJS는 클래스가 하나만있는 동안 클래스 자체를 내 보냅니다. ES6 내보내기는 여러 클래스가 있으므로 .ClassName
내 보낸 클래스를 가져 오는 데 사용해야 합니다. 실제로 구현에 영향을 미치는 다른 차이점이 있습니까?
module.exports = ...;
와 같습니다 export default ...
. exports.foo = ...
동등하다 export var foo = ...
;
import
Webpack 2 / Rollup (및 ES6 트리 흔들림을 허용하는 다른 번 들러) 과 함께 사용되는 Node의 CommonJS로 궁극적으로 변환하더라도 동등한 코드 노드 크런치보다 훨씬 작은 파일로 감을 수 있습니다 ES6은 require
정확한 가져 오기 / 내보내기 분석을 허용 하므로 정확하게 사용 합니다 . 이것이 노드 (아직)와 다르지 않지만 코드가 궁극적으로 단일 브라우저 번들로 작동하는 경우 확실히 가능합니다.
고려해야 할 몇 가지 사용법 / 기능이 있습니다.
요구 사항 :
require
, 여러 개가 있으면 하나씩로드되고 처리됩니다.ES6 수입품 :
또한 Require 모듈 시스템은 표준 기반이 아닙니다. ES6 모듈이 존재하기 때문에 이제 표준이 될 가능성은 거의 없습니다. 앞으로 성능 측면에서 유리한 다양한 구현에서 ES6 모듈에 대한 기본 지원이 제공 될 것입니다.
require
어쨌든 ES6 모듈을 컴파일 하고 있으므로 노드의 모듈 시스템과 로더를 사용하고 있습니다.
주요 장점은 구문입니다.
ES6 모듈의 성능 이점은 거의 없습니다. 브라우저에서 ES6 기능을 완벽하게 지원하는 경우에도 모듈을 번들로 제공하기 위해 추가 라이브러리가 필요합니다.
node --experimemntal-modules index.mjs
사용할 수 있습니다 import
. 당신은 (그리고해야한다) 또한 수 이전 버전과의 호환성, 기본 ESModule로 NPM 패키지를 게시 이전을위한 require
방법. 많은 브라우저가 기본적으로 동적 가져 오기를 지원 합니다.
하나를 다른 것보다 사용하면 성능상의 이점이 있습니까?
현재 브라우저 엔진 import/export
이 ES6 표준을 구현하지 않기 때문에 현재 답변은 아니요 입니다.
일부 비교 차트 http://kangax.github.io/compat-table/es6/ 는 이것을 고려하지 않으므로 Chrome의 거의 모든 녹색을 볼 때 조심하십시오. import
ES6의 키워드는 고려되지 않았습니다.
즉, V8을 포함한 현재 브라우저 엔진은 JavaScript 지시문을 통해 기본 JavaScript 파일 에서 새 JavaScript 파일 을 가져올 수 없습니다 .
( V8이 ES6 사양에 따라 구현할 때까지 몇 년이지나거나 몇 년이 걸릴 수 있습니다.)
이 문서 는 우리가 필요 로하는 것이며이 문서 는 우리가 준수해야 할 것입니다.
그리고 ES6 표준에 따르면, .h
파일 헤더가있는 프로그래밍 언어 C 에서처럼 모듈을 읽기 전에 모듈 종속성이 있어야한다고 합니다.
이것은 훌륭하고 잘 테스트 된 구조이며 ES6 표준을 만든 전문가가이를 염두에두고 있다고 확신합니다.
이것은 특별한 경우에 Webpack 또는 다른 패키지 번 들러가 번들을 최적화하고 필요하지 않은 번들의 종속성을 줄 이도록하는 것입니다. 그러나 우리가 완벽한 의존성을 가진 경우에는 결코 일어나지 않을 것입니다.
import/export
기본 지원이 시작될 때까지 약간의 시간이 필요 하며 require
키워드는 오랫동안 아무 데나 가지 않습니다.
무엇입니까 require
?
이것은 node.js
모듈을로드하는 방법입니다. ( https://github.com/nodejs/node )
노드는 시스템 레벨 방법을 사용하여 파일을 읽습니다. 당신은 기본적으로 그것을 사용할 때 그것에 의존합니다 require
. JavaScript 파일 / 모듈을로드하기 위해 (종료 시스템, Linux, Mac, Windows에 따라) require
와 같은 일부 시스템 호출로 uv_fs_open
끝납니다.
이것이 사실인지 확인하려면 Babel.js를 사용하십시오. 그러면 import
키워드가로 변환됩니다 require
.
import
Webpack 2 / Rollup 빌드 프로세스에서 사용하면 사용 하지 않는 모듈 / 코드를 '트리 떨림'하여 결과 파일 크기를 잠재적으로 줄일 수 있습니다. 작은 파일 크기 = 다운로드 속도 = 클라이언트에서 초기화 / 실행 속도가 빠릅니다.
import
키워드를 기본적으로 허용하지 않았다는 것 입니다. 또는 이는 JavaScript 파일에서 다른 JavaScript 파일을 가져올 수 없음을 의미합니다. 이것이이 두 가지의 성능 이점을 비교할 수없는 이유입니다. 물론 Webpack1 / 2 또는 Browserify와 같은 도구는 압축을 처리 할 수 있습니다. 그것들은 목에서 목까지입니다 : gist.github.com/substack/68f8d502be42d5cd4942
import
하고 export
특정 코드 경로를 가져 정적 선언하고, 반면에 require
동적 일 수 있으므로 사용하지 않는 코드에 번들. 성능 이점은 indirect-- 웹팩 2 및 / 또는 롤업 수 잠재적 빠른 다운로드한다 작은 다발 크기 초래하므로 (브라우저의) 최종 사용자 빠르다는 나타난다. 모든 코드가 ES6 모듈로 작성되어 가져 오기를 정적으로 분석 할 수있는 경우에만 작동합니다.
import/export
가로 변환되어 require
부여되었습니다. 그러나이 단계 이전에 발생하는 일은 "성능"향상으로 간주 될 수 있습니다. 예 : lodash
ES6 및 you로 작성된 경우 import { omit } from lodash
최종 번들에는 다른 유틸리티가 아닌 '생략'만 포함되지만 단순 require('lodash')
은 모든 항목을 가져옵니다. 이렇게하면 번들 크기가 늘어나고 다운로드 시간이 길어 지므로 성능이 저하됩니다. 이것은 물론 브라우저 컨텍스트에서만 유효합니다.
ES6 모듈을 사용하면 '트리 쉐이킹'에 유용 할 수 있습니다. 즉, Webpack 2, 롤업 (또는 다른 번 들러)을 사용하여 가져 오거나 가져 오지 않은 코드 경로를 식별하므로 결과 번들로 만들지 않습니다. 이렇게하면 필요하지 않은 코드를 제거하여 파일 크기를 크게 줄일 수 있지만 Webpack 등은 필요한지 여부를 알 수 없으므로 CommonJS와 함께 기본적으로 번들로 제공됩니다.
이것은 코드 경로의 정적 분석을 사용하여 수행됩니다.
예를 들어,
import { somePart } 'of/a/package';
... 번 들러에 package.anotherPart
필요하지 않은 힌트를 제공 합니다 (가져 오지 않으면 올바르게 사용할 수 없습니까?). 번들링을 방해하지 않습니다.
Webpack 2에서이를 사용 가능하게하려면 트랜스 파일러가 CommonJS 모듈을 분리하지 않아야합니다. es2015
babel과 함께 플러그인을 사용하는 경우 다음 .babelrc
과 같이 비활성화 할 수 있습니다 .
{
"presets": [
["es2015", { modules: false }],
]
}
롤업 및 기타 기능이 다르게 작동 할 수 있습니다. 관심이있는 경우 문서를보십시오.
비동기 또는 게으른 로딩과 관련하여 import ()
훨씬 강력합니다. 구성 요소가 비동기 방식으로 필요할 때 import
확인한 다음 const
변수 using 과 같이 비동기 방식으로 사용 await
합니다.
const module = await import('./module.js');
아니면 사용하려면 require()
다음,
const converter = require('./converter');
것입니다 import()
자연의 비동기 사실이다. 에 neehar venugopal에서 언급 한 바와 같이 ReactConf , 당신은 클라이언트 측 아키텍처의 구성 요소를 반응 동적 부하에 사용할 수 있습니다.
또한 라우팅과 관련하여 더 좋습니다. 그것은 사용자가 특정 웹 사이트에 특정 구성 요소에 연결할 때 필요한 부분을 다운로드하기 위해 네트워크 로그를 만드는 특별한 것입니다. 예를 들어 대시 보드 앞의 로그인 페이지는 대시 보드의 모든 구성 요소를 다운로드하지 않습니다. 현재 필요한 것은 로그인 컴포넌트입니다.
동일은 간다 export
: ES6는 export
CommonJS 경우와 정확히 동일합니다 module.exports
.
참고 -node.js 프로젝트를 개발하는 경우을 사용하는 require()
것처럼 노드에서 예외 오류가 발생하므로 엄격하게 사용해야 invalid token 'import'
합니다 import
. 따라서 노드는 import 문을 지원하지 않습니다.
업데이트 -Dan Dascalescu가 제안한 대로 : v8.5.0 (2017 년 9 월 릴리스)부터 Babel없이 node --experimental-modules index.mjs
사용할 수 있습니다 import
. 당신은 (그리고해야한다) 또한 수 이전 버전과의 호환성, 기본 ESModule로 NPM 패키지를 게시 이전을위한 require
방법.
비동기 가져 오기를 사용할 위치에 대한 자세한 내용은 https://www.youtube.com/watch?v=bb6RCrDaxhw를 참조하십시오.
알아야 할 가장 중요한 것은 ES6 모듈은 공식 표준이지만 CommonJS (Node.js) 모듈은 그렇지 않다는 것입니다.
2019 년에는 ES6 모듈이 브라우저의 84 % 에서 지원됩니다. Node.js는이를 --experimental-modules 플래그 뒤에 배치하지만 esm 이라는 편리한 노드 패키지도있어 통합이 원활합니다.
이러한 모듈 시스템간에 발생할 수있는 또 다른 문제는 코드 위치입니다. Node.js는 소스가 node_modules
디렉토리에 유지되는 반면 대부분의 ES6 모듈은 플랫 디렉토리 구조로 배포 된다고 가정합니다 . 이것들은 조정하기 쉽지 않지만 package.json
설치 전후 스크립트로 파일을 해킹하여 수행 할 수 있습니다 . 다음은 예입니다 동형 모듈 및 기사 어떻게 작동하는지 설명은.
가져 오기를 사용하여 필요한 메소드를 가져올 수 있기 때문에 개인적으로 가져 오기를 사용합니다.
import {foo, bar} from "dep";
파일 이름 : dep.js
export foo function(){};
export const bar = 22
크레딧은 Paul Shan에게갑니다. 더 많은 정보 .
const {a,b} = require('module.js');
수출 a
도 가능합니다b
module.exports = { a: ()={}, b: 22 }
- @BananaAcid respones의 두 번째 부분
현재 ES6 가져 오기에서 내보내기는 항상 CommonJS로 컴파일 되므로 하나를 사용하면 이점 이 없습니다 . ES6의 사용이 권장되지만 브라우저에서 기본 지원을 릴리스 할 때 유리해야합니다. 그 이유는 CommonJS를 사용하면 하나의 파일에서 부분을 가져올 수 있지만 모든 파일이 필요합니다.
ES6 → import, export default, export
커먼 JS → require, module.exports, exports.foo
아래는 그것들의 일반적인 사용법입니다.
ES6 내보내기 기본값
// hello.js
function hello() {
return 'hello'
}
export default hello
// app.js
import hello from './hello'
hello() // returns hello
ES6 다중 내보내기 및 다중 가져 오기
// hello.js
function hello1() {
return 'hello1'
}
function hello2() {
return 'hello2'
}
export { hello1, hello2 }
// app.js
import { hello1, hello2 } from './hello'
hello1() // returns hello1
hello2() // returns hello2
CommonJS module.exports
// hello.js
function hello() {
return 'hello'
}
module.exports = hello
// app.js
const hello = require('./hello')
hello() // returns hello
CommonJS 모듈. 여러 내보내기
// hello.js
function hello1() {
return 'hello1'
}
function hello2() {
return 'hello2'
}
module.exports = {
hello1,
hello2
}
// app.js
const hello = require('./hello')
hello.hello1() // returns hello1
hello.hello2() // returns hello2
왜 (아마도 최적화-게으른로드?) 그런 식으로 작동하는지 확실하지 않지만 import
가져온 모듈을 사용하지 않으면 코드를 구문 분석하지 못할 수 있습니다.
어떤 경우에는 예상대로 작동하지 않을 수 있습니다.
샘플 종속성으로 Foo 클래스를 싫어하십시오.
foo.ts
export default class Foo {}
console.log('Foo loaded');
예를 들면 다음과 같습니다.
index.ts
import Foo from './foo'
// prints nothing
index.ts
const Foo = require('./foo').default;
// prints "Foo loaded"
index.ts
(async () => {
const FooPack = await import('./foo');
// prints "Foo loaded"
})();
반면에 :
index.ts
import Foo from './foo'
typeof Foo; // any use case
// prints "Foo loaded"
node --experimental-modules index.mjs
import
Babel없이 사용할 수 있으며 Node 8.5.0 이상에서 작동합니다. 당신은 (그리고해야한다)도 할 수 네이티브 ESModule로 NPM 패키지를 게시 이전에 대한 이전 버전과의 호환성,require
방법.