수정 사항
이 코드는 export default class에 대해 작동하지만, export { foo, bar }와 같은 형식에선 작동하지 않습니다.
이에 대한 수정 사항이은 아래 게시글에서 확인하실 수 있습니다.
수정 전 코드:
import React, { Component } from 'react';
import { Col, Row, Form, FormGroup, Input } from 'reactstrap';
import SearchID from '../components/search_id';
import Info from '../components/info';
import CancelOkBtn from '../components/cancel_ok_btn';
import ReserveTable from '../components/reserve_table';
import Feedback from '../components/feedback';
개발을 하다보니, 컴포넌트가 점점 많아지면서 import를 몇 줄씩 쓰다보니 이상함이 느껴졌습니다. react는 되는데 나는 왜...? 한 눈에 비교되는 모습.. 그래서 오늘은 내가 짠 코드를 react처럼 import 하는 법을 알아보도록 하겠습니다.
결과물:
import React, { Component } from 'react';
import { Col, Row, Form, FormGroup, Input } from 'reactstrap';
import { SearchID, Info, CancelOkBtn, ReserveTable, Feedback } from '../components';
먼저 저의 프로젝트 디렉토리 구조입니다. UI를 하나의 단위 별로 나누어 components
폴더에 넣었습니다. 이를 조합하여 하나의 기능을 수행하는 containers
가 있고, 컨테이너가 조합되어 renderer
폴더 안에 있는 App.js가 있습니다.
components
와 containers
의 내용이 점점 늘어나기 때문에, 이 두 폴더를 모듈화 해보도록 하겠습니다. 제일 먼저 할 일은 각 폴더 아래에 index.js
파일을 만들어주는 것입니다. 예시를 위해 components 아래에 만들어보았습니다.
index.js에 다음 코드를 붙여넣으면 됩니다. 다음 코드에서 select 부분은 패턴으로, 패턴은 glob documentation을 참고하여 넣었습니다.
const glob = require('glob');
const path = require('path');
const folder = "./src/components/";
const select = "!(index)"; // 이 파일 제외
const format = ".js";
const local = folder + select + format;
module.exports = {};
glob.sync(local).forEach(file => {
const name = path.basename(file, format);
const m = require('./' + name).default;
module.exports[m.name] = m;
});
주의할 점
export default class *;
위와 같은 방식을 사용할 경우, 기존 코드에서 default로 설정한 부분만 export 되고, 마찬가지로 default로 설정한 부분만 import 할 수 있습니다. 저는 평소에 아래와 같이 작성하다보니 수정할 일이 없었습니다만, 혹시 모르니!!
export default class ReserveTable extends Component {
render() {
return (
<Table striped>
<thead>
<tr>
<th>#</th>
<th>학번</th>
<th>시간</th>
</tr>
</thead>
<tbody>
</tbody>
</Table>
);
}
}
Uncaught TypeError: Cannot assign to read only property 'exports' of object '#
const glob = require('glob');
대신 import glob from 'glob';
를 사용하면 이 에러가 발생합니다.
Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
at Module.eval (index.js?2af9:10)
at eval (index.js:21)
at Module../src/components/index.js (renderer.js:1610)
at __webpack_require__ (renderer.js:728)
at fn (renderer.js:102)
at eval (reserve_seat.js:7)
at Module../src/containers/reserve_seat.js (renderer.js:1646)
at __webpack_require__ (renderer.js:728)
at fn (renderer.js:102)
at eval (App.js?bd96:1)
간단히 말하자면, import
와 module.exports
는 같이 사용할 수 없습니다. export { m.name } from file;
과 같은 문구는 top level이 아닌 곳에서 사용할 수 없고요. 더 자세한 내용은 다음 글을 참고해주시기 바랍니다!!
require와 import, module.exports와 export는 뭐가 다를까?
Uncaught Error: Cannot find module './*'
at webpackEmptyContext
경로와 패턴, 파일 포맷을 변수화 하였지만, const m = require('./' + name).default;
에서 './'
를 변수로 빼면 아래와 같은 오류가 납니다.
Uncaught Error: Cannot find module './cancel_ok_btn'
at webpackEmptyContext (eval at ./src/components sync recursive (renderer.js:1587), <anonymous>:2:10)
at eval (index.js?2af9:13)
at Array.forEach (<anonymous>)
at eval (index.js?2af9:11)
at Object../src/components/index.js (renderer.js:1598)
at __webpack_require__ (renderer.js:728)
at fn (renderer.js:102)
at eval (reserve_seat.js:7)
at Module../src/containers/reserve_seat.js (renderer.js:1634)
at __webpack_require__ (renderer.js:728)
분명 변수 처리하지 않은 string과 동일한 값이지만, webpack을 거치는 과정에서 에러가 나는 걸로 보입니다. 아래 내용에 대한 해결 방법은 알아내는대로~ 글로 작성하도록 하겠습니다~!!
'React' 카테고리의 다른 글
이슈 8 Error: Cannot find module 'source-map-support/source-map-support.js' (0) | 2020.01.22 |
---|---|
이슈 7 node-sqlite3에서 this.changes / this.lastID 사용하기 (0) | 2020.01.20 |
이슈 5 react 아이콘 사용법 react-icons (0) | 2020.01.14 |
이슈 4 react form 버튼 새로고침 막기 (0) | 2020.01.14 |
이슈 3 electron + sqlite3 "Cannot find module 'node_modules/...'" (0) | 2020.01.14 |