스프링 부트 스타터로 프로젝트 생성

https://start.spring.io 

 

초기 설정 이렇게 해줌

-spring boot 설정할 때 뒤에 snapshot이 붙은 것들은 아직 정식 버전이 아니기 때문에 붙지 않은 다른 것들로 선택

 

IntelliJ에서 만든 프로젝트 염

- test 코드 : 요즘 개발과정에서 test가 가장 중요하다고함  

- build.gradle : 스프링부트 나오면서부터 개발자친화적으로 설정파일까지 제공해줌 

 

Build.gradle 구성
처음 실행했을때 자바 버전 에러가 뜸
File-Project Structure에서 버전 바꿔줌
에러가 발생해서 다시 프로젝트 생성
재생성했더니 정상적으로 실행됨
IntelliJ-Preference에서 Gradle 검색 후 run (gradle 통하지 않고 IntelliJ에서 바로 run하기 떄문에 더 빠름


✔︎Library

External Library 내에 수많은 빌드 툴들이 존재 // 서로 의존에 필요해서 

gradle에서 spring-boot-starter-logging은 스프링에 기본적으로 들어옴


✔︎환경설정 및 공식문서

스프링부트는 매우 포괄적이기 때문에 공식문서를 잘 활용할 줄 알아야함

spring.io 에서 사용기능들 검색 활용이 중요

https://spring.io/

 

템플릿 엔진 [thymeleaf]

https://www.thymeleaf.org/

 

서버 재시작없이 수정사항 바로 반영되게끔 하는 spring-boot-devtools 라이브러리 추가

- build.gradle의 dependencies안에 의존성 추가

developmentOnly 'org.sppringframework.boot:spring-boot-devtools'

 

- main-resources-application.properties에 application.properties에 사용 여부 추가

(필수적인 작업은 아니나 사용할 땐 true, 아닐 땐 false로 바꿈으로서 유용함)

spring.devtools.livereload.enabled=true
spring.devtools.restart.enabled=true

 

- intelliJ 환경설정

 

- 확장프로그램 설치

https://chrome.google.com/webstore/detail/livereload%20%20/ciehpookapcdlakedibajeccomagbfab

 


✔︎터미널에서 실행 (해결되지 않아서 실행방법만 기술)

1. IntellJ 종료후 터미널 접속 

2. 프로젝트 경로로 접속 

$ cd spring
$ cd hello-spring

3. build

$ ./gradlew build

이걸로 미해결

https://veneas.tistory.com/entry/IntelliJ-Execution-failed-for-task-compileJava

 

build.gradle 파일의 org.springframework.boot의 버전을 2.4.0으로 바꿔줬더니 새로운 에러가 발생

4.

$ cd build 
$ ls
$ cd libs 
$ ls -arlth //아마도 종료

 


✔︎MVC : Model, View, Controller

최근에는 Controller와 View를 쪼개서 진행함

 

<Controller>

main-java-hello-hellospring-controller-HelloController.java

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {
    @GetMapping("hello")    // url매칭됨
    public String hello(Model model){
        model.addAttribute("data", "hi!!");  // key는 data 값은 hello!!
        return "hello";  //hello.html을 return해라 return을 하게 되면 resources-templates에서 파일을 찾음
    }
    @GetMapping("hello-mvc")
    public String helloMvc(@RequestParam("name") String name, Model model) {
        model.addAttribute("name", name);
        return "hello-template";
    }
}

 

<View>

resource-templates-hello-template.html

<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello '+ ${name}">hello! empty</p>
</body>
</html>

 

http://localhost:8080/hello-mvc?name=spring!!!!!!!!!!

위에 접속했을 때


✔︎API

@ResponseBody 문자반환 (아래서 세번째줄부터 추가) 

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    @GetMapping("hello")    // url매칭됨
    public String hello(Model model){
        model.addAttribute("data", "hi!!");  // key는 data 값은 hello!!
        return "hello";  //hello.html을 return해라 return을 하게 되면 resources-templates에서 파일을 찾음
    }
    @GetMapping("hello-mvc")
    public String helloMvc(@RequestParam("name") String name, Model model) {
        model.addAttribute("name", name);
        return "hello-template";
    }
    @GetMapping("hello-string")
    @ResponseBody
    public String helloString(@RequestParam("name") String name) {
        return "hello " + name;
    }
}

command+N 단축키로 만듬 

코드 치다가 command+shift+enter 치면 코드 완성시켜줌

http://localhost:8080/hello-api?name=spring!!!!!!!!!!

이 경로 접속 시 json 형태로 출력이 되는것을 확인할 수 있음 

api 동작방식 

- localhost:8080/hello-api 접속 시 스프링으로 넘어가서 @ResponseBody를 읽게 되면 HttpMessageConverter를 이용해서 Json 스타일로 바꾼 내용 그대로를 반환한다. 

- 객체를 받게 되면 json 방식으로 데이터를 만들어서 http 응답을 한다. 

- viewResolver 대신 HttpMessageConverter가 동작함 

 


✔︎회원도메인과 레포지토리

hello-hello-spring 에 domain이라는 폴더 생성

 

 

🐰 Pre-rendering(사전 렌더링)

- 기본적으로 모든 페이지 pre-render 

- 사전에 HTML 파일들을 만든다는 의미

- 퍼포먼스 향상과 SEO에 좋음 

- Hydration : 정적인 무언가에 생기를 불어넣는 작업들을 칭함

종류 (차이점 : 언제 html을 만드냐)

- Static Generation : 정적생성
   정적은 build시에 만듦 

- Server-side Rendering : 서버 사이드 렌더링 

   요청을 하면 그때 html을 만들어서 보여줌 

 

대부분의 케이스에서는 정적생성이 권고됨 (유저가 요청을 보내기 전에 페이지를 미리 만들어도 되는 경우)

서버 사이드 렌더링 (항상 최신 상태를 유지해야 하는 경우)

 

#SEO (검색 엔진 최적화) 

웹사이트가 유기적인(무료) 검색 방식을 통해 검색 엔진에서 상위에 노출될 수 있도록 최적화하는 과정

 

pre-rendering이 안되면 js를 껐을 때 아무것도 안나오게됨 

 

이번 강의를 통해서는 정적 상태인 페이지를 만들거임

 

클라이언트 환경이 아니기 때문에 .env.파일들에서 NEXT_PUBLIC을 붙힐 필요가 없음 

 

5강 7:13초부터  

 


🐨 우여곡절 

- npm run start를 하게되면 실행이 안되서 npm run dev로 해줌 npm run build && npm run start도 마찬가지로 안됨 

$ npm run build && npm run dev

 

 

🐶 에러페이지

500error는 production에서 확인해야함

개발모드에서는 서버에러가 나면 로그를 보여줌 (어디서 에러가 났는지) 

production으로 띄우기 위해서는 build 하고 npm start 하면 build된 파일들 사용해서 뜨게 됨 

 

🐱 환경변수

- 환경에 따라 변할 수 있는 값들 분기 처리 가능

- development 환경과 production 환경에서 다른 리스트가 보여야 할 때 사용

- node.js 환경과 browser 환경에서의 사용법 다름 / node.js - process.env.변수명 / browser - process.env.NEXT_PUBLIC_변수명

 

 

pages/_error.js (언더스코어 error.js 라고 부름) [500에러페이지 만들어주려고 만듬]

- 정적으로 최적화되어 있지는 않음 

pages/404.js

pages/index.js

13-17번째 줄 수정

.env.development

.env.production

 

🐭 실행화면 

[id].js 화면에서 DEVELOPMENT 화면이라고 명시된것을 볼 수 있음


🙉 우여곡절

- 아래화면 뿐만 아니라 dior 상품 페이지도 떠야 하는데 뜨지 않음 

- [id].js 화면에서 development화면 뿐만 아니라 production 화면도 떠야되는데 안뜸

 

🐶 Next js는 모든 페이지를 사전 렌더링함

1. 정적 생성
- 프로젝트가 빌드하는 시점에 html파일들이 생성

- 모든 요청에 재사용

- 퍼포먼스 이유로, 넥스트 js는 정적 생성을 권고

- 정적 생성된 페이지들은 CDN에 캐시

- getStaticProps / getStaticPathsj

 

2. Server Side Rendering (Dynamic Rendering)

- 요청이 있을때마다 다시 부르려면은 서버사이드렌더링 사용

- 항상 최신 상태 유지

- getServerSideProps

 

ex 렌더링 

상세페이지 같은 경우는 화면에 보여지는 데이터들이 있어야 하기 때문에 API호출이 안되어 있을때 정보공유나 상세정보가 보이지 않기 때문에 서버사이드 렌더링으로 만들어본다.

 

index.js

[id].js

item을 props로 받아주게 되면서 기존의 코드에서 삭제되는 부분들임 

=> 아이템이 있는지 없는지만 확인이 되면 되서

삭제한 부분
전체코드

메뉴바 사용위한

Gnb.js

- router 사용

- next/link를 이용하면 새로고침이 없다는 특징

- Location을 사용하면 새로고침이 됨 -> 부드럽게 이동할수 없다는 단점

 

Footer.js 

Footer에 바가 없어서 수정해줌

about.js

최종구현 화면 

isLoading 사용으로 새로고침 시 로딩 됨

오늘 끝----

'개발 > next.js' 카테고리의 다른 글

[next.js] 블로그 앱 만들기 5강  (0) 2023.07.12
[next.js] 블로그 앱 만들기 4강  (0) 2023.07.11
[next.js] 블로그 앱 만들기 2강  (0) 2023.06.29
[next.js] 블로그 앱 만들기 1강  (0) 2023.06.27
[next.js] 라우팅  (0) 2023.06.27

🐶 api 불러오기 

api 호출 사용 전 axios 설치
$ npm i axios 

 

Index.js

useEffect import 해준뒤 아래와 같은 내용 추가
상품을 나눠서 보여주기 위해 slice 사용

ItemList.js 

component/ItemList.module.css

🐱 Dynamic Routes 사용

각 이미지를 클릭했을 경우 넘어가게끔 하는데 사용

https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes

 

Routing: Dynamic Routes | Next.js

Using Pages Router Features available in /pages

nextjs.org

- pages/blog/[slug].js 이처럼 []로 묶어주어서 사용을 하고 [] 내부가 1,2,3 a,b,c 이런식으로 id의 역할 

 

Pages/view/[id].js

src/component/Item.js

 

src/component/Item.module.css

 

만든 페이지


🦁 겪었던 우여곡절

- import Axios from "axios";가 아닌 import { Axios } from "axios"; 이렇게 해주면 Axios 에러가 발생함 

- item 클릭했을 때 이미지 안보이는 문제가 있었는데 [id].js 페이지에서 Axios 부분에 console.log만 있고 setData가 없어서 그랬던거였음;

 

 

'개발 > next.js' 카테고리의 다른 글

[next.js] 블로그 앱 만들기 5강  (0) 2023.07.12
[next.js] 블로그 앱 만들기 4강  (0) 2023.07.11
[next.js] 블로그 앱 만들기 3강  (0) 2023.07.05
[next.js] 블로그 앱 만들기 1강  (0) 2023.06.27
[next.js] 라우팅  (0) 2023.06.27

$ npm run dev 로 실행

파일 경로는 이럼

about.js와 view 안의 [id].js 내부의 import와 내용을 똑같이 해주게 되면 아래와 같이 이상한 경로에도 작성한 화면이 에러없이 뜨게됨 

semantic UI 사용하기 위한 설치 

$  npm install semantic-ui-react semantic-ui-css

_app.js  만들어주고 아래와 같은 내용 입력 

// import "./styles/globals.css";
import "semantic-ui-css/semantic.min.css";

function MyApp({ Component, pageProps }) {
    return <Component {...pageProps} />
}

export default MyApp;

🐶 _app.js 사용 특징
- 페이지 전환 시 레이아웃 유지 가능
- 페이지 전환 시 상태값 유지 가능
- componentDidCatch 이용해 커스텀 에러 핸들링 가능
- 추가적인 데이터 페이지로 주입시키는 것 가능 
- 글로벌 CSS 이곳에 선언 
 
_document.js 만들어주고 아래와 같이 입력 (  하단 next.js 공식문서 참고 )

//Document가 불러와지지 않아 발생한 에러때문에 import 옆에 Document 추가함
import Document, { Html, Head, Main, NextScript } from 'next/document'
 
class MyDocument extends Document {
// export default function Document() {
  
    render(){
        return (
            <Html lang="ko">
            <Head />
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
            );
        }
    }

    export default MyDocument;

🐱 app과 document의 역할은 다름
- app은 글로벌 css 적용 및 레이아웃 적용
- document는 서버에서만 렌더링되고 onClick과 같은 이벤트 핸들러나 css 적용 안됨 
- app과 document의 헤드도 서로 다른 역할을 해줌 
 
최종 library와 코드 내용

_app.js

// import "./styles/globals.css";
import "semantic-ui-css/semantic.min.css";
import Footer from "../src/component/Footer";
import Top from "../src/component/Top";

function MyApp({ Component, pageProps }) {
    return (
        <div style= {{ width: 1000, margin: "0 auto" }}>
            <Top />
            <Component {...pageProps} />;
            <Footer />
        </div>
    );
}

export default MyApp;

_document.js

import Document, { Html, Head, Main, NextScript } from 'next/document'
 
class MyDocument extends Document {
// export default function Document() {
  
    render(){
        return (
            <Html lang="ko">
            <Head />
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
            );
        }
    }

export default MyDocument;

index.js

import Head from 'next/head';
import styles from '../styles/Home.module.css';

export default function Home() {
  return (
    <div>
      <Head>
        <title>Home | uminida</title>
      </Head>
    </div>
  )
}

public/images안에는 poui.JPG라는 아래와 같은 이미지 

src/component/Footer.js

export default function Footer() {
  return <div>Copyright © uminida. All rights reserved.</div>;
}

src/component/Gnb.js

import { Menu } from "semantic-ui-react";

export default function Gnb(){
    const activeItem = "home";
    return (
        <Menu inverted>
        <Menu.Item
        name='home'
        active={activeItem === 'home'}
        //   onClick={this.handleItemClick}
        />
        <Menu.Item
        name='messages'
        active={activeItem === 'messages'}
        //   onClick={this.handleItemClick}
        />
        <Menu.Item
        name='friends'
        active={activeItem === 'friends'}
        //   onClick={this.handleItemClick}
        />
    </Menu>
  )
}

src/component/Top.js

import { Header } from "semantic-ui-react"; 
import Gnb from "./Gnb";

export default function Top() {
  return (
    <div>
        <div style={{ display: "flex", paddingTop: 20 }}>
            <div style={{ flex: "100px 0 0" }}>
                <img 
                    src="/images/poui.JPG" 
                    alt="logo"
                    style={{display: "block", width: 80 }}
                />
                </div>
                <Header as="h1">uminida</Header>
                </div>
            {/* Gnb 불러옴 */}
            <Gnb />   
        </div>
    ); 
}
1강 내용을 토대로 위와 같은 결과가 나옴

 


next.js 페이지들은 공식문서를 통해서 필요한 menu나 이런 양식들을 받아와서 코드를 짤 수가 있음 
https://nextjs.org/docs

Docs | Next.js

Using App Router Features available in /app

nextjs.org

만들면서 사용한 document.js 예시

🐸겪었던 우여곡절
- style에 분명히 width랑 margin을 줬는데 안먹어서 보니까 창크기 조절 안해줘서 그런거였음;
- Gnb 메뉴바가 안떠서 미치는 줄 알았는데 return을 빼먹어서 그런거였음;
- _document에서 자꾸 에러나길래 뭐가 문젠가 싶었는데 Document가 불러와지지 않아서 import에 Document를 따로 추가해주면 됬음;
 
이상.

'개발 > next.js' 카테고리의 다른 글

[next.js] 블로그 앱 만들기 5강  (0) 2023.07.12
[next.js] 블로그 앱 만들기 4강  (0) 2023.07.11
[next.js] 블로그 앱 만들기 3강  (0) 2023.07.05
[next.js] 블로그 앱 만들기 2강  (0) 2023.06.29
[next.js] 라우팅  (0) 2023.06.27

앱 라우팅 예시

🐶 앱 라우팅 ( App Routing ) 

앱 내에서 전체적인 라우팅 구조 관리하는 것 

 

🐱 페이지 라우팅 ( Page Routing )

개별 페이지 간의 라우팅 처리 

특징 

- 각 페이지는 고유한 경로와 해당 경로에 대응하는 컴포넌트 가짐 

 

두 라우팅은 보통 함께 사용됨

select 라이브러리 설치 

$ npm install react-select 

 

코드에 필요한 Select 컴포넌트 추가해줌

import Select from 'react-select';

 

select01 : 문제유형
select02/03 : 레벨, 언어

 

select 값 정상적용되는 부분은 아래 링크 참고해서 코드 수정해야함

https://so-so.dev/react/make-select/

 

Select 컴포넌트

Intro 어떤 디자인 시스템에서 컴포넌트를 제공한다면, 어떤 기능들을 기대하시나요? 이 글에서는 Select컴포넌트에게 바라는 기능을 중심으로 구현 방법과 예제 코드를 설명합니다. ⚠️ 이 글에

so-so.dev

 

'개발 > 졸작' 카테고리의 다른 글

npm-gyp 에러  (0) 2023.02.14
가상환경없이 OnlineJudge 커스터마이징  (0) 2023.02.09
real-project 과정  (0) 2023.02.06
참고자료  (0) 2023.02.06
自己開發  (0) 2023.01.25

+ Recent posts