React CRA를 이용하지 않고 프로젝트 생성(1)
CRA를 사용하지 않는 이유
- 불필요한 모듈의 설치
- Webpack.config.js를 이용해 여러 옵션을 변경할 필요가 있을 경우
프로젝트 생성 하기
npm init -y
or
yarn init -y
react를 사용하기 위한 기본 설치 패키지
npm i react react-dom // react 개발에 필요
npm install --save-dev webpack // 웹팩 기본 라이브러리
npm i --D webpack-cli // 웹팩을 명령어로 사용하기 위한 라이브러리
npm i --D html-webpack-plugin // html을 webpack으로 번들링 하기 위한 라이브러리
npm i --D webpack-dev-server // 웹팩을 이용한 로컬 테스트용 라이브러리
npm i --D babel-loader // 버전 호환을 위한 기본 라이브러리
npm i --D @babel-core // 코드에서 직접 바벨로 컴파일 할때 사용하는 라이브러리
npm i --D @babel-preset-env // babel에서 가장 많이 쓰는 플러그인 모음
npm i --D @babel-react // babel에서 많이 쓰이는 react용 플러그인 모음
* i = install
* --save-dev = --D
패키지를 설치 후 package.json파일을 확인 하면 아래와 같다
package.json
{
"main": "index.js",
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open",
},
"devDependencies": {
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"babel-loader": "^8.2.4",
"eslint": "^8.12.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.29.4",
"html-webpack-plugin": "^5.5.0",
"prettier": "^2.6.2",
"source-map-loader": "^3.0.1",
"ts-loader": "^9.2.8",
"ts-node": "^10.7.0",
"typescript": "^4.6.3",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.8.1"
},
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
script 명령어를 추가해 준다.
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open",
},
babel-loader를 사용하기 때문에 .babelrc 파일은 필요없다 필요한 경우 아래와 같이 작성한다.
root 디렉토리에 .babelrc 파일 생성
.babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": []
}
빌드 및 개발 테스트를 위한 webpack설정을 작성한다.
아래는 샘플 webpack.config.js 파일이다 참고만 하자
root 디렉토리에 webpack.config.js파일 생성
webpack.config.js
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 번들 파일 생성 위치
const bundlePath = path.resolve(__dirname, 'dist/');
module.exports = (_env, argv) => {
let entryPoints = {
main: {
path: './src/index.jsx',
outputHtml: 'main.html',
build: true
},
config: {
path: './src/config.jsx',
outputHtml: 'config.html',
build: false
}
};
let entry = {};
// 웹팩 플러그인 추가 구성
let plugins = [new webpack.HotModuleReplacementPlugin()];
Object.entries(entryPoints).map(([key, value]) => {
if (value.build) {
entry[key] = value.path;
if (argv.mode === 'production') {
plugins.push(
new HtmlWebpackPlugin({
inject: true,
chunks: [key],
template: './public/template.html',
filename: value.outputHtml
})
);
}
}
return null;
});
let config = {
entry,
optimization: {
minimize: true // 불필요한 코드 최적화
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: []
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: 'img/[name].[ext]'
}
}
]
},
resolve: { extensions: ['*', '.js', '.jsx'] },
output: {
filename: '[name].js',
path: bundlePath
},
plugins
};
if (argv.mode === 'development') {
config.devServer = {
static: './public',
host: 'localhost',
// host: '192.168.0.242',
// host: '0.0.0.0',
port: 3008,
historyApiFallback: {
index: 'index.html' //다중 엔트리 이기 때문에 시작시 기본 사용할 페이지를 지정해 준다. 해당페이지는 http://localhost:3008/ 기본URL의 index page가 된다.
},
hot: true // 테스트 구동과 동시에 기본페이지가 오픈된다.
allowedHosts: ['domain'],
};
config.performance = {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
};
config.output = {
// publicPath: "/",
path: path.resolve(__dirname, './dist'),
filename: '[name].js'
};
}
return config;
};
- 주의
static : 테스트가 구동될때 기본으로 사용할 위치
구버전 contentBase가 static으로 변경
./public 폴더에 index.html이 있어야 구동됨.
template 속성에 값을 실제 파일이 있는 위치로 설정 해야함.
빌드 및 테스트 구동을 위해 아래 파일을 추가한다.
빌드시 사용할 template 페이지
template.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>
<body>
<div id="example"></div>
<!-- Dependencies -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<!-- Main -->
<script src="./main.bundle.js"></script>
</body>
</html>
테스트 구동시 사용할 index 페이지
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>
<body>
<div id="example"></div>
<!-- Dependencies -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<!-- Main -->
<script src="main.js"></script>
</body>
</html>
기본 설정은 모두 완료다
Hello World를 출력해 보자
아래 페이지를 작성한다.
index.jsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
ReactDOM.render(
<div>Hello World</div>,
document.getElementById('example')
);
빌드
npm run build // 빌드 ./dist 페이지에 빌드 파일이 생성된다.
or
npm run start // 테스트 구동 웹페이지가 자동으로 팝업된다.
by Kazel
Author And Source
이 문제에 관하여(React CRA를 이용하지 않고 프로젝트 생성(1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@arenacast/react-cra1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)