우연히 CRA로 프로젝트를 생성하고 작업을 하려고 하는데
'과연 실무에서도 CRA를 사용할까?'라는 생각이 들었다.
CRA없이 리액트 설정을 해보잡
🦖 작성해두면 나중에 어느 곳에서도 동일한 개발 환경을 만들 수 있다 🦖
npm init -y
초기 설정이 포함된 package.json을 만들어준다
{
"name": "without-cra",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
그러면 내가 많이 본 package.json이 나온다
npm i react react-dom
react-dom : 가상 DOM을 실제 DOM에 렌더링 하는 역할
{
"name": "without-cra",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": { // 여기는 애플리케이션이랑 직접적으로 연관된 애들
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
// devDependencies는 개발할 때 필요한 애들만 설치 (typescript처럼)
without-cra
┣ public
┃ ┗ index.html
┗ src
┣ App.jsx
┗ index.jsx
src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
src/App.jsx
const App = () => {
return <div>안녕</div>
}
export default App
public/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>without-cra</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
npm install -D webpack webpack-dev-server webpack-cli
webpack-cli: 웹팩 명령어 사용 가능
webpack-dev-server: 실시간 개발 서버 환경
"scripts": {
"build": "webpack",
"start": "webpack serve",
},
기본적으로 webpack은 설정 파일을 사용할 필요가 없습니다. webpack은 프로젝트의 엔트리 포인트를 src/index.js으로 가정하고, 프로덕션을 위해 압축하고 최적화된 결과를 dist/main.js로 내보냅니다.
(설정 파일이 없으면 기본 설정으로 번들링을 함)
필요가 없다고 하니 npm run build
모드를 알려달라 하고, jsx를 모른다고 한다
기본적으로 webpack은 JavaScript 및 JSON 파일만 이해한다
그렇다면 나중에 추가되거나 변경되는 부분이 있으면 에러를 보낼 것이기 때문에
미리 진입점, 결과물 위치, 플러그인, loader 등등 알려주는 것
이 설정 파일도 작성해 두면 동일한 개발 환경 구축 가능
(이래서 설정 파일이 중요한가 보다)
// Node.js에서 제공하는 내장 모듈인 path 모듈을 가져오는 것, 파일 경로를 조작하고 다룰 수 있도록 도와줌
const path = require('path')
module.exports = {
// 진입점
entry: './src/index.jsx',
// webpack을 실행한 후의 결과물
output:
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
// __dirname : 절대 경로로 표현되며, 파일의 전체 경로에서 파일 이름을 제외한 디렉토리 경로를 나타냄
},
}
아까 jsx모른다고 했으니까 알아들을 수 있게 해줘야 하는데 그 기능을 하는 게
자바스크립트의 코드를 구버전에 맞게끔 변환시켜 주는 역할을 한다 = 트랜스파일링
npm i -D @babel/core @babel/cli @babel/preset-env @babel/preset-react
@babel/cli : 바벨 명령어 사용 가능
@babel/core : 이름은 core인데 하는 일은 파싱이랑 출력 담당
변환은 프리셋들이 한다
@babel/preset-env : 대상 환경에 필요한 구문 변환(및 선택적으로 브라우저 폴리필)
@babel/preset-react : jsx 문법을 변환하고 React의 추가 기능을 지원
npx babel --presets @babel/preset-react src/index.jsx --out-file result.js
"바벨아 preset-react를 이용해 index.jsx를 트랜스파일링 해서 result.js파일로 만들어줘"
// result.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( /*#__PURE__*/React.createElement(React.StrictMode, null, /*#__PURE__*/React.createElement(App, null)));
이제 jsx가 뭔지 알려줬으니까 webpack build를 해보면?
Module not found: Error: Can't resolve './App.jsx'
아앗
Module parse failed: Unexpected token (2:9)
You may need an appropriate loader to handle this file type,
currently no loaders are configured to process this file.
See https://webpack.js.org/concepts#loaders
| const App = () => {
> return <div>안녕</div>
| }
jsx확장자, App.jsx안에 있는 jsx문법을 이해하지 못한다
그렇다면 일일이 파일마다 트랜스파일링 하고 난 뒤에 webpack을 돌려야 한다는 말이 자네?
이 과정을 손쉽게 하기 위해서
Webpack이 Babel을 사용할 수 있게 해주는
babel-loader를 설치하는 것이다
npm i -D babel-loader
webpack설정 파일에서 프리셋 설정을 해두면 따로 babel설정 파일 없어도 된다
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
},
},
},
],
}
}
"웹팩아 번들링 할 때 test에다가 지정한 파일 형식을 만나면
use에 지정한 loader로 변환해 줘야 돼, 그리고 node_modules 폴더는 빼줘"
설정을 안 해도 데브 서버 시작 가능
npm run start
아아아아아 너무 빨게 아아아아아아아아아아아아아아
React17부터는 import React from 'react'를 쓰지 않아도 되는데
{ runtime: 'automatic' } 이렇게 설정을 해줘야
React의 JSX에서 React를 실제로 import 해오지 않더라도 자동으로 해석해준다
babel-preset-react#options
아니면 일일이 React를 import하는 방법도 있다 ㅎㅎ
module: {
rules: [
{
test: /\.(js|jsx)?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }],
],
},
},
},
],
},
이제는 나오겠지...ㅠ
사랑해요 stackoverflow
output: {
publicPath: '/dist',
},
설명 조금 더 붙이자면 publicPath를 설정하면
웹팩은 해당 경로를 사용하여 번들된 파일에 대한 URL을 생성하고
이 URL은 웹 애플리케이션에서 번들된 파일을 로드할 때 사용된다고 한다
드디어 에러 없이 화면이 나온다!!
번외
다른분 글인데 이것 저것 유용한 내용이 많았다.
[CodeStates-Section4]U3.React-번들링과 웹팩