CRA (Create-React-App) 없이 리액트 만들어보기
package.json 설치
cra 없이 react를 시작하기 위해 프로젝트에 node를 설치해줘야된다.
터미널에 아래와 같은 명령어 입력
1
npm init -y
- -y는 npm 설치를 default 값으로 해주는경우 써준다.
- 디테일한 세부 설정을 하려면 npm init 만 써주도록 하자
React 설치
react를 사용하기위해서 npm에서 react 와 react-dom 설치
1
npm install react react-dom
babel 설치
원활한 react 사용을 위한 babel 설치
1
npm install -D @babel/core @babel/preset-env @babel/preset-react
- @babel/core : 바벨의 코어
- @babel/preset-env : ES6코드를 ES5로 트랜스파일링
- @babel/preset-react : 리액트 JSX를 트랜스파일링
- 바벨은 개발때만 사용하므로 명령어에 -D를 붙여줌으로 써 package.json에서 dependencies에 담기지 않고 devDependencies 담기기 위해 사용
babel 설정파일 .babelrc 파일을 생성 및 내용 입력
바벨의 설정값을 사용하기 위해 .babelrc
파일 생성 (바벨의 설정파일)
1
2
3
4
5
6
7
8
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": []
}
webpack 설치
1
npm install -D webpack webpack-cli webpack-dev-server
- webpack : 웹팩의 코어를 의미
- webpack-cli : 웹팩을 커맨드라인에서 사용가능 하게함
- webpack-dev-server : 웹팩을 메모리 상에 빌드하여 개발 서버를 구동
webpack의 번들링에 필요한 loader 관련 설치
1
npm install -D babel-loader style-loader css-loader file-loader html-loader
- babel-loader : JSX 및 ES6+ 문법을 트랜스파일링
- style-loader : 변환된 CSS 파일을
<style>
태그로 감싸서 삽입 - css-loader : CSS 파일을 자바스크립트가 이해할 수 있도록 변환
- file-loader : 이미지 및 폰트 등의 파일 로딩
- html-loader : html을 읽을 수 있음
webpack에 필요한 플러그인 설치
1
npm install -D html-webpack-plugin clean-webpack-plugin
- html-webpack-plugin : HTML 파일에 번들링된 자바스크립트 파일을 삽입해주고 번들링된 결과가 저장되는 폴더에 옮김.
clean-webpack-plugin : 번들링을 할 때마다 이전 번들링 결과를 제거.
- mini-css-extract-plugin : css 파일로 변환해주는 플러그인.
webpack 설정파일 webpack.config.js 파일 생성 및 내용입력
1
2
3
4
5
6
7
8
9
10
11
12
13
const path = require("path");
module.exports = {
mode: "development",
entry: "./index.js",
resolve: {
extensions: [".js", ".jsx"]
},
output: {
//path: path.resolve(__dirname, './dist'),
filename: "bundle.[hash].js"
}
};
- require(’path’) : 노드에서 지원해주는 경로 모듈을 불러온다.
- mode : 웹펙의 현재 모드를 설정 development / production / none 의 3가지 모드가 있다.
- entry : 어플리케이션이 어디에서 실행하는 지를 설정한다.
- resolve : 웹펙에서 파일을 처리할때 확장자를 생략해도 인식하게 만들수 있게 해줌
- output.path : 결과물을 출력할때 나오게하는 곳을 직접 지정할 수 있음
- output.filename : 파일이름을 설정 할 수 있음 [hash]는 컴파일할때 사용한 hash를 사용하게 됨
1
devtool: 'eval-cheap-source-map',
- devtool : source-map을 설정하는 부분으로 에러가 발생했을 때 번들링된 파일에서 어느 부분에 에러가 났는지를 쉽게 확인할 수 있게 해주는 도구
1
2
3
4
5
6
7
8
9
10
const port = process.env.PORT || 3000;
----
devServer: {
host: 'localhost',
port: port,
hot : true,
open: true,
},
process.env.PORT 3000 : 포트번호 설정 - devServer : webpack-dev-server의 옵션 설정
- overlay : 에러 발생 시 브라우저에 내용을 띄울지 설정
- hot : 모듈의 변화만 자동으로 로드하는 HMR(Hot Module Replacement) 기능 활성화 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: '/node_modules/',
loader: 'babel-loader',
},
{
test: /\.css$/,
// use: ['style-loader', 'css-loader'],
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
{
test: /\.(jpeg|jpg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
모듈부분 추가
- modules, rules : 모듈에 적용할 로더들과 그 옵션들을 설정
- test : 어떤 파일에 적용할지 확장자 작성
- exclude : 로더에서 제외할 파일 설정
- loader : 적용할 로더가 1개라면 loader로 설정
- use : 적용할 로더가 2개 이상이면 use 배열로 설정
플러그인 추가 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 설치된 플러그인들을 불러온다.
const HtmlWebpackPlugin = require('html-webpack-plugin');
//const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
-----
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
// new MiniCssExtractPlugin({ filename: 'app.css' }),
// "style-loader"와 MiniCssExtractPlugin.loader를 함께 사용하면 안됩니다
],
모드코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const path = require("path");
// 설치된 플러그인들을 불러온다.
const HtmlWebpackPlugin = require("html-webpack-plugin");
//const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// 기본 포트 설정
const port = process.env.PORT || 3000;
module.exports = {
mode: "development",
entry: "./index.js",
resolve: {
extensions: [".js", ".jsx"]
},
output: {
path: path.resolve(__dirname, "./dist"),
filename: "bundle.[hash].js"
},
devtool: "eval-cheap-source-map",
devServer: {
host: "localhost",
port: port,
hot: true,
open: true
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules/",
loader: "babel-loader"
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
// use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
{
test: /\.(jpeg|jpg|png)$/,
loader: "file-loader",
options: {
name: "[name].[ext]"
}
}
]
},
// 추가된 플러그인을 설정해주는곳
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./public/index.html"
})
// new MiniCssExtractPlugin({ filename: 'app.css' }),
// "style-loader"와 MiniCssExtractPlugin.loader를 함께 사용하면 안됩니다
]
};
package.json script 작성
1
2
3
4
"scripts": {
"dev": "webpack-dev-server --progress",
"build": "webpack"
}
src에 파일 생성 App.jsx
1
2
3
4
5
6
7
8
9
10
11
import React from "react";
const App = () => {
return (
<>
<h1>hello</h1>
</>
);
};
export default App;
root에 index.js 파일 생성
1
2
3
4
5
import React from "react";
import ReactDom from "react-dom";
import App from "./src/App";
ReactDom.render(<App />, document.getElementById("root"));
실행
1
npm run dev
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.