작업 상태

- vscode에서 express 작업중이었습니다.

- vscode node-terminal 설정 후 사용시 발생한 현상입니다.

        {
            "command": "npm run dev",
            "name": "client 3500",
            "request": "launch",
            "type": "node-terminal"
        }

  
에러 상황

원인

- 근본 원인은 확인하지 못했고 현상에서 원인은

1. nodemon은 변경사항을 확인하고 재시작합니다.

2. vscode에서 디버그 모드 시작시 설정파일을 변환해서 사용하는듯 합니다.

3. vscode에서 vite.config.js 이파일을 잠시 temp파일로 만들고 삭제하려 합니다. > nodemon이 변화감지 후 재시작 > vscode로 변화감지후 설정 재변경을 위한 파일 생성을 서로 사이좋게 주고받습니다.


처리

- nodemon에서 임시파일 변경 감지를 제거합니다.

 

기존 package.json설정입니다.

    "scripts": {
        "dev": "cross-env NODE_ENV=development nodemon server.js",

수정후

    "scripts": {
        "dev": "cross-env NODE_ENV=development nodemon server.js --ignore './vite.config*.mjs",

참고

 

nodemon을 사용할 때 자주 쓰이는 주요 옵션들은 다음과 같습니다.

-e, --ext [ext]: 모니터링할 파일의 확장자를 설정합니다. 예를 들어, -e js,hbs와 같이 사용하면 확장자가 .js와 .hbs인 파일을 모니터링합니다.
-i, --ignore [pattern]: nodemon이 모니터링하지 않을 파일의 패턴을 설정합니다. 정규 표현식으로 작성할 수 있습니다.
-w, --watch [path]: 모니터링할 디렉토리를 설정합니다. 여러 개의 경로를 설정할 수 있습니다.
-V, --version: nodemon의 버전 정보를 출력합니다.
-h, --help: 도움말을 출력합니다.

 

nodemon --help 치면 좀더 자세히 나옵니다.

작업 상태

- 기존에 react에서 사용하던 코드를 vite사용 환경으로 포팅하던중 .env 에서 설정한 변수 사용중 발생했습니다.

- react만 사용할때는 정상 작동했던 코드입니다.

 

.env

REACT_APP_LOG_LEVEL=debug

  

const apiLogLevel = process.env.REACT_APP_LOG_LEVEL; //에러가 발생한 장소 입니다


에러 메시지 

Uncaught ReferenceError: process is not defined


원인

- vite 쪽 환경으로 이동하면서 발생한 문제였습니다.

처리

-  vite 에서 환경변수 관리하는 형태로 변경합니다.

- vite 쪽에서 VITE_ prefix 사용을 권장합니다.

const apiLogLevel = import.meta.env.VITE_APP_LOG_LEVEL;

 

.env

VITE_APP_LOG_LEVEL=debug

 

또는

npm install dotenv 이후 

import dotenv from 'dotenv';
dotenv.config();

로 하면 동작하기는 합니다.

 


참고

--------------------------React

React에서 .env 환경 변수를 사용하기 위해서는 몇 가지 조건이 있습니다.

환경 변수 이름은 반드시 REACT_APP_으로 시작해야 합니다.
환경 변수는 프로젝트 루트 디렉토리에 위치한 .env 파일에 선언해야 합니다.
위 두 가지 조건을 만족하면, React 애플리케이션에서 process.env.REACT_APP_ 접두어를 사용하여 .env 파일에 선언된 환경 변수에 접근할 수 있습니다.

 

.env 파일명 

<projectroot>/.env
REACT_APP_LOG_LEVEL=debug

 

react.js에서 사용예시

const apiLogLevel = process.env.REACT_APP_LOG_LEVEL;

 

--------------------------Vite

Vite에서 .env 환경 변수를 사용하기 위해서는 다음과 같은 방법을 사용할 수 있습니다.

.env 파일을 프로젝트 루트 디렉토리에 위치시킵니다.
.env 파일에서 사용할 환경 변수를 선언합니다. 변수 이름은 VITE_으로 시작해야 합니다.

 

/.env
VITE_APP_LOG_LEVEL=debug

 

vite 환경에서 사용예시

const apiUrl = import.meta.env.VITE_APP_LOG_LEVEL;

 

주의할점은, Vite에서는 .env.local, .env.development, .env.production과 같은 환경 변수 파일도 지원합니다. 이러한 파일을 사용하면, 개발 환경과 프로덕션 환경에서 각각 다른 환경 변수 값을 설정할 수 있습니다.

 

보통은 참조할점인데. react에서 이동하는 상황이어서  .env, .env.development, .env.production 이 세개의 파일이 존재했는데, vite에서는 설정값에 따라 알아서 다른 환경변수 파일을 불러옵니다.

 

Vite의 환경 변수와 모드 | Vite (vitejs-kr.github.io)

 

Vite

Vite, 차세대 프런트엔드 개발 툴

vitejs-kr.github.io

 

작업 상태
- querydsl을 vscode에서 작업하던중 발생했습니다.

- vscode 사용중이었고 querydsl 설정은 완료되었고 vscode에서 springboot 시작중에 나온에러입니다.


에러 메시지 

- Project 'back' is missing required source folder: 'src/main/generated/querydsl'

- The type QBoard is already defined


원인

- Q..Entity를 사용했는데 없어서 나오는 에러입니다.


처리

- gradle로 생성해 줍니다.  gradle project > Tasks> ohters > compileQuerydls 실행

생성후 > Entity를 기준으로 Q클래스가 생성됩니다.

- Q클래스들을 생성후 boot를 실행시키면 경우에 따라서 또 다시 아래와 같은 에러가 발생하는 경우가 있습니다.

- The type QBoard is already defined

- 이 에러가 발생한 경우 vscode일 때 새로 생성된 Q클래스들을 인식시키기 위해 전부 생성된 Q클래스들을 클릭해서 열어줍니다.

전부 클릭해서 인식시키후 상황

- 이후 실행하면 정상 실행 됩니다.


참고

- BUILD FAILED in 1s
0. error: Could not find class file com.a3040.member.Member 등 :back:compileQuerydsl FAILED 이 나올경우

이미 Qclass가 생성되어 있는지 확인 queryDsl 이미 실행되어 compileQuerydsl실행 후 프로젝트에 관련 Qclass.java 파일들이 존재하면 발생합니다.

1. 생성된 Qclass가 있는 폴더를 삭제합니다.  > 이후 실행하면 Qclass가 없어서 실행이 안됩니다.

2. gradle project > Tasks> ohters > compileQuerydls 실행 > Qclass는 생성되었으나 이번에는 The type QBoard is already defined: <--이 에러로 실행 안됩니다.

3. vscode에서 자동 생성된 class를 인식시킵니다. 다 열어봄 > 잘 실행 됩니다.

4. 이상태에서 뭔간 변경되어 수정하고 compileQuerydls을 실행할경우 이번에는 기본 Entity 클래스가 없다는 에러가 발생합니다.  0번 부터 다시 확인합니다.

작업 상태

- TodoController라는 콘트롤러에서 json으로 데이터를 받아 update하는 과정에서 발생했습니다.
 
에러 메시지 

- java.lang.Error: Unresolved compilation problems:
        The method setIsCompleted(String) is undefined for the type Optional<Todo>
        The method save(Todo) in the type TodoService is not applicable for the arguments (Optional<Todo>)

원인

 Optional<Todo> currentTodo  currentTodo의 현재 타입은  Optional<Todo>입니다.

Optional<Todo> 는 Todo 클래스가 아니기 때문에 Todo 클래스의 메소드를 사용할수 없습니다.


증상 발생 코드 

@PostMapping("/admin/todos/complete")
public ResponseEntity<String> updateComplete(@RequestBody @Valid Todo todo,
        BindingResult result) {
        Optional<Todo> currentTodo = todoService.findById(todo.getId());
    if (currentTodo.isPresent()) { 
        currentTodo.setIsCompleted(todo.getIsCompleted());
        todoService.save(currentTodo);
        return ResponseEntity.ok("저장되었습니다.");
    } else {
        throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Working not found");
    }
}

 

처리코드

@PostMapping("/admin/todos/complete")
public ResponseEntity<String> updateComplete(@RequestBody @Valid Todo todo,
        BindingResult result) {
        Optional<Todo> searchTodo = todoService.findById(todo.getId());
    if (searchTodo.isPresent()) { 
        Todo currentTodo = searchTodo.get();
        currentTodo.setIsCompleted(todo.getIsCompleted());
        todoService.save(currentTodo);
        return ResponseEntity.ok().build();
    } else {
        throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Working not found");
    }
}


참고

Optional은 Java 8에서 추가된 클래스로, 값이 있을 수도 있고 없을 수도 있는 객체를 감싸는 래퍼 클래스입니다. 이를 통해 NullPointerException 등의 오류를 방지할 수 있습니다. 데이터를 조회해서 가져오는 등의 작업을 할때도 사용됩니다.

 

메소드
of: 주어진 값으로 Optional 객체를 생성합니다. 값이 null인 경우에는 NullPointerException이 발생합니다.
isPresent: Optional 객체에 값이 있는지 여부를 반환합니다.

get: Optional 객체에 저장된 값을 반환합니다. 값이 없는 경우에는 NoSuchElementException이 발생합니다.

 

Optional<String> name = Optional.of("John");// "John"이라는 값을 가진 Optional 객체를 생성합니다.
if (name.isPresent()) {  //값이 있는지 여부를 체크합니다.
    System.out.println("Hello, " + name.get() + "!"); // get 메소드를 이용해값을 가져옵니다.
} else {
    System.out.println("Hello, anonymous!");
}

+ Recent posts