컴포넌트로 나누는 이유

-성능 최적화에 더 좋다.(성능 최적화 시간에 자세히 다룬다고함)

-가독성이 좋아진다. (메인 파일의 코드가 길어지는 것을 방지할 수 있다.)

-코드 관리가 쉬워진다.

-재사용성이 좋아진다.

 

Props

-부모 컴포넌트에서 자식 컴포넌트에 데이터를 전달하는 방법임.

this.props.value

class component에서 props 받는방법.

map에 관해서는 적지 않는다.

 

map을 돌릴 때는 항상 key라는 것을 추가해줘야한다.

key는 react가 성능 최적화 할 때 사용하는 값이고, 고유한 값을 적어줘야한다.

key에 index를 넣어주는 경우가 있는데 이런 경우는 성능 최적화 할 때 문제가 생기기 때문에 index를 넣으면 안된다.

 

 

require

require : node의 모듈 시스템

내보내기 module.exports 이름; (= export default) 엄밀히 따지면 다른데 react 하는 데에는 호환된다고함.

가져오기 const 변수명 require('이름');

 

노드 모듈 시스템에서 

module.exports = { hello: 'a' };

exports.hello = 'a'; 는 같다.

 

import

ES2015문법으로 Node의 모듈과 다르다.

내보내기 export default 이름; (한번만 가능)   import { hello };

               export 이름; (여러번 가능)               import Numberbaseball;

가져오기 import 이름 from '이름';

 

사실 import쓰면 에러가 나는데 babel이 import들을 모두 require로 변경해준다고함.

Node에서는 require쓰고, react에서는 import와 exports 쓴다.

 

webpack

웹팩은 노드가 돌려주는 것이기 때문에 require를 써야한다!!

client부분(jsx)는 babel이 import를 require로 변경해주기 때문에 import를 사용해도 된다.

 

 

공통점은 exports 되는게 객체나 배열이면 구조분해 가능!

ex) import {useState, useRef} from 'react';

컨트롤드 인풋 vs 언컨트롤드 인풋

컨트롤드 인풋 : state로 만들어진 value, 해당 value를 변경할 수 있는 onChange(setState)

언컨트롤드 인풋 : value, onChange가 없는 것 (원시적인 인풋 형태)

  --> <input type='text', ref={inputRef} defaultValue="하이" />

(언컨트롤드 인풋에 value를 넣는건 컨트롤드 인풋으로 간주될 수 있기 때문에 언컨트롤드 인풋에서 기본값을 넣으려면 defalutValue를 사용해야한다.)

쉽게 말해서 input의 value가 onSubmit에서만 동작하는 경우 unControlledInput을 사용해도 된다.

 

컨트롤드 인풋을 사용할 때는?

예를 들면 아래와 같은 경우임.

 

1. 비밀번호 체크할 때 valid해서 밑에 빨간줄 뜨게 해야한다. (dynamic inputs)

2. 비밀번호 체크할 때 조건에 안맞으면 submit 불가능하도록 해야한다. (conditionally disabling submit button)

3. 비밀번호 검증하는 것

4. 비밀번호 형식 강제하는 것

뭐 등등 많은데 사실 몰라도 되고 그냥 컨트롤드 인풋만 사용하면 된다고 하심.

//필요로 하는 패키지나 라이브러리 불러오기
const React = require('react');
const {useState, useRef} = React;


const WordRelayHooks = () => {
    const [word, setWord] = useState('제로초');
    const [value, setValue] = useState('');
    const [result, setResult] = useState('');
    const inputRef = useRef(null);

    const onChange = e => {
        const value = e.target.value;
        setValue((prev)=>value);
    }
    const onSubmit = e => {
        e.preventDefault();
        const lastChar = word[word.length-1];
        const input = value;
        if(lastChar === input[0]){
            setResult('딩동댕');
            setWord((prev)=>input);
            setValue((prev)=>'');
        }else{
            setResult('땡');
            setValue('');
        }
        inputRef.current.focus();
    }

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

}

//쪼갠 파일에서 쓰는 컴포넌트를 밖에서도 사용할 수 있게 해주는 것. (이것이 노드의 모듈 시스템)
module.exports = WordRelayHooks;

WordRelayHooks.jsx

 

const React = require('react');
const ReactDom = require('react-dom');
const WordRelay = require('./WordRelay'); //module.export를 했기 때문에 require로 가져올 수 있다.
const WordRelayHooks = require('./WordRelayHooks');

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

Client.jsx

코드를 바꿀 때마다 webpack 명령어로 리빌드 하는 것이 매우 귀찮은 일이고, 실수를 유발할 포인트가 매우 크다.

그래서 자동으로 리빌드 되는 방법을 알려주는 강의임.

 

1. 패키지 설치

npm i -D react-refresh 

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

npm i -D webpack-dev-server //개발용 서버

 

2. package.json 변경

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack serve --env development"
},

package.json에서 먼저 설치한 패키지들이 잘 설치되었는지 devDependencies를 확인 후 script의 dev 부분을 저렇게 바꿔주자.

webpack serve --env development

 

3. webpack-config.js 변경

3-1. 패키지 require

받았던 패키지 중에 아래 패키지를 require 해준다.

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

 

3-2. webpack plugins 추가

가져온 패키지를 plugins 부분에 넣어주면 장착완료 (plugins에 넣어준 패키지들은 빌드 될 때마다 해당 부분이 실행된다고 생각하면 된다.)

plugins: [//webpack에 대한 plugins (바벨의 plugins와 다르다!)
    new webpack.LoaderOptionsPlugin({debug: true}), //Loader = module,rules 의 options에 debug: true를 넣어주는 것이다.
    new RefreshWebpackPlugin()
],

 

3-3. babel loader plugins 추가

또 바벨로더에도 플러그인을 넣어줘야한다.

('react-refresh/babel', //바벨이 최신 문법을 예전 문법으로 트랜스파일할 떄 핫리로드 기능도 추가해줌.)

//webpack과 연결할 모듈들을 적시한다.
module: {
    rules:[{
        test: /\.jsx?/,
        loader: 'babel-loader',
        options:{ //바벨로더의 옵션
            presets:[['@babel/preset-env',{  //예전 브라우저 지원 문법으로 변경해주는 프리셋
                targets:{   //@babel/preset-env 프리셋에 대한 옵션
                    browsers: ['> 5% in KR','last 2 chrome versions'] // 한국에서 5% 이상, 크롬 최신 전 버전까지만 지원 (browserslist 사이트 참고)
                },
                debug: true
            }], '@babel/preset-react'],
            plugins: [
                //'@babel/plugin-proposal-class-properties',
                'react-refresh/babel', //바벨이 최신 문법을 예전 문법으로 트랜스파일할 떄 핫리로드 기능도 추가해줌.
            ]
        }
    }],
},

이렇게 하면 바벨이 최신 문법을 예전 문법으로 트랜스파일할 때 핫리로드 기능도 추가를 해준다.

 

3-4. 데브 서버 설정 추가

데브서버의 역할 :

1. webpack.config.js에 적어둔 대로 빌드 결과물을 설정해둔 폴더로 저장해둔다. (실제로 파일이 저장되는건 아니고 ram에 저장됨.)

2. index.html을 실행하면 저장했던 결과물을 제공해준다. 

3. hot-reload 기능도 추가했기 때문에 소스에 변경점이 생기면 저장했던 결과물도 자동으로 수정해준다.

devServer: {
    devMiddleware: { publicPath: '/dist' }, //웹팩이 빌드할때 파일을 생성해주는 경로 (RAM에 추가됨)
    static: { directory: path.resolve(__dirname) }, // static은 정적파일의 경로 (index.html 같은거)
    hot: true,
}

 

※ reload vs hot-reload 

리로드는 그냥 새로고침 (기존 데이터가 날아감)

핫리로드는 기존 데이터를 보존하고 화면만 바꿔준다.

데브서버를 추가하면 그냥 리로드는 되는데 핫 리로드는 

npm i -D react-refresh 

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

해당 두개의 패키지를 설치해야만 한다.

 

지금까지의 webpack.config.js 전체코드

const path = require('path'); //node에 기본적으로 제공해주는 path를 쉽게 조작하기 위한 라이브러리
const webpack = require('webpack');
const RefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

module.exports = {
    name: 'word_relay-setting', //어떤 것을 위한 웹팩 설정인지
    mode: 'development', //실서비스에서는 production
    devtool: 'eval', //빠르게
    resolve: {
        extensions: ['.js', '.jsx'] //확장자 적어놓으면 xxx.js, xxx.jsx 알아서 찾아서 빌드한다.
    },
    //여기서 부터가 제일 중요
    //entry : 입력,
    //output: 출력
    entry: {
        app:['./client'] // './WordRelay.jsx' 는 이미 client.jsx에서 불러오고 있기 때문에 굳이 써주지 않아도 된다.
    },

    //webpack과 연결할 모듈들을 적시한다.
    module: {
        rules:[{
            test: /\.jsx?/,
            loader: 'babel-loader',
            options:{ //바벨로더의 옵션
                presets:[['@babel/preset-env',{  //예전 브라우저 지원 문법으로 변경해주는 프리셋
                    targets:{   //@babel/preset-env 프리셋에 대한 옵션
                        browsers: ['> 5% in KR','last 2 chrome versions'] // 한국에서 5% 이상, 크롬 최신 전 버전까지만 지원 (browserslist 사이트 참고)
                    },
                    debug: true
                }], '@babel/preset-react'],
                plugins: [
                    //'@babel/plugin-proposal-class-properties',
                    'react-refresh/babel', //바벨이 최신 문법을 예전 문법으로 트랜스파일할 떄 핫리로드 기능도 추가해줌.
                ]
            }
        }],
    },
    plugins: [//webpack에 대한 plugins (바벨의 plugins와 다르다!)
        new webpack.LoaderOptionsPlugin({debug: true}), //Loader = module,rules 의 options에 debug: true를 넣어주는 것이다.
        new RefreshWebpackPlugin()
    ],
    output: {
        //path.join : 파라미터로 전달된 경로를 합쳐준다.
        //__dirname -> 현재 경로(lecture)
        path: path.join(__dirname, 'dist'), //C:\Users\iLovePC\Desktop\codingapple\zerocho-react-webgame\lecture 에 dist를 더해준다.
        filename: "app.js",
        publicPath: "/dist/",
    },
    devServer: {
        devMiddleware: { publicPath: '/dist' }, //웹팩이 빌드할때 파일을 생성해주는 경로 (RAM에 추가됨)
        static: { directory: path.resolve(__dirname) }, // static은 정적파일의 경로 (index.html 같은거)
        hot: true,
    }
}
//필요로 하는 패키지나 라이브러리 불러오기
const React = require('react');
const {Component} = React;

class WordRelay extends Component{
    state={
        word:'제로초',
        value:'',
        result:'',
    }
    input;

    onChange = e => {
        const value = e.target.value;
        this.setState({value});
    }
    onSubmit = e => {
        e.preventDefault();
        const word = this.state.word;
        const lastChar = word[word.length-1];
        const input = this.state.value;
        if(lastChar === input[0]){
            this.setState({
                result:'딩동댕',
                word:input,
                value:'',
            })
        }else{
            this.setState({
                result:'땡',
                value:'',
            })
        }
        this.input.focus();
    }

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

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

//쪼갠 파일에서 쓰는 컴포넌트를 밖에서도 사용할 수 있게 해주는 것. (이것이 노드의 모듈 시스템)
module.exports = WordRelay;

일단 강의 안보고 만든 작품 

 

리액트에서 value와 onChange는 세트이다. onChange를 안넣을거면 defaultValue를 넣어줘야함.

(defaultValue = {this.state.value})

※컨트롤드 인풋, 언컨트롤드 인풋으로 리액트 공식문서를 찾아보면 된다고 하심.

 

웹팩 설정의 연속

 

plugin들의 모음이 preset이다.

module 중 하나인 babel-loader에서 presets를 명시할 수 있는데 해당 presets들은 사실 plugins의 모음들이다.

플러그인만의 옵션을 따로 적용할 수 있다.

        options:{ //바벨로더의 옵션
                presets:[['@babel/preset-env',{  //예전 브라우저 지원 문법으로 변경해주는 프리셋
                    targets:{   //@babel/preset-env 프리셋에 대한 옵션
                        browsers: ['> 5% in KR','last 2 chrome versions'] // 한국에서 5% 이상, 크롬 최신 전 버전까지만 지원 (browers list 사이트 참고)
                    },
                    debug: true
                }], '@babel/preset-react'],
                //plugins: ['@babel/plugin-proposal-class-properties']
        }

 

webpack의 플러그인

webpack의 플러그인을 따로 명시할 수 있다. (위에서 살펴본 모듈 플러그인과 다르다.)

 

정리

webpack 공식 사이트에서도 적용할 수 있는게 너무 많아서 복잡하다.

하지만 핵심은 5가지를 알고 있어야한다는 것.

entry,

output,

module (Loaders),

Plugins,

Mode (development, production)

 

외우는 방식을 웹팩 동작 순서대로 외우면 편리하다.

entry(시작하는 파일, 합쳐질 파일들) 

module (entry파일들에 적용될 규칙들)

plugins (추가적인 작업)

output(최종적으로 만들어질 파일)

 

지금까지 webpack.config.js 전체코드

const path = require('path'); //node에 기본적으로 제공해주는 path를 쉽게 조작하기 위한 라이브러리
const webpack = require('webpack');

module.exports = {
    name: 'word_relay-setting', //어떤 것을 위한 웹팩 설정인지
    mode: 'development', //실서비스에서는 production
    devtool: 'eval', //빠르게
    resolve: {
        extensions: ['.js', '.jsx'] //확장자 적어놓으면 xxx.js, xxx.jsx 알아서 찾아서 빌드한다.
    },
    //여기서 부터가 제일 중요
    //entry : 입력,
    //output: 출력
    entry: {
        app:['./client'] // './WordRelay.jsx' 는 이미 client.jsx에서 불러오고 있기 때문에 굳이 써주지 않아도 된다.
    },

    //webpack과 연결할 모듈들을 적시한다.
    module: {
        rules:[{
            test: /\.jsx?/,
            loader: 'babel-loader',
            options:{ //바벨로더의 옵션
                presets:[['@babel/preset-env',{  //예전 브라우저 지원 문법으로 변경해주는 프리셋
                    targets:{   //@babel/preset-env 프리셋에 대한 옵션
                        browsers: ['> 5% in KR','last 2 chrome versions'] // 한국에서 5% 이상, 크롬 최신 전 버전까지만 지원 (browserslist 사이트 참고)
                    },
                    debug: true
                }], '@babel/preset-react'],
                //plugins: ['@babel/plugin-proposal-class-properties']
            }
        }],
    },
    plugins: [//webpack에 대한 plugins (바벨의 plugins와 다르다!)
        new webpack.LoaderOptionsPlugin({debug: true}) //Loader = module,rules 의 options에 debug: true를 넣어주는 것이다.
    ],
    output: {
        //path.join : 파라미터로 전달된 경로를 합쳐준다.
        //__dirname -> 현재 경로(lecture)
        path: path.join(__dirname, 'dist'), //C:\Users\iLovePC\Desktop\codingapple\zerocho-react-webgame\lecture 에 dist를 더해준다.
        filename: "app.js"
    }
}

1. 웹팩으로 빌드하기

터미널에 아래와 같이 webpack을 입력하면 된다. 

> webpackwebpack

※만약 webpack 명령어 등록이 되어있지 않다면 ? (아래와 같은 방법으로 해결)

[package.json]

"scripts": {
    "dev": "webpack"
  },

script 부분에 위와 같이 입력 후 터미널에 아래와 같이 입력한다.

> npm run dev

 

해당 방법도 안되면 npx 사용

> npx webpack 

 

asset app.js 1.59 KiB [emitted] (name: app)
./client.jsx 250 bytes [built] [code generated] [1 error]

ERROR in ./client.jsx 5:16
Module parse failed: Unexpected token (5:16)
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/concep

word_relay-setting (webpack 5.91.0) compiled with 1 error in 75 ms

webpack으로 빌드하면 위와 같이 아래가 발생하는데 위 에러는 client.jsx의

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

해당 코드에서 발생하는 것이다. 전에 실습할 때도 말했듯 js에서는 '<','>' 해당 문자열을 인식하지 못한다. (JSX문법 이해하지 못함.) 그래서 바벨을 사용해야한다.

바벨이 jsx문법을 react.createDom 같은 문법으로 바꿔줌.

 

2. 바벨 설치하기

npm i -D @babel/core : 바벨의 기본적인것

npm i -D @babel/preset-env : 최신 문법을 예전 브라우저 문법에 맞게 바꿔준다.

npm i -D @babel/preset-react : jsx같은 문법을 지원하는 문법으로 바꿔준다.

npm i -D babel-loader : 웹팩과 바벨을 연결

※ @babel/plugin-proposal-class-properties 나는 추가 안해도 되긴했음. (강의에서는 추가해야만 바벨이 원활하게 작동함)

 

[-D 옵션]

개발할 때만 바벨을 사용하기 때문에 -D 옵션을 준다.

 

3. 웹팩과 바벨 연결하기

웹팩과 바벨을 연결 해주는 babel-loader를 설치했으니 webpack.config.js에 문법에 맞게 입력하면 웹팩과 바벨을 연결할 수 있다.

module:{
	rules:[{
    	test: /\.jsx?/,
        loader: 'babel-loader',
        options:{
        	presets:['@babel/preset-env', '@babel/preset-react'],
            //plugins: ['@babel/plugin-proposal-class-properties']
        }
    }]
}

 

entry에 있는 파일을 읽고 거기에 module을 적용한 후 output에 뺀다. 라는 의미로 알고 있으면 될 것 같다.

-rules는 여러 개를 적용할 수 있어서 배열로 작성한다.

-test는 rule을 적용할 파일들 (위의 예시에서는 js와 jsx에 적용하겠다는 정규식)

-loader : 어떤 규칙을 적용할지 작성한다. (예시에서는 바벨 로더를 적용한다라는 의미라고 함.)

-options는 바벨의 옵션들 (option에 있는 plugins는 안써도 에러가 나지 않아서 주석처리해놓음. 관련된 에러가 나면 추가해주면 될듯)

 

이제 터미널에서 다시 해당 명령어를 입력해주면 build가 정상적으로 될 것이다.

(output에 명시된 규칙대로 잘 나왔는지 확인해보면 된다.)

> webpack

혹은 > npx webpack

 

webpack.config.js 전체코드

const path = require('path'); //node에 기본적으로 제공해주는 path를 쉽게 조작하기 위한 라이브러리

module.exports = {
    name: 'word_relay-setting', //어떤 것을 위한 웹팩 설정인지
    mode: 'development', //실서비스에서는 production
    devtool: 'eval', //빠르게
    resolve: {
        extensions: ['.js', '.jsx'] //확장자 적어놓으면 xxx.js, xxx.jsx 알아서 찾아서 빌드한다.
    },
    //여기서 부터가 제일 중요
    //entry : 입력,
    //output: 출력
    entry: {
        app:['./client'] // './WordRelay.jsx' 는 이미 client.jsx에서 불러오고 있기 때문에 굳이 써주지 않아도 된다.
    },

    //webpack과 연결할 모듈들을 적시한다.
    module: {
        rules:[{
            test: /\.jsx?/,
            loader: 'babel-loader',
            options:{
                presets:['@babel/preset-env', '@babel/preset-react'],
                //plugins: ['@babel/plugin-proposal-class-properties']
            }
        }],
    },
    output: {
        //path.join : 파라미터로 전달된 경로를 합쳐준다.
        //__dirname -> 현재 경로(lecture)
        path: path.join(__dirname, 'dist'), //C:\Users\iLovePC\Desktop\codingapple\zerocho-react-webgame\lecture 에 dist를 더해준다.
        filename: "app.js"
    }
}

 

다시 한번 복습

웹팩의 사용 이유

-entry에 있는 여러 파일들을 module의 rules를 적용시켜 output에 적힌 규칙대로 합쳐준다.

-난독화도 시켜준다.

webpack을 사용하는 이유

여러 컴포넌트를 모아서 한방에 합쳐서 하나의 js파일로 만들어 준다.

합치면서 babel도 적용할 수 있고, console.log 같은 것도 모두 빼버릴 수 있는 기능을 제공한다.

 

webpack을 하려면 node를 알아야한다.

node는 js 실행기 그 이상 그 이하도 아니다. (백엔드 아님..)

react할 때 node를 알아야 한다. 라는것이 서버 백엔드를 알아야 한다는 것이 아니라는 것이다. webpack을 돌리기 위한 그 js실행기를 알아야 한다는 뜻이다.

 

1. node를 설치하고 

2. (터미널로 강의 폴더로 이동 후) npm init

3. package.json이 생성된다.

4. npm i react react-dom

5. npm i -D webpack webpack-cli 

   (-D는 개발용으로만 사용한다는 의미이다. 실제 서비스 할 때는 webpack이 필요 없다고 한다.)

6. package.json에 우리가 설치한 package들이 잘 기록되어있는지 확인

   (개발용 devDependencies,    실제 서비스 dependencies)

7. 강의 폴더에 webpack.config.js 생성 및 아래와 같이 작성

module.exports = {
    
}

8. 강의 폴더에 client.jsx 생성 및 아래와 같이 작성

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

ReactDom.render(<WorldRelay/>, document.querySelector('#root'));

9. 강의 폴더에 index.html 생성 및 아래와 같이 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>끝말잇기</title>
</head>
<body>
    <div id="root"></div>
    <script src="./dist/app.js"></script>
</body>
</html>

10. 강의 폴더에 WorldRelay.jsx 파일 생성 및 작성

//필요로 하는 패키지나 라이브러리 불러오기
const React = require('react');
const {Component} = React;

class WordRelay extends Component{
    state={

    }

    render() {
        return (
            <div>

            </div>
        );
    }
}

//쪼갠 파일에서 쓰는 컴포넌트를 밖에서도 사용할 수 있게 해주는 것. (이것이 노드의 모듈 시스템)
module.exports = WordRelay;

여기서 node module 시스템 처음 봤음. export default ~ 이거랑 다른가. 아무튼 저렇게 module.exports를 해줘야 밖에서 사용할 수 있다고 함.

 

실제로 이제 client.jsx파일을 수정해줘야한다.

const React = require('react');
const ReactDom = require('react-dom');
const WordRelay = require('./WordRelay'); //module.export를 했기 때문에 require로 가져올 수 있다.

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

 

근데 여기서 문제점이 있는데, 위에서 만들었던 index.html에서는 app.js 한개만 사용해야한다. 그게 아니면 기존 방식 처럼 <script src=~></script> <script src=~></script> <script src=~></script> 이렇게 여러 <script>태그를 사용해야하는데 그것을 안하려고 webpack을 사용하는 것이다.

 

11. webpack.config.js 에 아래의 내용 추가

const path = require('path'); //node에 기본적으로 제공해주는 path를 쉽게 조작하기 위한 라이브러리

module.exports = {
    name: 'word_relay-setting', //어떤 것을 위한 웹팩 설정인지
    mode: 'development', //실서비스에서는 production
    devtool: 'eval', //빠르게(개발시에만), 'hidden-source-map' //실서버 배포시에는 저거쓰면됨.
    resolve: {
        extensions: ['.js', '.jsx'] //확장자 적어놓으면 xxx.js, xxx.jsx 알아서 찾아서 빌드한다.
    },
    //여기서 부터가 제일 중요
    //entry : 입력,
    //output: 출력
    entry: {
        app:['./client'] // './WordRelay.jsx' 는 이미 client.jsx에서 불러오고 있기 때문에 굳이 써주지 않아도 된다.
    },
    output: {
        //path.join : 파라미터로 전달된 경로를 합쳐준다.
        //__dirname -> 현재 경로 webpack.config.js가 있는 곳(lecture)
        path: path.join(__dirname, 'dist'), //C:\Users\iLovePC\Desktop\codingapple\zerocho-react-webgame\lecture 에 dist를 더해준다.
        filename: "app.js"
    }
}

 

+ Recent posts