{
"$schema": "https://json.schemastore.org/tsconfig.json",
// schemaStore에서 제공해주는 정보. 해당 JSON 파일이 무엇을 의미하는지, 또 어떤 키와 어떤 값이 들어갈 수 있는지 알려주는 도구. VSCode같은 IDE에서 자동완성이 가능해진다.
// .eslintrc, .prettierrc와 같이 JSON 방식으로 설정을 작성하는 라이브러리가 schemaStore에 내용을 제공한다면 편리하게 JSON 설정을 할 수 있다.
"compilerOptions": {
// ts를 js로 컴파일할 때 사용하는 옵션
"target": "es5",
// ts가 변환을 목표로 하는 언어의 버전(폴리필은 지원하지 않는다.)
"lib": ["DOM", "DOM.Iterable", "ESNext"],
// 신규 기능에 대한 API 정보를 확인할 수 있게 되어 에러가 발생하지 않는다. DOM -> window, document 등 브라우저 위주 API에 대한 명세 사용하기 위해
"allowJs": true,
// ts가 js파일도 컴파일할지 여부. js와 ts 파일이 혼재됐을 때 사용하는 옵션
"skipLibCheck": true,
// 라이브러리에서 제공하는 d.ts에 대한 검사 여부 -> 켜져있다면 d.ts에 에러가 있으면 에러 발생
// 전체적인 d.ts를 모두 검사하기 때문에 컴파일 시간이 길어져 일반적으로는 off
"strict": true,
// ts 컴파일러의 strict mode 제어. 이 모드가 켜지면 아래 옵션도 true로 설정된다.
// - alwaysStrict : 모든 js 파일에 use strict 추가(권장)
// - strictNullChecks : 엄격한 null check 활성화. null과 undefined를 명확하게 구분해 사용한다.(권장)
// - strictBindCallApply : 함수에 대해 사용할 수 있는 call, bind, apply에 대해 정확한 인수를 요구하는 옵션(권장)
// - strictFunctionTypes : 함수의 타입에 대해 엄격함을 유지한다.(권장)
// - strictPropertyInitialization : 클래스 내부의 프로퍼티에 값을 할당할 때 타입 틀리면 에러 발생
// - noImplicitAny : 타입을 명시하지 않은 변수에 any를 자동으로 할당하지 않고 에러 발생
// - noImplicitThis : This를 추론할 수 없는 상황에서 any를 자동으로 할당하지 않고 에러 발생
// - useUnknownInCatchVariables : catch 구문 잡은 변수에 any가 아닌 unknown 할당 -> catch 한 것이 반드시 에러라는 보장이 없기 때문(권장)
"forceConsistentCasingInFileNames": true,
// 파일 이름의 대소문자 구분을 강제한다.
"noEmit": true,
// 컴파일 하지 않고 타입 체크만 한다. Next.js는 swc가 ts 파일을 컴파일하기 때문에 ts는 단순히 타입 검사만 하는 역할을 한다.
"esModuleInterop": true,
// CommonJS 방식으로 보낸 모듈을 ES 모듈 방식의 import로 가져올 수 있게 해준다.
"module": "ESNext",
// 모듈 시스템 설정 : commonjs - require, esnext - import
"moduleResolution": "Node",
// 모듈 해석하는 방식 설정 : node - node_modules 기준, classic - tsconfig.json이 있는 디렉터리 기준
// node는 모듈이 commonjs일 때만 사용할 수 있다
"resolveJsonModule": true,
// JSON 파일을 import할 수 있게 해준다. 이 옵션을 켜면 allowJS 옵션도 자동으로 켜짐
"isolatedModules": true,
// 파일에 import나 export가 없다면 단순 스크립트 파일로 인식해 이러한 파일이 생성되지 않도록 막는다.
"jsx": "preserve",
// .tsx 파일 내부에 있는 JSX를 어떻게 컴파일할지 설정
"incremental": true,
// ts는 마지막 컴파일 정보를 .tsbuildinfo 파일 형태로 만들어 디스크에 저장. -> 다시 컴파일러가 호출되면 해당 정보를 활용해 가장 비용이 적게 드는 방식으로 컴파일을 수행해 더 빠르게 컴파일한다.
"baseUrl": "src",
// 모듈을 찾을 때 기준이 되는 디렉터리 지정
"paths": {
"#pages/*": ["pages/*"],
"#hooks/*": ["hooks/*"],
"#types/*": ["types/*"],
"#components/*": ["components/*"],
"#utils/*": ["utils/*"]
},
// 경로에 별칭(alias) 지정
// #hooks/useToggle = src/hooks/useToggle
// @는 충돌할 수 있으므로 사용을 피한다.
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
// ts 컴파일 대상에서 포함시킬 파일 목록
"exclude": ["node_modules"]
// ts 컴파일 대상에서 제외시킬 파일 목록
}
}
export const Hello = () => <div>Hello</div>
// react : 기본값. React.createElement로 변환된다.
export const Hello = () => React.createElement('h1', null, 'Hello')
// react-jsx
// 리액트17에서 새롭게 등장. react/jsx-runtime 사용해 변환
// React.createElement 사용하지 않음 -> 상단에서 React import할 필요가 없다.
import {jsx as _jsx} from 'react/jsx-runtime',
export const Hello = () => _jsx('div', {children: 'Hello'})
// react-jsxdev : react-jsx에 디버깅 정보 추가
import {jsxDEV as _jsxDEV} from 'react/jsx-dev-runtime'
const _jsxFileName = 'file:///input.tsx'
export const Hello = () => {
_jsxDEV(
'div',
{children: 'Hello'},
void 0,
false,
{fileName: _jsxFileName, lineNumber: 1, columnNumber: 27},
this,
)
}
// preserve : 변환하지 않고 그대로 유지
export const Hello = () => <div>Hello</div>
// react-native : react native 에서 사용하는 방식. 변환하지 않는다.
export const Hello = () => <div>Hello</div>
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
// 리액트 strict mode 활성화
poweredByHeader: false,
// X-Powered-By 헤더를 제거한다(보안)
eslint: {
ignoreDuringBuilds: true,
// 빌드 시에 ESLint를 무시한다.
},
};
module.exports = nextConfig;
즉, 스텝 -> 잡(병렬 실행) -> 액션 -> 러너에서 실행
name : chapter7 build
run-name : ${{ github. actor }} has been added new commit.
on:
push:
branches-ignore:
- 'main'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: 'install dependencies'
working-directory: ./chapter7/my-app
run: npm ci
- name: 'build'
working-directory: ./chapter7/my-app
run: npm run build
의존성에 문제가 있다면 이에 대해 문제를 알려주고 해결할 수 있는 PR도 열어준다.
시멘틱 버전 : 주.부.수
주의할 점
npm 버전 규칙
이는 약속일 뿐이므로, 실제로 이에 맞춰 개발되었다고 확신할 수는 없다.
의존성
실습 위주의 내용이므로 정리하지 않음
[[plugins]]
package = "netlify/plugin-nextjs"
도커 용어
도커 cli 명령어
docker build -t foo:bar ./
docker inspect {이미지명 | 컨테이너명}
docker rm {이미지명}
FROM node:18.12.0-alpine3.16 as build
# FROM : 이 이미지가 어떤 베이스 이미지 위에서 실행될 지 결정
# node:18.12.0 : Node.js 18.12.0 버전이 설치되어 있는 이미지
# alpine3.16 : alpine3.16 버전의 운영 체제 위에서 실행되는 이미지
# alpine : 알파인 리눅스. 도커 허브에서 가져온다.
# as build : 이 베이스 이미지는 빌드 단계에서만 사용한다.
WORKDIR /app
# WORKDIR : 작업을 수행하고자 하는 기본 디렉터리
COPY package.json ./package.json
COPY package-lock.json ./package-lock.json
# COPY : 파일을 복사하는 명령어
# 복사하는 위치는 앞서 설정한 ./app
RUN npm ci
# RUN : 컨테이너에서 명령어 실행
# npm ci : 의존성 설치
COPY . ./
# 모든 리소스 복사
RUN npm run build
# 애플리케이션 빌드
애플리케이션 실행을 위해 코드 추가
FROM nginx:1.23.2-alpine as start
# 최신 버전의 NGINX가 설치된 알파인 리눅스 설치
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# 빌드한 파일을 NGINX가 서비스할 수 있도록 설정 파일 복사
COPY --from=build /app/build /usr/share/nginx/html
# --from=build : as build로 선언한 단계
# build단게에서 /app/build를 가져와 /usr/share/nginx/html 에 복사한다.
EXPOSE 3000
# 3000번 포트를 연다
# 도커 이미지를 실행할 때 호스트 운영체제에서 오픈된다
ENTRYPOINT ["nginx", "-g", "daemon off;"]
# 컨테이너가 실행됐을 때 어떤 명령을 실행할지 정한다
# Dockerfile 내부에서 단 한 번 실행된다
# NGINX의 데몬을 시작하도록 했다
실습 위주라 정리하지 않음