협업을 하면서 다른 팀원들의 코드를 살펴보고 내 코드에 적용할 기회가 아주 많아졌다. 그 중에서 오늘 정리해보고 싶은 포인트는 default export와 named export의 차이점이다.
ES6에서부터는 한 파일에서 다른 파일로 모듈을 내보내고 받아올 수 있게 되었다. 리액트에서는 한 컴포넌트를 다른 컴포넌트에서 가져올 수 있다는 의미다. ES6는 모듈을 내보내는 두 가지 방식을 지원한다. Default export와 named export에 대해서 정리해보려고 한다.
Default로 선언된 모듈은 하나의 파일에서 단 하나의 변수 또는 클래스 등만 export할 수 있다.
// import
import MyComponent from "./MyDefaultExport";
// export
const MyComponent = () => {}
export default MyComponent;
모듈의 이름이 무엇이든 간에 default로 내보낸 모듈은 어떤 이름으로든지 import할 수 있다.
// import
import MyDefaultComponent from "./MyDefaultExport";
// import
import NewComponent from "./MyDefaultExport";
// export
const MyComponent = () => {}
export default MyComponent;
하나의 파일 당 한 개의 모듈만 default export할 수 있기 때문에 어떤 이름을 붙이든 상관이 없다. let, const를 바로 default export할 수는 없다.
// export 나쁜 예
export default const DataVisualization = () => {}
이렇게 못 한다는 소리.
한 파일 내에서 여러 변수/클래스 등을 export할 수 있다.
// imports
// ex. importing a single named export
import { MyComponent } from "./MyComponent";
// ex. importing multiple named exports
import { MyComponent, MyComponent2 } from "./MyComponent";
// exports from ./MyComponent.js file
export const MyComponent = () => {}
export const MyComponent2 = () => {}
Named export 방식으로 내보내기를 하면, 해당 모듈을 불러오고자 하는 파일에서는 중괄호로 감싸서 불러와야 한다. MyComponent.js 파일에서 2개 이상의 모듈을 내보내도 불러올 때는 한 개만 불러와도 된다.
// imports
// ex. giving a named import a different name by using "as":
import { ChartData as UsageChartData } from "./MyComponent";
// exports from ./MyComponent.js file
export const ChartData = () => {}
export const TableData = () => {}
Default export 방식으로 내보내기를 했을 때 마음대로 이름을 정해서 불러왔듯이, Named export 방식으로 내보내기를 했을 때도 이름을 다시 정해서 불러올 수 있다. ChartData 모듈을 불러올 때, import { ChartData as UsageChartData } from ~
이런 식으로 이름을 재정의할 수 있다.
// imports
// ex. giving a named import a different name by using "as":
import { ChartData as UsageChartData, TableData } from "./MyComponent";
// exports from ./MyComponent.js file
export const ChartData = () => {}
export const TableData = () => {}
이렇게 두가지 방법으로 한번에 불러올 수 있다.
// imports
import * as DataComponents from "./MyComponent";
// exports from ./MyComponent.js file
export const ChartData = () => {}
export const TableData = () => {}
위와 같이 *
를 쓰면 해당 파일에 있는 모든 모듈을 한꺼번에 불러올 수 있다.
// import from RealTimeUsageByTime.js
import TimeUsageCharts from './TimeUsageChart/TimeUsageCharts';
import TimeUsageSummary from './TimeUsageSummary/TimeUsageSummary';
import MinuteUsageTable from './TimeUsageTable/MinuteUsageTable';
// export from TimeUsageCharts.js
const TimeUsageCharts = () => {}
export default TimeUsageCharts;
// export from TimeUsageSummary.js
const TimeUsageSummary = () => {}
export default TimeUsageSummary;
// export from MinuteUsageTable.js
const MinuteUsageTable = () => {}
export default MinuteUsageTable;
각각 TimeUsageCharts.js
, TimeUsageSummary.js
, MinuteUsageTable.js
파일에서 default로 내보내기한 컴포넌트를, 부모 컴포넌트이자 전체 페이지인 RealTimeUsageByTime.js
에서 받아오는 예시다.
// exports from api.js
export const getUserProfileApi = () => {
return apiCall(`${WEB_SERVER_API_BASE}/member/user/profile`);
};
export const getPlaceApi = () => {
return apiCall(`${WEB_SERVER_API_BASE}/customer`);
};
export const smartViewApi = (placeCode, customerCode, currentDate) => {
return apiCall(
`${WEB_SERVER_API_BASE}/pp/realtime?placeCd=${placeCode}&custCd=${customerCode}&cronDt=${currentDate}`,
'get',
{
placeCode,
customerCode,
currentDate,
},
);
};
...
// import modules from api.js
import { getUserProfileApi, getPlaceApi } from '../../../../Helpers/api';
api.js에는 수많은 API들이 모듈화되어 작성되어 있는데 그 중에서 필요한 API만 가져다 쓰기 위해 중괄호 안에 필요한 api만을 넣어서 불러왔다.
// import
import { useWindowSize } from '../../../../Hooks/useWindowSize';
// export from useWindowSize.js
const useWindowSize = () => {};
export { useWindowSize };
useWindowSize.js 파일에 한 가지 모듈만이 있는데 export default로 하지 않고 중괄호에 넣어서 저렇게 내보내기한 후, 마찬가지로 중괄호에 모듈 이름을 넣어서 import하는 방법도 있다. useWindowSize.js 파일에서 또 다른 모듈이 추가되는 경우를 예상하는 경우다. 만약 해당 파일에서 모듈이 유일하다면 이 코드는 이렇게 쓸 수도 있다.
// import
import useWindowSize from '../../../../Hooks/useWindowSize';
// export from useWindowSize.js
const useWindowSize = () => {};
export default useWindowSize;
그렇다고 한다. (사수님께 여쭤보니 전자의 중괄호는 그냥 intelliJ에서 자동완성되었기 때문이며 default로 고쳐도 된다고 하셨다 ㅋㅋ)