기본 세팅
어제 만든 webpack 환경 설정 을 바탕으로 아래 파일들을 복사해서 새로운 파일에 넣기!
1. package.josn
2. webpack.config.js
그리고 새로 아래의 파일들을 만들어 기본 코드 작성하기
3. index.html
4. index.jsx
index.html
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="./dist/app.js"></script>
</body>
</html>
index.jsx (entry ----> output 은 App.js 로 설정 - 개발 환경에서는 dist / App.js 가 보이지는 않지만 돌아가고 있음!)
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return (
<>
Hi !
</>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
5. 현재 터미널의 위치 잘 체크 !! 해당 위치로 이동
6. 아래 명령어로 package.json에 있는 라이브러리들 한번에 install
$npm install
아래와 같은 오류가 나는 경우
C:\Users\saeee_z18xmwt\OneDrive\문서\react_first_lesson0628\0706webpack\0706header_practice>npm i npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: 0705webpack@1.0.0 npm ERR! Found: react-refresh@0.10.0 npm ERR! node_modules/react-refresh npm ERR! dev react-refresh@"^0.10.0" from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer react-refresh@">=0.8.3 <0.10.0" from @pmmmwh/react-refresh-webpack-plugin@0.4.3 npm ERR! node_modules/@pmmmwh/react-refresh-webpack-plugin npm ERR! dev @pmmmwh/react-refresh-webpack-plugin@"^0.4.3" from the root project npm ERR! npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. npm ERR! npm ERR! See C:\Users\saeee_z18xmwt\AppData\Local\npm-cache\eresolve-report.txt for a full report. npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\saeee_z18xmwt\AppData\Local\npm-cache\_logs\2021-07-06T06_44_42_704Z-debug.log
아래 명령어 실행
$ npm install -D @pmmmwh/react-refresh-webpack-plugin --save --legacy-peer-deps
또 안되면 아래 명령어 실행
$ npm install webpack -D
7. webpack 실행하기
npm run dev
<- 잘 나온다 !
위 명령어는 package.json 에서 설정해주었기 때문 !
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack server --env development"
},
npx webpack은 이제 명령어 실행이 안됨 !
기본 세팅 끝
웹팩 개발 환경 구축 후, 이제 Components를 여러개 만들어서 연결시켜보기 ! + CSS
index 최상단 부모 (using ReactDOM) <- App 연결 <- FuncComp & ClassComp 연결 시키기
App, FuncComp, ClassComp 모두 모듈로 뺄 것 -> 총 4개의 파일로 쪼개진다.
App은 ul tag로 , App에 연결할 Func, ClassComp는 li tag 로 !
1. 아래와 같은 폴더/파일 트리 만들기
2. index.jsx 에 App 연결
index.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from './App' // App 불러오기
ReactDOM.render(
<App />,
document.querySelector('#root')
)
App.jsx
import React, {Component} from 'react';
class App extends Component {
render() {
return (
<ul>
<h2>Hi !</h2>
</ul>
)
}
}
export default App
3. App.jsx 에 ClassComp, FuncComp 연결하기
ClassComp.jsx
import React, {Component} from 'react';
class ClassComp extends React.Component{
render(){
return(
<li className="funccomp">
I am ClassComp covered by 'li' tag
</li>
)
}
}
export default ClassComp
FuncComp.jsx
import React from 'react';
const FuncComp=()=>{
return (
<>
<li className="classcomp">I am FuncComp1 covered by 'li' tag</li>
<li className="classcomp">I am FuncComp2 covered by 'li' tag</li>
</>
)
}
export default FuncComp
App.jsx 에서 위의 components 불러와서 사용하기
import React, { Component } from 'react';
import ClassComp from './components/ClassComp'
import FuncComp from './components/FuncComp'
class App extends Component {
render() {
return (
<>
<h2>Hi !</h2>
<ul className="comp">
<ClassComp />
<FuncComp />
<ClassComp />
<FuncComp />
</ul>
</>
)
}
}
export default App
$ npm run dev -> http:localhost:8000 가면
* className은 미리 넣음
위의 중간 완성본에 CSS 연결하기
CSS 연결은 두 가지 방법이 있다.
첫 번째 방법 : 웹페이지에서 만드는 방식
1. css 폴더 > index.css 파일 만들기
2. html 에 css 연결
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<link rel="stylesheet" href="./css/index.css"> // css 연결
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="./dist/app.js"></script>
</body>
</html>
3. css 코드 작성
index.css
*{ margin:0; padding:0;}
ul,li{
list-style:none;
padding:5px;
margin:5px;
}
ul{
text-align: center;
}
h2{
text-align: center;
}
body{
background-color: cadetblue;
color: black;
}
.comp{
border:2px solid white;
}
.classcomp{
border:2px solid red;
}
.funccomp{
border:2px solid blue;
}
두 번째 방법 : 웹팩을 이용해서 만드는 방법
웹팩을 이용해서 만드는 방법도 두 가지이다.
1) 하나의 css마다 style tag 도 한 개씩 추가하는 방법
2) 모든 css를 하나의 style tag 로 합쳐서 추가하는 방법
1) 하나의 css마다 style tag 도 한 개씩 추가하는 방법
1. 서버를 끄고 html의 css 연결된 코드 한줄 삭제 & 아래 명령어 실행
$ npm i -D css-loader // react 파일에서 css 불러오는 능력 有 (react page에서 import css 코드 가능하게함)
$ npm i -D style-loader // css-loader가 가지고 온걸 style tag로 감싸는 아이
$ npm i -D mini-css-extract-plugin // 여러개의 css 들을 하나로 합치기 -> style 하나만 head에 추가되도록
2. webpack.config.js 수정
rules의 두 번째 요소 {} 객체 추가, 객체 안에는 test, use 사용
const path = require('path')
const webpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = { //module.exports부터 무조건 쓰기 !
name:'firstWebpack', //webpack의 이름 / 안적어도 된다.
mode:'development', //어떤 용도로 개발을 할 것이냐
devtool:'eval', // eval -> 개발용 , hidden-source-map -> 배포용
resolve:{
extensions:['.js', '.jsx']
},
entry:{
app:['./index.jsx']
},
// module을 통해 babel or sth 통해 해석해야하는구나 알도록 설정
// 외부파일 가져와서 읽을 때 사용하는
// babel은 js 뿐만 아니라 다른 파일도 읽을 수 있음 -> 규칙 정해주기
module:{
rules:[{
test:/\.jsx?$/, //확장자 .js / .jsx 가능하게
loader:'babel-loader', // webpack - babel 이해해주는 아이
// babel 내용 바꾸고 싶을 때 ex) plugin, preset..
options:{
presets:[
['@babel/preset-env', {
targets:{
browsers:['>5% in KR','last 2 chrome versions']
},
debug:true,
}],
'@babel/preset-react'
],
plugins:[
'react-refresh/babel'
]
}
},{
test:/\.css$/, //수정 111
//js에서 css파일 읽어서 어떻게 작동시킬지 적기
//뒤에 있는 css-loader부터 실행 -> style-loader 실행
//style-loader는 css-loader 없이 사용이 안됨!
use:['style-loader,'css-loader']
}]
},
plugins:[
new webpackPlugin(),
new webpack.LoaderOptionsPlugin({debug:true}),
],
output:{
path:path.join(__dirname,'dist'),
filename:'app.js',
//정적 파일로 바꾼다.
publicPath:'/dist'
},
// 실행할 때
devServer:{
publicPath:'/dist',
hot:true, // hot reload
}
}
-
},{
test:/\.css$/, //수정 111
//js에서 css파일 읽어서 어떻게 작동시킬지 적기
//뒤에 있는 css-loader부터 실행 -> style-loader 실행
//style-loader는 css-loader 없이 사용이 안됨!
use:['style-loader,'css-loader']
}]
test: 정규식 사용
use: ['style-loader', 'css-loader']
1) css-loader가 먼저 실행되고
2) style-loader 가 두 번째로 실행됨 (style-loader는 css-loader가 꼭 필요 !)
3. index.jsx 에 import css
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import './css/index.css'
ReactDOM.render(
<App />,
document.querySelector('#root')
)
4. css의 funcComp & classComp 부분을 따로 나누어서 style 추가해보기
1) css > classComp.css / funcComp.css 생성
2) css 옮겨 담기 (해당 component에 적용할 부분만)
3) clasComponent / funcComponent 에 각각의 css import 하기
완성 ! 그런데 style이 추가한 만큼 나온다. 총 3개를 style tag 들을 한 개로 합쳐서 style 하나의 tag에 올려보기
2) 모든 css를 하나의 style tag 로 합쳐서 추가하는 방법
아까 npm 설치한 세 가지 명령 중 마지막 아래 명령이 여러개의 css를 하나의 style tag로 return 할 수 있게 만드는 것!
$ npm i -D mini-css-extract-plugin
1. webpack.config.js 수정
- 위에 설치한 내용 가져오기 + module>rules>두 번째 인자의 use의 첫번째 자리에 가져온 변수 안에 있는 loader입력
('style-loader'삭제하고 MiniCssExtractPlugin.loader 입력 )
- plugin에서 파일명 정해서 해당 매서드 실행 -> output 에서 지정한 경로 -> 절대경로 + dist 에 app.css 가 생긴다. (개발자 모드라 dist파일 / app.css / app.js 가 보이지않는다)
const path = require('path')
const webpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') //추가 1111
module.exports = { //module.exports부터 무조건 쓰기 !
name:'firstWebpack', //webpack의 이름 / 안적어도 된다.
mode:'development', //어떤 용도로 개발을 할 것이냐
devtool:'eval', // eval -> 개발용 , hidden-source-map -> 배포용
resolve:{
extensions:['.js', '.jsx']
},
entry:{
app:['./index.jsx']
},
// module을 통해 babel or sth 통해 해석해야하는구나 알도록 설정
// 외부파일 가져와서 읽을 때 사용하는
// babel은 js 뿐만 아니라 다른 파일도 읽을 수 있음 -> 규칙 정해주기
module:{
rules:[{
test:/\.jsx?$/, //확장자 .js / .jsx 가능하게
loader:'babel-loader', // webpack - babel 이해해주는 아이
// babel 내용 바꾸고 싶을 때 ex) plugin, preset..
options:{
presets:[
['@babel/preset-env', {
targets:{
browsers:['>5% in KR','last 2 chrome versions']
},
debug:true,
}],
'@babel/preset-react'
],
plugins:[
'react-refresh/babel'
]
}
},{
test:/\.css$/,
use:[MiniCssExtractPlugin,'css-loader'] ///// 수정 11111
}]
},
plugins:[
new webpackPlugin(),
new webpack.LoaderOptionsPlugin({debug:true}),
//() 매서드 실행시켜주기
// app.css 파일 명으로 만들어서 하나로 묶어 주겠다.
new MiniCssExtractPlugin({filename:'app.css'}) ///// 수정 222
// 그럼 아래에 output 경로로 css 가 생긴다.
],
output:{
path:path.join(__dirname,'dist'),
filename:'app.js',
//정적 파일로 바꾼다.
publicPath:'/dist'
},
// 실행할 때
devServer:{
publicPath:'/dist',
hot:true, // hot reload
}
}
실행시켜보기
2. 방금 만들어 낸 app.css를 index.html 에 추가
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<link rel="stylesheet" href="./dist/app.css"> //추가
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="./dist/app.js"></script>
</body>
</html>
CRA로 웹팩 환경 구출을 하게되면 위의 기능이 react 기술이라고 오해할 수도 있다 !
요건 웹팩의 능력(?)이다.
이제 위에서 연습해본 것들로 마지막 실습해보기 !
React, Webpack, CSS, 간단한 반응형까지 !
header 만들어보기
1. 웹팩 기본 개발환경 구축
- package.json / webpack.config.js 복사 + 다른 파일들 생성 (위의 파일트리대로!)
- terminal 현재 위치 조정
- npm install 진행 (오류나면 위에 나온대로 처리!)
$ npm install
2. index.jsx <- app.jsx 연결
index.jsx
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import App from './app'
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
app.jsx
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<>
hi I am App for heade-making
</>
)
}
}
export default App
$ npm run dev 로 연결 확인
3. Navbar.jsx 코드 작성 + App 과 연결하기
Navbar.jsx
import React, {Component} from 'react'
import '../css/navbar.css'
class Navbar extends Component{
render(){
return(
<ul>
<li>버튼1</li>
<li>버튼2</li>
</ul>
)
}
}
export default Navbar
app.jsx
import React, { Component } from 'react';
import Navbar from './component/Navbar'
class App extends Component {
render() {
return (
<>
<Navbar/>
</>
)
}
}
export default App
4. react-icons 미리 만들어진 아이콘 패키지 다운
$npm i react-icons
위의 아이콘들을 볼 수 있는 곳 !
https://react-icons.github.io/react-icons/
5. Navbar.jsx에 아이콘 적용해보기
import React, {Component} from 'react'
import '../css/navbar.css'
import {FaFacebook, FaInstagram, FaBeer} from 'react-icons/fa'
class Navbar extends Component{
render(){
return(
<ul>
<li><FaFacebook/></li>
<li><FaInstagram/></li>
<li><FaBeer> 한 쟌 </FaBeer></li>
</ul>
)
}
}
export default Navbar
6. Navbar state에 social 배열 추가 + map 사용하여 반복 return
(key 값은 id, url, icon 총 3가지)
import React, {Component} from 'react'
import '../css/navbar.css'
import {FaFacebook, FaInstagram, FaTwitter} from 'react-icons/fa'
class Navbar extends Component{
state={
social:[
{
id:1,
url:'https://www.twitter.com',
icon:<FaTwitter/>
},
{
id:2,
url:'https://www.facebook.com',
icon:<FaFacebook/>
},
{
id:3,
url:'https://www.instagram.com',
icon:<FaInstagram/>
},
]
}
render(){
return(
<ul>
<li><FaFacebook/></li>
<li><FaInstagram/></li>
<li><FaBeer></FaBeer>굳</li>
</ul>
)
}
}
export default Navbar
이제 요 위의 배열을 return에 map() 매서드를 통해 반복해서 return 하기
render() {
return (
<nav>
<div className="nav-center">
<ul className="social-icons">
{
this.state.social.map(item=>{
let {id, url, icon} = item
return(
<li key={id}>
<a href={url}>{icon}</a>
</li>
)
})
}
</ul>
</div>
</nav>
)
}
7. div 추가한 아래 li (text) 들을 다시 반복문으로 위와 동일하게 return 하기
import React, { Component } from 'react'
import '../css/navbar.css'
import { FaFacebook, FaInstagram, FaTwitter, FaBars } from 'react-icons/fa'
class Navbar extends Component {
state = {
social: [
{
id: 1,
url: 'https://www.twitter.com',
icon: <FaTwitter />
},
{
id: 2,
url: 'https://www.facebook.com',
icon: <FaFacebook />
},
{
id: 3,
url: 'https://www.instagram.com',
icon: <FaInstagram />
},
],
menu:[
{
id:1,
url:'/',
text:'coconut'
},
{
id:2,
url:'/',
text:'always'
},
{
id:3,
url:'/',
text:'great'
}
]
}
render() {
return (
<nav>
<div className="nav-center">
{/* logo */}
<div className="nav-header">
<h1 className="logo">LOGO</h1>
<button className="nav-toggle">
<FaBars/>
</button>
</div>
{/* navigation */}
<div className="links-container">
<ul className="links">
{
this.state.menu.map(v=>{
let {id, url, text} = v;
return(
<li key={id}>
<a href={url}>{text}</a>
</li>
)
})
}
</ul>
</div>
<ul className="social-icons">
{
this.state.social.map(item=>{
let {id, url, icon} = item
return(
<li key={id}>
<a href={url}>{icon}</a>
</li>
)
})
}
</ul>
</div>
</nav>
)
}
}
export default Navbar
8. css index.html / index.jsx 에 연결
index.html
webpack.config.js에서 MiniCssExtractPlugin <- 이걸 사용해서 모든 css 합쳐서 한 개의 style tag 로 될 수 있도록 app.css 라는 파일을 dist 에 저장해놓음 - 요걸 적기 !
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<link rel="stylesheet" href="./dist/app.css"> <!--연결 -->
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="./dist/app.js"></script>
</body>
</html>
index.jsx
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import App from './app'
import './css/index.css'
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
Narbar.jsx
import React, { Component } from 'react'
import '../css/navbar.css'
import { FaFacebook, FaInstagram, FaTwitter } from 'react-icons/fa'
i
class Navbar extends Component {
state = {
social: [
9. Navbar.jsx 에 FaBar (반응형 시 햄버거모양 버튼!) 추가 + button tag 추가
Navbar.jsx
import { FaFacebook, FaInstagram, FaTwitter, FaBars } from 'react-icons/fa'
{/* logo */}
<div className="nav-header">
<h1 className="logo">LOGO</h1>
<button className="nav-toggle">
<FaBars/>
</button>
</div>
10. css 작성
index.css
*{padding:0;margin:0;}
ul,li{list-style:none;}
a{ text-decoration:none;}
/* NavBar */
narbar.css
/* mobile */
.nav-header{
display:flex;
align-items: center;
justify-content: space-between; /* 양쪽 끝 */
padding:1rem;
}
.logo{
font-size: 3rem;
}
/* rem 확대 축소 비율로 늘어남 */
.links-container{
height:0;
overflow:hidden;
}
.social-icons{
height:0;
overflow:hidden;
}
.nav-toggle{
font-size:3rem;
/*투명하게 만들기 */
background:transparent;
border-color:transparent;
color:blue;
}
/* PC css style */
@media screen and (min-width:800px){
.logo{
font-size: 4rem;
}
.nav-toggle{
/*pc 경우에 토글 안보이게*/
font-size: 0px;
color:blue;
}
.nav-center{
max-width:1170px;
margin:0 auto;
display: flex;
align-items:center;
justify-content: space-between;
padding:1rem;
}
.links-container{
height:auto;
}
.links{
display: flex;
}
.links>li>a{
margin:0 0.5rem;
color:black;
font-size: 2rem;
}
.social-icons{
display:flex;
height:auto;
}
.social-icons>li>a{
margin: 0 .5rem;
color: darkcyan;
}
}
웹팩 + css + React + 반응형 실습 끄읕
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[81일차 복습] css 반응형 햄버거 (삼선) 메뉴 만들기 / 리액트 라우터 react-router-dom (1) | 2021.07.07 |
---|---|
[81일차]20210707 웹팩, 리액트 header 반응형, router 라우터, 경일 홈페이지 상담게시판 page 구현 (0) | 2021.07.07 |
[80일차] 20210706 React, Webpack, CSS 웹팩으로 Header 만들기 (0) | 2021.07.06 |
[79일차 복습] 웹팩 CRA 없이 React 개발 환경 구축 및 핫리로드 & CRA 사용버전 (0) | 2021.07.05 |
[79일차] 20210705 react Webpack 웹팩 수동으로 개발 환경 구축/ 핫리로드 / & CRA 사용버전 (0) | 2021.07.05 |