React Basic - 11. webpack plugins, 끝말잇기, react refresh

Bloooooooooooooog..·2023년 7월 7일
0

module.exports = {

    name: 'wordrelay-setting', // 설정의 이름
    mode : 'development', // 개발용, 만약 실서비스용이면 : 'production'
    devtool : 'eval', // 빠르게 하겠다는 의미
    resolve : {
        extensions : ['.js', '.jsx'], // 자동으로 js와 jsx 파일을 찾아서 연결해준다.
    },
    entry : {
        app: ['./client'],

    }, // 입력 부분
    module : {
        rules : [{
            test: /\.jsx?/,
            loader : 'babel-loader',
            options : {
                presets: ['@babel/preset-env','@babel/preset-react']
            }
        }]
    }, // 모듈 입력
    output : {
        path : path.join(__dirname, 'dist'), // 현재 폴더 안의 dist 폴더를 말한다.
        filename : 'app.js'

    }, // 출력 부분
};

위와 같은 설정 파일에서 babel-loader의 presets는 @babel/preset-env와 @babel/preset-react가 있다.

만약 @babel/preset-env에서 설정을 지정할 때는 어떻게 해야할까
@babel/preset-env를 []배열로 감싸고, 이후 설정 정보를 적으면 된다.

               	presets: [
                    ['@babel/preset-env',{
                        targets : {
                            browsers: ['last 2 chrome versions']
                        }
                    }],'@babel/preset-react']

presets 부분은 위와 같이 쓸 수 있다.

끝말잇기 react

이전의 구구단과 큰 차이가 없기 때문에 빠르게 코드만 정리하겠다

WordRelay.jsx

const React = require('react');
const { Component } = React;

class WordRelay extends Component {
    state = {
        word : '김밥말이',
        value : '',
        result : '',
    };

    onSubmitForm = e =>{
        e.preventDefault();
        if(this.state.word[this.state.word.length-1] === this.state.value[0]){
            this.setState({
                word : this.state.value,
                result : '딩동뎅',
                value : '',
            });
            this.input.focus();    
        }else{
            this.setState({
                result : '떙',
                value : '',
                

            });
            this.input.focus();
        }
    };

    onChange = e =>{
        this.setState({ value : e.target.value})
    };

    input;

    onRefInput = c =>{
        this.input = c;
    }

    render(){
        return(
            <>
                <div>{this.state.word}</div>
                <form onSubmit = {this.onSubmitForm}>
                    <input ref={this.onRefInput} value={this.state.value} onChange={this.onChange}/>
                    <button>입력</button>    
                </form>
                <div>{this.state.result}</div>       
            </>
        );
    }
}

module.exports = WordRelay;

client.jsx

const React = require('react');
const ReactDom = require('react-dom/client');

const WordRelay = require('./WordRelay');


ReactDom.createRoot(document.querySelector('#root')).render(<WordRelay/>);

webpack.config.js는 이전과 동일

웹팩 데브 서버와 핫 리로딩

npm i react-refresh @pmmmwh/react-refresh-webpack-plugin -D
npm i -D webpack-dev-server

핫 리로딩용 플러그인와 개발용 웹팩 서버도 다운받아준다.
package.json에 있는 script 부분에 아래와 같이 추가해준다.

  "scripts": {
    "dev" : "webpack serve --env development"
  },

이후 webpack.config.js에서 아래와 같이 불러와준다.

const refresh = require('@pmmmwh/react-refresh-webpack-plugin');

....
....

//plugin 내부에 아래와 같이 사용해준다.
    plugins:[
        new refresh()
    ],

이후 babel-loader의 내부 플러그인에도 아래와 같이 플러그인을 넣어준다

            plugins :[
                '@babel/plugin-proposal-class-properties',
                'react-refresh/babel',
            ],

또한 아까 다운받은 개발용 서버를 넣어준다.

    devServer: {
        devMiddleware: {
            publicPath : '/dist'
        },
        static:{
            directory : path.resolve(__dirname)
        },
        hot : true,

    },

이렇게 되면 총 아래와 같은 코드가 된다.
webpack.config.js

const path = require('path');
// node의 경로 설정을 돕는 도구
const webpack = require('webpack');
const refresh = require('@pmmmwh/react-refresh-webpack-plugin');

module.exports = {

    name: 'wordrelay-setting', // 설정의 이름
    mode : 'development', // 개발용, 만약 실서비스용이면 : 'production'
    devtool : 'eval', // 빠르게 하겠다는 의미
    resolve : {
        extensions : ['.js', '.jsx'], // 자동으로 js와 jsx 파일을 찾아서 연결해준다.
    },
    entry : {
        app: ['./client'],

    }, // 입력 부분
    module : {
        rules : [{
            test: /\.jsx?/,
            loader : 'babel-loader',
            options : {
                presets: [
                    ['@babel/preset-env',{
                        targets : {
                            browsers: ['> 5% in KR','last 2 chrome versions']
                        }
                    }],
                    '@babel/preset-react'
                ],
            plugins :[
                '@babel/plugin-proposal-class-properties',
                'react-refresh/babel',
            ],
            },
        }],
    }, // 모듈 입력
    plugins:[
        new webpack.LoaderOptionsPlugin({ debug: true }),
        new refresh()
    ],
    output : {
        path : path.join(__dirname, 'dist'), // 현재 폴더 안의 dist 폴더를 말한다.
        filename : 'app.js',
        publicPath: '/dist',
    }, // 출력 부분
    devServer: {
        publicPath: '/dist',
        hot : true,

    },
};

이렇게 되면 소스코드의 변경점을 저장한 뒤에 수정 사항을 실시간으로 반영해준다.

끝말잇기 hooks로 수정

최근 react에서는 대부분 hooks 방식을 사용한다. 실제 사용해보면 hooks가 훨씬 간결하고 직관적인 느낌

const React = require('react');
const { useState, useRef} = React;

const WordRelay = ()=>{
    
    const [word, setWord] = useState('김밥말이');
    const [value, setValue] = useState('');
    const [result, setResult] = useState('');
    
    const inputRef= useRef(null);
    
    const onSubmitForm = e =>{
        e.preventDefault();
        if(word[word.length-1] === value[0]){

            setResult('딩동댕');
            setWord(value);
            setValue('')
            inputRef.current.focus();    
        }else{
            setResult('땡');
            setValue('');
            inputRef.current.focus();    
        }
    };

    const onChangeInput = e =>{
        setValue(e.target.value);
    };


    return(
        <>
            <div>{word}</div>
            <form onSubmit = {onSubmitForm}>
                <input ref={inputRef} value={value} onChange={onChangeInput}/>
                <button>입력</button>    
            </form>
            <div>{result}</div>       
        </>
    );

}

module.exports = WordRelay;

위에서 핫 리로딩 설정을 해주었기 때문에 빌드를 다시 해주지 않아도 실시간으로 반영된 결과를 볼 수 있다.

Uncontrolled Input

input 내에 value와 onchange로 setValue를 해주는 것이 Controlled Input이다.
Uncontrolled Input은 input에 ref만 존재하는 간단한 형태이다.

<form ref={inputRef} >

앞선 onSubmitForm에서 value를 사용하지 않고 e.target으로 모두 대체해주었을 때, input은 간단하게 사용할 수 있다. (권장하지는 않는 방법)

profile
공부와 일상

0개의 댓글