FrontEnd/Vue를 이용한 웹 게임 만들기

Chapter 03. 웹팩 적용하기와 숫자 야구

계란💕 2023. 3. 31. 12:41

초기 설정

  • 웹팩을 쓰기 위해서는 먼저 node를 깔아야한다. 
  • node를 설치하면 npm이 같이 따라온다. 
  • npm은 다른 사람이 작성해둔 javascript 코드를 끌어다 쓸 수 있다. 
  • 결국  Vue도 남이 만들어둔 소스라고 볼 수 있다. 

 

  • node를 제대로 설치하면 다음과 같이 버전 확인이 가능하다. 
    • node -v
    • npm -v

 

 

  • npm init
    • 터미널로 들어와서 npm init  입력하고 나면 다음과 같이 버전 및 여러 가지가 나오는데 package name만 다음과 같이  입력하고 나머지는 모두 넘긴다.
    • 입력하고나면 다음과 같이 json 파일이 하나 생성된다. 
    • 내가 쓸 수 있는 다른 사람의 소스 코드가 정리된 파일이다. 
    • 정리하는 이유: 각 소스코드마다 버전이 있다. 내가 어떤 버전을 쓰고 있는지 버전관리하고 몇 버전인지 파악하기 위한 package.json을 만든다. 

 

  • npm install vue
    • (npm install vue)
    • Vue를 설치한다. 
    • 더이상 <script>를 사용하지 않을 예정이다. 
    • 앞으로 npm으로 소스 코드를 관리하자.

 

 

  • npm i webpack webpack -cli -D
    • 웹팩 설치
    • webpack 과 webpack cli 두 패키지를 설치하는데 옵션으로 "-D"를 선택했다. (D는 개발할 때만 쓰겠다는 설정이다.)

 

 

  • package.json 파일
    • main: 숫자 야구 프로젝트에서 가장 중요한 파일명을 넣어준다. 
    • 앞에서 "-D" 옵션을 줬기 때문에 devDependencies{}에 웹팩 내용이 추가됐다. 
    • vue는 개발, 배포 시 둘다 사용되지만 웹팩, 웹팩 cli는 개발을 위한 보조 도구이다. 
<hide/>
{
  "name": "number-baseball",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vue": "^3.2.47"
  },
  "devDependencies": {
    "webpack": "^5.77.0",
    "webpack-cli": "^5.0.1"
  }
}

 


웹팩 사용하기

 

웹팩 관련 핵심 옵션

  • entry: 웹팩을 이용하면 여러 스크립를 관리하는데 가장 대표가 되는 파일을 entry에 넣어준다. 
  • module: 웹 팩의 핵심이다. rules에서 합칠 때 어떻게 합칠 것인지, 처리할 건지 정해준다. 
  • plugins: 후처리하는 부분
    • module이 먼저 처리하다가 최종 처리
    • output 나오기 직전에 plugins이 적용되서 한번 더 가공된다. 
  • output
  • 가장 먼저 entry 부분부터 처리하다가 희한한? 부분을 만나면 module의 rules가  처리한다. s
  • exports에 넣는 옵션
    • mode: 개발 중인 경우는 "development" , 배포시에는  mode: "production"을 넣어준다. 
    • devtools: 개발 중인 경우는 'eval'  , 배포시에는   devtools: 'hidden-source-map'
    • (eval로 설정하면 빌드 속도가 빠르다. )
    • resolve: {extensions:  ['.js', '.vue']}  .. 확장자 를 처리한다. 
      • app.js 파일을 보면
      • import NumberBaseball from './NumberBaseball.vue' 가 있는데 뒷부분의  확장자인".vue"를 생략할 수 있다.  없어도 자동으로 .vue 파일이라고 인식한다. 

 

 

  Ex) 

  • webpack.config.js 파일을 만든다. 
    • module.exports= {} : 노드 모듈을 만들어준다. 
    • 웹팩이 웹팩 처리할 때(웹 패킹) 방금 만든 모듈로 만든 객체가 사용된다.
  • entry 에 넣으려는 main.js 파일을 만든다. 
    • entry 안에 있는 app 은 나중에 하나로 합쳐줄 파일의 이름이다. 
    • main.js 외 여러 개의 script가 app.js로 합쳐질 예정이다. 
  • dist 라는 폴더가 생기고 그 안에  app.js라는  최종 결과물이 생길 것이다. 
  • 그러고나서 html 파일에 <script src = "/dist/app.js"></script> ... 이런 식으로 가져올 수 있다. 뷰 가져오는 소스 경로 같은 부분도 필요없다. 
  • plugins: 
  • output: 

 

  • webpack.config.js 
<hide/>
module.exports = {
    entry: {
        app: './main.js'
    },
    module: {

    },
    plugins: [],
    output: {
        filename: 'app.js',
        path: './dist'
    },
};

 

 

  • 복잡한 스크립트 코드가 모두 app.js 로 합쳐지기 때문에 html 파일이 다음과 같이 간단해진다. 
<hide/>
<!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>숫자 야구</title>
</head>
<body>
    <div id="root"></div>
    <script src="/dist/app.js"></script>
</body>
</html>

 


프로젝트 구조와 웹팩 빌드

  •  main.js
    • import 문: package.json에서 설치한 뷰를 가져오고 있다. => new Vue() 를 사용 가능하다.
    • mount는 "el" 과 같은 역할을 한다. (el에 Vue가 통제하도록 div 태그의 이름을 넣어줬었다. )
    • Vue 인스턴스로 만든다. 
    • 기존에 만들었던 Vue 컴포넌트가  NumberBaseball.vue가 된다. 
import Vue from 'vue';
new Vue().$mount('#root');

 

 

  • NumberBaseball.vue
    • 확장자는 뷰지만 javascript 라고 생각하면  된다. 
    • 특수한 문법을 쓰는 javascript
    • template: 기존에 만든 Vue 인스턴스의 template 영역에 해당한다. 
    • <script> 안에 export default: 
    • main.js NumberBaseball.vue 를 모두 합쳐서 dist/app.js로 만들어줘야 NumberBaseball.html 파일이 완성된다. 

 

  • NumberBaseball.html
<hide/>
<!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>숫자 야구</title>
</head>
<body>
    <div id="root"></div>
    <script src="/dist/app.js"></script>
</body>
</html>

 

 

  • 기존의 package.json 파일의  부분을 다음과 같이 수정한다. 
    • scripts의 test => build
<hide/>
{
  "name": "number-baseball",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vue": "^3.2.47"
  },
  "devDependencies": {
    "webpack": "^5.77.0",
    "webpack-cli": "^5.0.1"
  }
}

 

 

  • npm run "스크립트명" 을 터미널에 입력하면 웹팩이 실행된다. 
    • 웹팩을 돌리는 명령어가 바로 webpack이다. 
    • npm run build 입력
    • 다음과 같이 에러가 난다. 
    • dist 폴더의 절대 경로가 잘못되었기 때문이다. 
    • 하지만 절대 경로를 직접 적기 보다는 노드에서 절대경로 입력 도와주는 기능을 이용하는 게 훨씬 편리하다. 

 

 

 

 


 

  • 다음과 같이
    • path: 노드가 만든 스트립트를 의미한다. 
    • __dirname: 현재 폴더 경로에 접근 가능하다. (현재 폴더: ch03)
    • join(): path안에 있는 메서드로 어느 경로로 들어갈건지 경로를 넣어준다. 
    • path: path.join(__dirname, 'dist'): 경로를 합쳐준다. 괄호 안에 폴더, 파일명을 차례로 넣는다.  
    • 아래와 같이 두 곳에 적용할 수 있다. 
<hide/>
const path = require('path');

module.exports = {
    entry: {
        app: path.join(__dirname, 'main.js')
    },
    module: {

    },
    plugins: [],
    output: {
        filename: '[name].js',
        path: path.join(__dirname, 'dist'),
    },
};

 

 

 


웹팩 로더 사용하기

  •  npm run build 입력
  • NumberBaseball.vue와  main.js를 연결시키려한다. 
  • 웹팩은 자바스크립트만 합쳐준다. 
    • 그런데 NumberBaseball.vue는 자바스크립트가 아니라서 문제가 생긴다. 
    • 그래서 webpack.config.js에  rules가 필요하다. 
    • 정규 표현식: 파일명이 ".vue"로 끝나는($) 파일에 대해 vue-loader를 사용하겠다. 
    • npm i vue-loader 를 입력해서 다운받는다. 


  • 오류
    • package.json 파일에 다음과 같이 vue-loader 가 생기는 게 정상이다.
    • 앞으로 vue 파일은 웹팩이 아닌 vue-loader가 처리한다. 
{
  "name": "number-baseball",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vue": "^3.2.47"
  },
  "devDependencies": {
    "vue-loader": "^15.7.0",
    "webpack": "^5.77.0",
    "webpack-cli": "^5.0.1"
  }
}

 

 

 

  • 지금 이상태로 npm run build 해보면 에러가 난다. 

 

  • config 파일에 다음 내용을 추가한다. 
    • VueLoaderPlugin()

  • main.js
    • Node 환경에서는 requireVue 환경에서는 import
    • 웹팩은 노드 환경이므로  require를 쓴다. 
<hide/>
import Vue from 'vue';
import NumberBaseball from './NumberBaseball.vue'

new Vue().$mount('#root');

 

 

  • npm i vue-template-compiler -D

 

  • cf) Vue와 vue-template-compiler 의 버전이 항상 일치해야한다. 
    • 특정 버전으로 깔기 위해서는 다음과 같이 @ 뒤에 버전을 입력한다. 
    • ex)npm  i vue@2.7.0
    • @를 쓰지 않으면 항상 최신 버전으로 깔린다. 

 

<hide/>
npm ERR! Missing script: "build"
npm ERR!
npm ERR! To see a list of scripts, run:
npm ERR!   npm run
<hide/>
S C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03> npm run build
Debugger attached.

> number-baseball@1.0.0 build
> webpack

Debugger attached.
[webpack-cli] Failed to load 'C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\webpack.config.js' config
[webpack-cli] Error: Cannot find module 'webpack/lib/RuleSet'
Require stack:
- C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\node_modules\vue-loader\lib\plugin.js
- C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\webpack.config.js
- C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\node_modules\webpack-cli\lib\webpack-cli.js
- C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\node_modules\webpack-cli\lib\bootstrap.js
- C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\node_modules\webpack-cli\bin\cli.js
- C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\node_modules\webpack\bin\webpack.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Module._load (node:internal/modules/cjs/loader:920:27)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (C:\Users\lan42\OneDrive\바탕 화면\vue\web_game\ch03\node_modules\vue-loader\lib\plugin.js:2:17)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\lan42\\OneDrive\\바탕 화면\\vue\\web_game\\ch03\\node_modules\\vue-loader\\lib\\plugin.js',
    'C:\\Users\\lan42\\OneDrive\\바탕 화면\\vue\\web_game\\ch03\\webpack.config.js',
    'C:\\Users\\lan42\\OneDrive\\바탕 화면\\vue\\web_game\\ch03\\node_modules\\webpack-cli\\lib\\webpack-cli.js',
    'C:\\Users\\lan42\\OneDrive\\바탕 화면\\vue\\web_game\\ch03\\node_modules\\webpack-cli\\lib\\bootstrap.js',
    'C:\\Users\\lan42\\OneDrive\\바탕 화면\\vue\\web_game\\ch03\\node_modules\\webpack-cli\\bin\\cli.js',
    'C:\\Users\\lan42\\OneDrive\\바탕 화면\\vue\\web_game\\ch03\\node_modules\\webpack\\bin\\webpack.js'
  ]
}
Waiting for the debugger to disconnect...
Waiting for the debugger to disconnect.

 

  • 오류: build 관련 스크립트가 없다
  • 원인: 빌드 스크립트를 넣었는데도 이런 오류가 난다. 
  • 해결
    • 1) vue loader 관련 모듈을 다시 설치한다. 
    • 2) webpack.config 파일에서  const.. 부분을 수정한다.  
<hide/>
npm install vue-loader vue-template-compiler --save-dev

 

  • webpack
    • 주석 처리한 부분을 기존 코드인데  뒷 부분의 lib으로 시작되는 부분을 지우니까 해결됐다. 
<hide/>
// const {VueLoaderPlugin} = require('vue-loader/lib/plugin');

const {VueLoaderPlugin} = require('vue-loader');
const path = require('path');

module.exports = {
    entry: {
        app: path.join(__dirname, 'main.js')
    },
    module: {
        rules: [
        {
            test: /\.vue$/,
            loader: 'vue-loader'
        }]
    },
    plugins: [
        new VueLoaderPlugin(), 
        
    ],
    output: {
        filename: '[name].js',
        path: path.join(__dirname, 'dist'),
    },
};

 

 

  • 빌드 성공 화면
    • 성공하고 나면 dist 폴더에 app.js라는 파일이 생긴다. 


 

  • webpack.config 파일에 extensions에 ['.js', '.vue'] 를  설정한다. 
<hide/>
// const {VueLoaderPlugin} = require('vue-loader/lib/plugin');

const {VueLoaderPlugin} = require('vue-loader');
const path = require('path');

module.exports = {
    mode: "development",
    devtool: 'eval', 
    resolve: {
        extensions: ['.js', '.vue']
    },
    entry: {
        app: path.join(__dirname, 'main.js')
    },
    module: {
        rules: [
        {
            test: /\.vue$/,
            loader: 'vue-loader'
        }]
    },
    plugins: [
        new VueLoaderPlugin(), 
        
    ],
    output: {
        filename: '[name].js',
        path: path.join(__dirname, 'dist'),
    },
};

 

 

  • main 파일을 다음과 같이 바꿀 수 있다. 
    • 확장자  ".vue"를 없애거 Vue () 안에 매개변수를 넣었다. 
<hide/>
import Vue from 'vue';
import NumberBaseball from './NumberBaseball'

new Vue(NumberBaseball).$mount('#root');

 

 

  • 새롭게 빌드한다. npm run build
    • 빌드해주고 나면 app.js 파일에 "eval" 단어가 여러 개 등장한다. 
    • Vue 컴포넌트를 전환하고 설정을 통해서  웹팩이 main.js, NumberBaseball.vue 가  NumberBaseball.vue를 dist 폴더 안의  "app.js"로 합쳐준 것이다. 

v-for 로 반복문 사용하기

  •  

 

  Ex)  숫자  야구

  •  숫자  야구는 랜덤으로 주어진 네 자리 숫자에 대해서 숫자만 맞추면 볼, 숫자와 자리까지 맞추면 스트라이크로 카운트해주는 게임이다. 
  • 랜덤으로 숫자 만들기

 

  • default에 배열  tries를 추가한다. 입력값이 들어올 때마다 tries 배열 안에 push 하려고 한다. 
  • 어떤 기능을 추가할 때마다 npm run build 해준다. 
  • vue 파일
    • v-for문 안에 보면 "t" 라는 인스턴스를 만들었다.
    • try에 target 값을 추가해준다. 
    • 입력한 다음에는  focus()하고  value도 ''로 초기화해준다. 
    • "v-"가 붙으면  뷰가 통제하는 속성이다. 
    • 입력할 때 마다 "tries" 배열에 데이터가 푸시되고 값을 화면에 보여준다. 
<hide>
<template>
  <div>
    <h1>{{ result }}</h1>
    <form v-on:submit="onSubmitForm">
      <input ref="answer" maxlength="4" v-model="value" />
      <button>입력</button>
    </form>
    <div>시도: {{ tries.length }}</div>
    <ul>
      <li v-for="t in tries">{{ t }}</li>
    </ul>
  </div>
</template>

<script>
const getNumbers = () => {
  const candidates = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  const array = [];

  for (let i = 0; i < 4; ++i) {
    const chosen = candidates.splice(Math.random());
  }
};

export default {
  data() {
    return {
      tries: [],
      value: "",
      result: "",
    };
  },
  methods: {
    onSubmitForm(e) {
      e.preventDefault();
      this.tries.push(this.value);
      this.value = "";
      this.$refs.answer.focus();
    },
  },
};
</script>

<style></style>

 

  Note) 실행 결과

 

 

 

  Ex) 배열 안에 인스턴스 넣기

  • 아까는 this.value 라는 값을 넣었지만 이번에는 인스턴스를 넣으려고 한다. 
  • methods 안에 배열에 입력값을 넣어주고 result에는 "홈런"을 넣는다. 
<hide/>
<template>
  <div>
    <h1>{{ result }}</h1>
    <form v-on:submit="onSubmitForm">
      <input ref="answer" maxlength="4" v-model="value" />
      <button>입력</button>
    </form>
    <div>시도: {{ tries.length }}</div>
    <ul>
      <li v-for="t in tries"><div>
        {{ t.tries }}
        {{ t.result }}
      </div></li>
    </ul>
  </div>
</template>

<script>
const getNumbers = () => {
  const candidates = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  const array = [];

  for (let i = 0; i < 4; ++i) {
    const chosen = candidates.splice(Math.random());
  }
};

export default {
  data() {
    return {
      tries: [],
      value: "",
      result: "",
    };
  },
  methods: {
    onSubmitForm(e) {
      e.preventDefault();
      this.tries.push({
        tries: this.value,
        result: "홈런",
      });
      this.value = "";
      this.$refs.answer.focus();
    },
  },
};
</script>

<style></style>

 

  Note) 실행 결과

 

 

  cf) 코드 줄이기

  • <form> 안에 있는 "v-on:" 은 "@"로 바꿀 수 있다. 
  • submitForm에서 preventDefault를 자주 쓰는데 이 부분을 지우고 다으과 같이 form  태그 안에 표현 가능하다. 
  • ===>    <form @submit.prevent="onSubmitForm">

 

 

 

 

  Ex)

  •  npm run build 를 매번 입력하는 게 번거롭다.  build가 자동으로 되도록 하려면?

 

 


숫자 야구 완성하기

 

  • 네 개의 랜덤으로 숫자 만들기
    • 아래 코드를 메서드로 만들 수도 있다. 
    • 그러면 다른 곳에서 this.getNumbers()로 접근 가능하다.
    • data{} 또는  methods{}  같은 영역에는 화면과 밀접한 관련이 있는 것들만 묶어준다.
    •  
<hide/>
const getNumbers = () => {
  const candidates = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  const array = [];

  for (let i = 0; i < 4; ++i) {
    const chosen = candidates.splice(Math.floor(Math.random() * (9 -i)), 1)[0];
    array.push(chosen);
  }
  return array;
};

 

 

 

  • submitForm
    • 게임이 끝나고 나면 다음과 같이 초기화해준다. 
    • 틀린 경우는 스트라이크와 볼 개수를 카운트해야하므로 복잡하다. 
    • 변수더라도 화면에 보이면 데이터, 화면에 보이지 않으면 그냥 변수로 선언한다. 
    •  const answerArr = this.value.split('').map(v => parseInt(v)); 
      •  this.value가 문자 배열이더라도 숫자 배열로 바꿔준다. 
    • 주의) result는 물결 위에 있는 따옴표( ` , 백틱)로 감싸야한다. 그냥 홑따옴표로 감싸면 오류가 난다. 
<hide/>
<template>
  <div>
    <h1>{{ result }}</h1>
    <form @submit.prevent="onSubmitForm">
      <input ref="answer" minlength="4" maxlength="4" v-model="value" />
      <button>입력</button>
    </form>
    <div>시도: {{ tries.length }}</div>
    <ul>
      <!-- <li v-for="t in tries" :key="t.try">
        <div>
            {{ t.try }}
            {{ t.result }}
        </div>
      </li> -->
      <li v-for="t in tries" :key="t.try">
        <div>
          {{ t.try }}: {{ t.result }}
        </div>
      </li>
    </ul>
  </div>
</template>

<script>
    const getNumbers = () => {
        const candidates = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        const array = [];
        for (let i = 0; i < 4; i += 1) {
            const chosen = candidates.splice(Math.floor(Math.random() * (9 - i)), 1)[0];
            array.push(chosen);
        }
    return array;
    };

export default {
  data() {
    return {
      answer: getNumbers(), // 정답은 배열 형태 ex. [1, 5, 3, 4]
      tries: [],
      value: '',
      result: '',
    }
  },
  methods: {
    onSubmitForm() {
        
        // 맞춘 경우
        if(this.value === this.answer.join('')){    // 문자열과 배열은 join()해줘야 비교 가능
            this.tries.push({
                try: this.value,
                result: '홈런',
            });

            this.result = '홈런';
            alert('게임을 다시 실행합니다.');
            this.value = '';    // 초기화
            this.tries = [];
            this.$refs.answer.focus();
        }else{  // 틀린 경우

            let strike = 0;
            let ball = 0;
            const answerArr = this.value.split('').map(v => parseInt(v));

            for(let i = 0; i < 4; i += 1){
                if(answerArr[i] === this.answer[i] ){   // 숫자와 자릿수 모두 맞는 경우: 스트라이크
                    ++strike;
                }else if(this.answer.includes(answerArr[i])){ // 볼
                    ++ball;
                }
            }

            this.tries.push({
                try: this.value,
                result : `${strike} 스트라이크, ${ball} 볼입니다.`
            });

            this.value = '';
            this.$refs.answer.focus();
        }
    }
  }
};
</script>

<style></style>

 

 

  Note) 실행 결과

 

 

 

 Ex) 10번 너게 틀린 경우, 초기화하기

  • 틀린 경우의 앞 부분에 다음과 같이 추가한다. 
<hide/>
if(this.tries.length >= 9){
    this.result = `10번 넘게 틀려서 실패! 답은 ${this.answer.join(',')} 였습니다.`;
    alert("게임을 다시 시작합니다. ");
    this.value = '';    // 초기화
    this.answer = getNumbers();    
    this.tries = [];
    this.$refs.answer.focus();
}

 

  Note) 실행 결과

 


  • NumberBasebll 파일의 export default {} 를 이용하면?
    •  main.js 파일에서 import로 가져올 수 있다.
    • export default{} 와 import from은 세트라고 생각하면 된다. 
  • node에서는 import나 default를 쓰지 않고 require,  module.export를 쓴다. 
    • (뷰) import => require
    • (뷰) export  default => module.export

  • 오류
    • try는 예약어라서 아래와 같이 쓸 수 없다. 
  • 원인: build 스크립트가 없다는 뜻이다.  
  • 해결: try말고 다른 변수를 사용한다. 

 


  • 오류: npm run build가 안되는 경우
  • 원인: package.json 파일이 실행중인 상태가 아니라서 오류 발생
  • 해결: package 파일을 한 번 실행해준 다음에 새롭게 빌드한다. 

정상 빌드 화면

 

 

<hide/>
 <li v-for="t in tries" :key="t.try">
    <div>
      {{ t.try }}: {{ t.result }}
    </div>
</li>

Note

  •  content

 

 

출처 - https://www.inflearn.com/course/web-game-vue/dashboard

 

[무료] 웹 게임을 만들며 배우는 Vue - 인프런 | 강의

간단한 8가지 웹 게임을 만들며 Vue.js와 Vue와 함께 사용되는 Vuex, Vue Router를 배워봅니다., - 강의 소개 | 인프런

www.inflearn.com