1. TypeError: Cannot read properties of undefined (reading 'findOne') 오류 해결 과정
2. 테이블 오류해결
3. VScode에서 MySQL 테이블 보기
4. index.js 로 본 프로젝트 보수
5. index 진입점
느낀 점
참조한 사이트
// model/user.js
'use strict';
const { Model} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Users extends Model {
//많은 생략
});
return Users;
};
// userCreate.js
// 패키지 가져오기
const express = require("express");
const jwt = require("jsonwebtoken");
// 스키마 가져오기
const { Users } = require("../models/user");
// 라우터 생성하기
const router = express.Router();
// 중략
const user = await Users.findOne()
이러한 코드가 있었다.
node app
, POST localhost:3018/api/user
{
"id": "qwe123qweasd",
"password": "Asd12",
"confirmPassword": "Asd12",
"name": "김노드",
"message": "김노드입니다.",
"nickname": "노드김qweasd"
}
위와 같은 형태로 서버를 실행하고, 요청을 보냈는데 자꾸 아래와 같은 에러가 떴다.
const isExistUserNickname = await Users.findOne({ where: { nickname } });
^
TypeError: Cannot read properties of undefined (reading 'findOne')
분명히 Users를 만들었고, 내보냈고, 가져왔는데. 어째성 오류가 생기는지 몰랐다.
userCreate.js 안에 User라는 변수가 있어서 겹친건가 싶어서 Users로 이름을 바꾸기도 했고, 스키마에 이상이 있는지도 확인을 했다. 하지만 문제가 뭔지 찾지는 못하였다.
결국 팀원들과 의논을 하였고, 의외로 간단한데서 문제가 해결되었다.
const { Users } = require("../models/user");
를 const { Users } = require("../models/");
로 바꾸는 것이었다.
fs.readdirSync(__dirname)
등의 기능으로 인해서 /models/index.js 가 /models/user.js를 이용하여서 Users를 생성한다.const { Users } = require("../models/");
또는 const { Users } = require("../models");
라고 입력하면 index.js를 진입점으로 삼는다.const { Users } = require("../models/index");
와 같이 입력해도 상관 없다.require
에서는 되지만 import
에서는 안된다고 한다.그 이후에도 code: 'ER_NO_SUCH_TABLE', errno: 1146, sqlState: '42S02', sqlMessage: "Table 'expressdb.Users' doesn't exist",
라는 오류가 떴다. 이것은 내가 테이블을 추가하는 것을 까먹어서 생겼을 뿐인 오류였다.
npx sequelize-cli migration:generate --name=create-users
스키마에서 마이그레이션 생성
npx sequelize-cli db:migrate
마이그레이션에서 테이블 생성
연결해둔 DB에 우클릭하고 New Query 클릭
SELECT * FROM Users;
를 입력하고 Ctrl+Alt+E
또는 우클릭 + Run MySQL Query 클릭
입력된 테이블이 나온다.
쿼리는 따로 파일로 저장할 수 도 있다.
index.js
는 위에 말했듯이 node.js에서 require()의 진입점으로 사용되는 파일이다. 프로젝트들의 내용물이 처음에는 작지만, 점점 커지기때문에 스키마들을 구별하는 것이 좋다고한다.
models/
의 아래에 index.js
와 각각 스키마.js
를 배치하는 것이 아니라. models/각각의스키마/
의 아래에 각각의 index.js
를 넣는 것이다.
이렇게 되면 const {모듈명} = require ("../models/스키마")
로 불러올 때 /models/
아래에 index라는 .js파일이 있든 폴더가 있든 불러올 수 있으며, 폴더를 분리하면 그 밑에 index.js
(users의 스키마), test.js
(테스트용), types.ts
(타입스크립트의 타입들) 이런식으로 따로 분리할 수 도 있다.
즉, 간단한 프로젝트에서도 사용할 수 있고, 프로젝트가 커질 경우에도 수정없이 사용이 가능하다.
컴퓨터 엔지니어의 일은 달리는 기차를 수리하는 것과 같다. 달리는 기차를 멈추지 않고 수리하고, 기능을 업그레이드해서 비행기로 만들어보자.
index.js
또는 index.node
를 진입점으로 사용하는 방식은 매우 유용해 보이지만, Node.js의 개발자인 라이언 달은 "잘못 된 구조이며, 이렇게 만든걸 후회한다"라고 말했다고 한다.
원래는 .js
파밀만 썼지만 점차 .ts
, .mjs
, .cjs
등 여러 파일이 추가되고, 이것들을 찾을 수 없어서 사라졌다고 한다.
"아니 위에서는 자기가 잘썼다고 해놓고 없어졌다고?" require()
에서는 되지만 import()
에서는 안된다고 한다. 또 require()
도 요새는 잘 안쓰고 타입스크립트로 하는 추세라고한다. JS에서 JQuery를 잘 안쓰는 경향과 비슷한걸까?
user.js 를 참조해야하는데 index.js 를 참조해야한다는건, 처음에는 내가 누더기로 짠 코드를 내가 완전히 이해 못한 헤프닝이었다. 하지만 어째서 ../models/
가 ../models/user.js
를 참조하는가? 자동으로 스캔이라도 하나? > ../models/index.js
를 참조하는것이다. > 아니 난 그런거 설정한적 없는데 왜? > Node.js 는 원래 그렇게 만들어졌다. > 그리고 개발자도 그렇게 만들걸 후회하고 있다. 로 이어지는 의외의 공부도 좋았다.