2부 React 아키택쳐

리액트 교과서 Chapter12(Webpack)

Webpack의 역할

자바스크립트를 작성을 하다보면 많은 js 파일을 생성하게 된다.
이러한 js 파일들을 적은 수의 js로 합쳐주며 이를 통해 js 요청의 횟수를 줄여준다.

또한 A.jsx와 B.jsx가 모두 Multiutil이라는 유틸리티 모듈을 사용 할 경우 중복하여 요청을 할 수 있다. 이러한 상황에서 Webpack의 도움을 받을 수 있다.

Webpack은 의존성을 분석하여 다음과 같은 작업을 진행한다.

  • 모든 의존 모듈을 올바른 순서로 불러오도록 한다.
  • 모든 의존 모듈을 한 번ㅆ기만 불러오도록 한다.
  • 자바스크립트 파일이 가능한 적은 파일로 묶여지도록 한다.(이를 정적자원이라고 부른다.)

그 외에도

  • JS, Jade, CoffeScript 파일을 js파일로 변환한다.
  • ES6 미지원 브라우저를 대응하기 위해 ES6+ 코드를 ES5 코드로 변환한다.
  • 스프라이트 이미지를 하나의 PNG 파일이나 JPG 파일 또는 인라인 데이터 URI 이미지로 최적화 한다.
  • npm 의존 모듈을 관리하고 번들링하여 일일이 인터넷에서 내려받거나 HTML의 script 태그를 추가하지 않아도 사용할 수 있도록 한다.
  • 핫 모듈 대체를 적용한다(?)
  • 개발용 웹 서버를 실행한다.

Webpack의 적용

  • Webpack: 번들로 도구
  • 로더: 스타일, CSS, 핫 모듈 대체, Babel, JSX 전처리기(style-loader, css-loader, react-hot-loader, babel-loader, babel-core, babel-preset-react)
  • Webpack 개발 서버: Express 기반의 서버로 HMR 기능을 사용할 수 있다.

$ npm init -y
$ npm i -D babel-loader css-loader react-hot-loader webpack webpack-dev-server html-webpack-plugin react-dom react babel/preset-react @babel/plugin-syntax-jsx babel/syntax-dynamic-import --force
$ npm install -D @webpack-cli/generators
$ npx webpack init --force

 

barbelrc

{
  "plugins": [],
  "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
  ]
}

 

 

js의 로드는 dom 이후에

<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Hello World</title>
</head>
<body>
  <div id="root"></div>
</body>
<script src="./main.js" crossorigin></script>
</html>

 

$ npm run serve

 


https://github.com/Kmmanki/react_note/tree/master/chapter12

 

react_note/chapter12 at master · Kmmanki/react_note

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

 

리액트 교과서 Chapter11(타이머)


// 시간 정보 timer 정보를 가지고 있는 wrapper 
class TimerWrapper extends React.Component {
  constructor(props) {
    super(props)
    this.state = {timeLeft : null, timer: null}
    this.startTimer = this.startTimer.bind(this)
  }

  // 타이머 시작, 타이머가 존재한다면 기존 타이머 제거
  // setInterval로 1초마다 시간이 줄어들도록
  startTimer(timeLeft){
    clearInterval(this.state.timer)
    let timer = setInterval(() => {
      var timeLeft = this.state.timeLeft - 1
      if (timeLeft <= 0) {
        clearInterval(this.state.timer)
      }
      this.setState({
        timeLeft :timeLeft
      })
      console.log("running")
    }, 1000);
    console.log("start")
    return this.setState({timeLeft: timeLeft , timer: timer})
  }

  // button에 startTimer와 각각 할당된 time 제공
  render() {
    return (
      <div>
        <h2>Timer</h2>
        <Button time="5" startTimer={this.startTimer}></Button>
        <Button time="10" startTimer={this.startTimer}></Button>
        <Button time="15" startTimer={this.startTimer}></Button>
        <Timer timeLeft={this.state.timeLeft}></Timer>
      </div>
    )
  }

}

// 제공된 time과 startTimer 사용
class Button extends React.Component {

  render() {
    return (
      <div>
        <button onClick={() => {this.props.startTimer(this.props.time)}}>{this.props.time}</button>
      </div>
    )
  }
}

// 상위로 wrapper로 부터 받은 시간을 표기 
class Timer extends React.Component {
  constructor(props) {
    super(props)
  }

  render(){
    return (
      <div>'
        <h2>{this.props.timeLeft}</h2>
      </div>
    )
  }
  
}


let timer = document.getElementById('timer')
let root = ReactDOM.createRoot(timer)

root.render(
  <TimerWrapper></TimerWrapper>
)

https://github.com/Kmmanki/react_note/tree/master/chapter11

 

GitHub - Kmmanki/react_note: 리액트 교과서 따라하기

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

 

리액트 교과서 Chapter10(툴팁 컴포넌트)

class Tooltip extends React.Component {
  constructor(props) {
    super(props)
    this.state = {opacity :false}
    this.toggle = this.toggle.bind(this)
  }
  // 토글 함수
  toggle() {
    const tooltipNode = ReactDOM.findDOMNode(this)
    this.setState({
      opacity: !this.state.opacity
    })
  }
  render() {
    // 토글 여부에 따른 스타일 변경
    const style = {
      "zIndex": this.state.opacity ? 1000 : -1000,
      "opacity": +this.state.opacity,
      "top": (this.state.top || 0) + 20,
      "left": (this.state.left || 0) - 30
  };
    return (
    <div style={{display: "inline"}}  >
    // 마우스 오버, 아웃 시 토글 함수 동작
      <span onMouseOver={this.toggle} onMouseOut={this.toggle} style={{color: 'blue'}}>{this.props.children}</span>
      <div style={style} >{this.props.text}</div>
    </div>
    )
  } 
}



let tooltip = document.getElementById('tooltip')
let root = ReactDOM.createRoot(tooltip)

root.render(
  <Tooltip text="The Book you're reading now">"React Quickly" </Tooltip>
)

 


 

 

 

빌드를 간편하게 하기위한 스크립트 정리

packge.json에 빌드 스크립트를 추가
npm build를 사용하여 jsx -> js로 변환한다.

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": ".\\node_modules\\.bin\\babel .\\jsx -d .\\js --extensions .jsx --copy-files -w"
  },

 

메뉴 컴포넌트 작성

menu.jsx

class Menu extends React.Component {

  render() {
    const menu = [ 'Home',
      'About',
      'Service',
      'Portfolio',
      'Contact us'
    ]
    return (
      <div>
        {menu.map((x, i) => {
          return <div key={i}>
            <Link label={x}></Link>
            <br></br>
          </div>
        })}
      </div>

    ) 
  }
}

 

Link 컴포넌트 작성

Link.jsx

class Link extends React.Component{
  render() {
    const url = '/' + this.props.label.toLowerCase().trim().replace(' ','-')
    return (
      <a href={url}>{this.props.label}</a>
    )
  }
}

 

script 작성

script.jsx

let menu = document.getElementById('menu')
let root = ReactDOM.createRoot(menu)

root.render(
  <Menu></Menu>
)

 

해당 컴포넌트들을 html에서 로드

/menu/index.html
만약 menu가 하나의 jsx에 작성되어 있다면 하나의 js만 불러와도 될듯.

    <script src="../js/components/menu/Menu.js" type="text/javascript"></script>
    <script src="../js/components/common/Link.js" type="text/javascript"></script>
    <script src="../js/components/script.js" type="text/javascript"></script>

 


https://github.com/Kmmanki/react_note/tree/master/chapter09

 

 

GitHub - Kmmanki/react_note: 리액트 교과서 따라하기

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

+ Recent posts