Webpack 이란 ?
웹팩 개념을 위함 자세한 포스팅 ↓↓
https://blckchainetc.tistory.com/253
여러개의 JS를 하나의 JS로 만들기
Component 별로 파일을 쪼개놓고 (코드를 짤 때, 협업할 때 필수) 그리고 실제로 빌드해서 배포할 때는 한 파일로 만들 때 Webpack을 쓴다.
Node.js 환경에서 돌아간다. 웹팩을하기 위해 코드까지 짤 필요는 없지만 설정해야하는 것이 많다. 웹팩을 실행하기 위해서는 하나의 JS 파일이 필요하다. Json 형태로 된 변수가 엄청 많다. 환경설정하는게 코드 짤 때보다 힘들 수도 있다.
예시 1)
맨처음 let a = 10
그 다음 외부 파일에 let a = 0
그 다음 console.log(a)
JS 같은 경우 모듈시스템이 잘 되어 있지않음
어떻게 해야 변수가 꼬이지 않을가,,, --- Webpack 출현 ---> webpack에 보내면 위의 코드 둘 다 쓸 수 있도록 변환을 해줌. 코드가 꼬임이 없게 해줌 ! 변환을 해줄 때 모든 브라우저에서 실행이 가능한 코드로 바꿔 준다.
하나의 파일로 묶어준다. (여러 파일로 쪼갤 수 있도록 해준다.)
Webpack 환경설정
1. cd webpack 까지 들어오기
2. 들어온 상태에서 terminal명령 실행
$npm init
3. react 아래 환경 설정
$npm install react
$npm intstall react-dom
4. 이제 앞으로 사용할 webpack 설치
$npm install -D webpack
-D = 개발 용도 (실제 배포 때는 사용하지 않는다 라는 의미)
웹팩은 결국 하나의 파일로 만드는 것 ! -> 굳이 실 서버에 쓸 이유는 없다. 개발의 도구일뿐 !
5. webpack cli설치
$npm install -D webpack-cli
packages.json 에 설치된 것 확인하기
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"webpack": "^5.42.0",
"webpack-cli": "^4.7.2"
}
}
webpack / webpack-cli는 devDependencies 가 있음 !
6. 파일 webpack.config.js 만들기
-> webpack 아이콘 나타남
* 이름 'webpack.config.js' 로 !
7. webpack.config.js 작성
Entry : 내가 가져올 파일들을 설정하는 값
합칠 파일들을 가리키는 내용 적기 - 복수이기 때문에 배열형태로 webpack이 읽을 파일들 알려주기
// 입력받을 내용들
entry:{
app:['./index.jsx']
},
Output : 내가 위의 파일들을 어떻게 내보낼 것인지
경로와 파일명을 적기 - path는 절대경로를 가져오는게 좋다고 함. -> path 를 사용하기
const path = require('path')
path = node.js 기본적으로 가지고 있기 때문에 설치가 필요 없다.
// 내보낼 내용들
// 현재 디렉토리 + dist까지
output:{
path:path.join(__dirname,'dist'),
filename:'app.js'
}
전체
const path = require('path')
module.exports = { //module.exports부터 무조건 쓰기 !
name:'firstWebpack', //webpack의 이름 / 안적어도 된다.
mode:'development', //어떤 용도로 개발을 할 것이냐
// development -> 개발용
// production -> 배포 용!
devtool:'eval',
// eval -> 개발용
// hidden-source-map -> 배포용
// 입력받을 내용들
entry:{
app:['./index.jsx']
},
// 내보낼 내용들
// 현재 디렉토리 + dist까지
output:{
path:path.join(__dirname,'dist'),
filename:'app.js'
}
}
8. index.html / index.jsx 새로 만들기
0705webpack - 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>
jsx - JS 파일인데 x을 달아줌 - > '아 리액트 컴포넌트 파일이구나' 구별할 수 있음 가독성의 차이일 뿐 / 기능이 다른게 아니다.
0705webpack - index.jsx
--> 웹팩이 해석해서 다른 파일로 만들 것이야
const React = require('react') // CRA 에서 import ~ 하는 경우가 있음
const ReactDOM = require('react-dom')
class App extends React.Component{
render(){
return(
<div>Hello Webpack !</div>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
9. webpack 실행시키기
webpack.config.js 실행시켜서 index.html 파일을 바꾸ㅓ주는 것
$ webpack
-> 윈도우 환경의 경우에는 에러가 난다.
첫 번째 방법 : package.json 파일에서 아래 scripts에 설정값 정하고
$npm run dev
{
"name": "0705webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
// 아래 추가해주기
"dev":"webpack"
//npm script 명령어 미리 설정
//npm run dev 라고 실행하면 dev 의 webpack이 실행되게
},
"author": "",
"license": "ISC",
두 번째 방법 :
$npx webpack
--> 두 방법 다 에러가 나옴,,
JS 읽는 능력치를 올려줘야함
webpack도 바벨 babel 이 있어야 사용이 가능하다 !
만약 babel을 사용 전인 React 아래 코드로 한 후
const React = require('react') // CRA 에서 import ~ 하는 경우가 있음
const ReactDOM = require('react-dom')
class App extends React.Component{
render(){
return(
React.createElement('div',null,'Hello webpack')
)
}
}
ReactDOM.render(
React.createElement(App),
document.querySelector('#root')
)
$ npm run dev 를 해보기 -> 오류없이 잘 됨 !
dist 폴더 - app.js 파일이 생김
index.html 실행시켜보기
* build - 있던 코드를 다른 코드로 바꾸는 것
10. webpack에 babel 세팅해주기
webpack이 babel도 해석해 줄 수 있도록 ! - 환경설정이 생각보다 많이 길다.
첫 번째 - bable의 기본적인 core 내용을 담고 있는
두 번째 - 브라우저에 맞게 최신문법을 옛날 문법으로 바꾸기
세 번째 - React에 필요한 babel을 설치하기
네 번째 - babel & webpack 연결해줄 때
$npm install -D @babel/core
$npm install -D @babel/preset-env
$npm install -D @babel/preset-react
$npm install -D babel-loader
* 실무에서는 더 설치 필요한 경우도 있음
11. webpack.config.js 추가
// module을 통해 babel or sth 통해 해석해야하는구나 알도록 설정
// 외부파일 가져와서 읽을 때 사용하는
// babel은 js 뿐만 아니라 다른 파일도 읽을 수 있음 -> 규칙 정해주기
module:{
rules:[{
//확장자가 .jsx 이냐 .js이냐 - 적합하면 실행하겟다.
test:/\.jsx?$/,
loader:'babel-loader', // webpack - babel 이해해주는 아이
// babel 내용 바꾸고 싶을 때 ex) plugin, preset..
options:{
preset:[
'@babel/preset-env',
'@babel/preset-react'
]
}
}]
},
---> 되는지 test
index.jsx 다시 babel로 수정
const React = require('react') // CRA 에서 import ~ 하는 경우가 있음
const ReactDOM = require('react-dom')
class App extends React.Component {
render() {
return (
<div> Hello babel! </div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
-> $ npm run dev
-> presets로 변경
JSX 파일 BUILD 완료 ---> app.js 파일로 변환됨
* html 에 <script type="text/javascript"> 인 이유 ( "text/babel" 이 아닌 이유)
이미 webpack에서 babel의 --> 일반 js로 만들었기 때문에 build할 떄 babel의 내용 해석해서 보냈기 때문
- 이미 webpack이 babel을 다 읽고 처리해서 보내줬기 때문
components가 2만개야 그럼.. -> 그럼 넘 힘들 -> 최소화해주는게 webpack
12. components module화 해서 사용하기
loginBox.jsx 생성 & 아래 내용 붙여넣기
class LoginBox extends React.Component{
state={
userid:'',
userpw:''
}
handleChange = (e) =>{
this.setState({[e.target.name]:e.target.value})
}
letsubmit = (e) =>{
console.log(e)
e.preventDefault()
this.props.onCreate(this.state)
}
render(){
return(
<form onSubmit={this.letsubmit}>
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
onChange = {this.handleChange}
/>
<input
type="password"
placeholder="비번 입력해주세요"
value={this.state.userpw}
name="userpw"
onChange = {this.handleChange}
/>
<button type="submit">로그인</button>
</form>
)
}
}
webpack에서 react 처리한다고 설정 안했기 때문에 아래 내용 추가
const React = require('react')
class LoginBox extends React.Component{
state={
userid:'',
마지막에 module.exports = Class 명
module.exports = LoginBox
이제 요 파일은 require로 보낼 수 있는 파일이 됨
전체 코드
const React = require('react')
class LoginBox extends React.Component{
state={
userid:'',
userpw:''
}
handleChange = (e) =>{
this.setState({[e.target.name]:e.target.value})
}
letsubmit = (e) =>{
console.log(e)
e.preventDefault()
this.props.onCreate(this.state)
}
render(){
return(
<form onSubmit={this.letsubmit}>
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
onChange = {this.handleChange}
/>
<input
type="password"
placeholder="비번 입력해주세요"
value={this.state.userpw}
name="userpw"
onChange = {this.handleChange}
/>
<button type="submit">로그인</button>
</form>
)
}
}
module.exports = LoginBox
13. index.jsx에서 LoginBox 불러오기
index.jsx
const React = require('react') // CRA 에서 import ~ 하는 경우가 있음
const ReactDOM = require('react-dom')
const LoginBox = require('./loginBox.jsx') //추가
class App extends React.Component {
render() {
return (
<>
<div> Hello babel! </div>
<LoginBox /> // 변경
</>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
terminal 명령
$npm run dev
or
$npx webpack (package.json에서 설정안했다면)
브라우저 확인
오우.... 연결되엇당.. 신기하군,,
모듈화의 장점
-> 하나의 component 씩 만들어서 위처럼 끼워 넣기 -> 협업이 좀 더 쉬워짐 ! 간결
-> sub page의 경우 또 한 component를 재사용해야할 때 편함 !
1. 아래 내용을 import 사용해서 바꾸기
webpack과 함께 있을 때만 import 구문이 사용된다.
webpack.config.js 같은 경우 안되고 아래 index.jsx 가 됨
index.jsx
const React = require('react') // CRA 에서 import ~ 하는 경우가 있음
// react 객체를 담아 사용하겠다.
// react안에는 component가 있다. 그래서 아래에 저렇게 사용 가능
// 비구조 할당문 {Component} = React 로 만들어서 아래 React제거 가능
const ReactDOM = require('react-dom')
const LoginBox = require('./loginBox.jsx')
// require - node .js 에서 노드 구문
// import - js 버전 업그레이드되며 생김 (nodex.js 에서 X )
// import & require 둘 다 가능 import가 최근 추세
아래처럼 변경 가능
const React = require('react')
const Component = React
const ReactDOM = require('react-dom')
const LoginBox = require('./loginBox.jsx')
// import 의 장점 변수 두가지 설정 가능
// import는 babel이 한 번 읽고 처리됨 (require는 node.js가 )
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import LoginBox from './loginBox.jsx'
2. 확장자가 반드시 있어야하는 이유 (위의 코드에서 LoginBox에 .jsx 없으면 오류!)
-> webpack에 확장자 설정해주기
webpack.config.js
devtool:'eval',
// eval -> 개발용
// hidden-source-map -> 배포용
resolve:{
extensions:['.js', '.jsx'] // 추가 --- 복수일 때 보통 s를 붙임
},
// 입력받을 내용들
entry:{
app:['./index.jsx']
},
index.jsx
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import LoginBox from './loginBox' //확장자 없애보기
실행
$npm run dev or $npx webpack
3. 핫 로드 (build를 다시 하지 않아도 실시간 ** 으로 처리해주는 것 설정)
== 자동으로 build 해주는 세팅
webpack에 test 서버 하나 만들어서 구동시키기
코드가 변경될 때마다 서버를 알아서 restart 해주면서 코드의 내용을 바로 보여주기
$ npm install -D react-refresh
$ npm install -D @pmmmwh/react-refresh-webpack-plugin
$ npm install -D webpack-dev-server
첫 번째, 두 번째 - react 코드 변경 시 refresh
webpack-dev-server : express로 구현되어 있는 webpack 세팅을 다 해놓은 것
pmmmwh 오류날 경우 아래 코드 입력
$ npm install -D @pmmmwh/react-refresh-webpack-plugin --save --legacy-peer-deps
4. index.jsx 실행될 때 무조건 실행될 plugin 설정 webpack
webpack.config.js에 다운받은 내용 가지고 오기
output 전에 가져왔던 plugin 달아주기
module 부분에 담기
webpack.config.js
const webpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin') //추가
첫 번째 코드에 대한 설정
options:{
presets:[
'@babel/preset-env',
'@babel/preset-react'
],
plugins:[
'react-refresh/bable'
]
}
두 번째 코드에 대한 설정
//webpack이 구동이 될 때 아래 plugins를 무조건 실행하겠다.
plugins:[
new webpackPlugin()
],
세 번째 코드에 대한 설정
// 내보낼 내용들
// 현재 디렉토리 + dist까지
output:{
path:path.join(__dirname,'dist'),
filename:'app.js',
//정적 파일로 바꾼다.
publicPath:'/dist'
},
// 실행할 때
devServer:{
publicPath:'/dist',
hot:true, // hot reload
}
}
package.json 파일 아래 dev 변경
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack server --env development"
},
webpack - webserver로 구동해서 돌리기
web server -코드가 바뀔 때마다 파일을 다시 읽어서 build 해줌
$npm run dev 실행 -> http://localhost:8080/ 로 들어가면 내용이 뜸 --> 실시간 수정을 보여준다.
장점 : --> 실시간으로 바뀜 / 디버깅하기 훨씬 쉽다 ! ex) 로그인하고 코드 코치고 새로고침하면 -> 다시 재로그인할 필요가 없다 ! --> 웹팩의 능력
preset-env - 옛날 문법을 최신 버젼으로 바꿔줌
더 자세히 정해줄 수 있음 ! ~을 제외하겠다. or 대한민국 점유율 5% 이상의 브라우저만 설정하겠다 등등..
https://github.com/browserslist/browserslist
webpack.config.js
// module을 통해 babel or sth 통해 해석해야하는구나 알도록 설정
// 외부파일 가져와서 읽을 때 사용하는
// babel은 js 뿐만 아니라 다른 파일도 읽을 수 있음 -> 규칙 정해주기
module:{
rules:[{
//확장자가 .jsx 이냐 .js이냐 - 적합하면 실행하겟다.
test:/\.jsx?$/,
//js 실행할 때 babel 쓸꺼야 !
loader:'babel-loader', // webpack - babel 이해해주는 아이
// babel 내용 바꾸고 싶을 때 ex) plugin, preset..
options:{
presets:[
['@babel/preset-env', {
targets:{
//여기에 link 에 나온 내용들 넣어주기
browsers:['>5% in KR','last 2 chrome versions']
},
debug:true,
}],
'@babel/preset-react'
],
plugins:[
'react-refresh/babel'
]
}
}]
},
-> webpack 실행
$npm run dev
options안 debug를 전체 실행되도록 만들기
//webpack이 구동이 될 때 아래 plugins를 무조건 실행하겠다.
plugins:[
new webpackPlugin(),
new webpack.LoaderOptionsPlugin({debug:true})
],
위에서 loader == module 안에서 option에 있는plugin을 모두 debug : true 해주겠다.
맨 위에 webpack 추가
const path = require('path')
const webpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const webpack = require('webpack') //추가
전체 코드
const path = require('path')
const webpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin') //추가
const webpack = require('webpack')
module.exports = { //module.exports부터 무조건 쓰기 !
name:'firstWebpack', //webpack의 이름 / 안적어도 된다.
mode:'development', //어떤 용도로 개발을 할 것이냐
// development -> 개발용
// production -> 배포 용!
devtool:'eval',
// eval -> 개발용
// hidden-source-map -> 배포용
resolve:{
extensions:['.js', '.jsx']
},
// 입력받을 내용들
entry:{
app:['./index.jsx']
},
// module을 통해 babel or sth 통해 해석해야하는구나 알도록 설정
// 외부파일 가져와서 읽을 때 사용하는
// babel은 js 뿐만 아니라 다른 파일도 읽을 수 있음 -> 규칙 정해주기
module:{
rules:[{
//확장자가 .jsx 이냐 .js이냐 - 적합하면 실행하겟다.
test:/\.jsx?$/,
//js 실행할 때 babel 쓸꺼야 !
loader:'babel-loader', // webpack - babel 이해해주는 아이
// babel 내용 바꾸고 싶을 때 ex) plugin, preset..
options:{
presets:[
['@babel/preset-env', {
targets:{
//여기에 link 에 나온 내용들 넣어주기
browsers:['>5% in KR','last 2 chrome versions']
},
debug:true,
}],
'@babel/preset-react'
],
plugins:[
'react-refresh/babel'
]
}
}]
},
//webpack이 구동이 될 때 아래 plugins를 무조건 실행하겠다.
plugins:[
new webpackPlugin(),
new webpack.LoaderOptionsPlugin({debug:true})
],
// 내보낼 내용들
// 현재 디렉토리 + dist까지
output:{
path:path.join(__dirname,'dist'),
filename:'app.js',
//정적 파일로 바꾼다.
publicPath:'/dist'
},
// 실행할 때
devServer:{
publicPath:'/dist',
hot:true, // hot reload
}
}
React 환경 구성하기 CRM
1. cd.. 한 번 나가기
2. 아래 명령어 실행
$ npm install -g create-react-app
- g = global
$npx create-react-app reactsample
reactApp -> 내가 생성한 폴더 명 / 폴더 명은 대문자 쓰면 안됨
cd reactsample 들어가기
실행할 때는 npm start 로 !
package.json 들어가보면 아까 본 익숙한 것들이 보임
"browserslist": {
"production": [ //배포용
">0.2%",
"not dead",
"not op_mini all"
],
"development": [ //개발용
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
$npm start
-> 안에 있던 react page 가 실행됨 (in src)
-> 수정하면 바로바로 실시간으로 뜬다 !
reactsample 구조를 잘 살펴보기 !
위에서 직접 설정한 내용과 완벽히 똑같지 않지만... 큰 틀은 대강 비슷하다.
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[80일차] 20210706 React, Webpack, CSS 웹팩으로 Header 만들기 (0) | 2021.07.06 |
---|---|
[79일차 복습] 웹팩 CRA 없이 React 개발 환경 구축 및 핫리로드 & CRA 사용버전 (0) | 2021.07.05 |
[Webpack] 웹팩이란 ? 웹팩 사용 전, 알아야할 기본 개념 6가지 (0) | 2021.07.05 |
[78일차 복습] React, 리액트 함수형 컴포넌트 vs 클래스 컴포넌트 (0) | 2021.07.02 |
3주 팀프로젝트 리뷰 (0) | 2021.07.02 |