Vue: TypeScript ๋ฐ AMD(UMD)์—์„œ ์ž˜๋ชป ์ƒ์„ฑ๋œ JS ์ฝ”๋“œ - ๋ฒ„์ „ 2

์— ๋งŒ๋“  2018๋…„ 01์›” 04์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: vuejs/vue

๋ฒ„์ „

2.5.13

์žฌ์ƒ์‚ฐ ๋งํฌ

https://github.com/80LevelElf/VueProblemApp

์žฌํ˜„ ๋‹จ๊ณ„

์•ฑ์„ ์—ด์–ด์„œ ์‹คํ–‰ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด
/VueProblemApp/VueProblemApp/index.html ํŒŒ์ผ๋กœ ์ด๋™ํ•˜๋ฉด ์ฝ˜์†”์— ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๋ฌด์—‡์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๊นŒ?

Typescript ์ปดํŒŒ์ผ๋Ÿฌ๋Š” Vue ํƒ€์ดํ•‘์„ ๋ฐ›์•„ ์˜ฌ๋ฐ”๋ฅธ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฒฐ๊ณผ JS ์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์ž์„ธํ•œ ์„ค๋ช…์€ ์ฃผ์„ ์ฐธ์กฐ).


๋ฉฐ์น  ์ „์— TypeScript ๋ฐ AMD(UMD) ๋ฒ„๊ทธ์—

@yyx990803 ์—์„œ ๋‹ต๋ณ€์„ ์–ป์—ˆ์ง€๋งŒ ์ €๋Š” JS์˜ ๋ฉ์ฒญํ•œ ๋†ˆ์ด๊ณ  ์ฒ˜์Œ๋ถ€ํ„ฐ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ์ง€๊ธˆ ๊ทธ๊ฒƒ์„ ์–ป๋Š”๋‹ค๋ฉด ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—๋ฐ˜์ด ๋‚˜์—๊ฒŒ ๋Œ€๋‹ตํ–ˆ๋‹ค.

"vue" ๋ชจ๋“ˆ์„ ์ง์ ‘ ํฌํ•จ์‹œํ‚จ vue.js UMD ๋นŒ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์„ค์ •์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ TS ์ปดํŒŒ์ผ๋Ÿฌ๋Š” node_modules/vue์—์„œ ํ•ด๊ฒฐํ•˜๊ณ  CommonJS ๋นŒ๋“œ์ธ package.json์˜ "main" ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. tsconfig์—์„œ compilerOptions.paths๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งคํ•‘์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Evan์ด ๋งž๋‹ค๋ฉด ๊ทธ๋Š” RequireJS๊ฐ€ ์ž˜๋ชป๋œ vue.js ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
์˜ค๋ฅธ์ชฝ์€ UMD/AMD ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์šฉ์ด์ง€๋งŒ TS ์ปดํŒŒ์ผ๋Ÿฌ๋Š” CommonJS ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์šฉ vue.js ํŒŒ์ผ์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ์–ป์€ ์ด์œ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. TS ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‹ค์Œ์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ด์‚ฌ์ดํŠธ/

์ œ ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

mySite/vue.js

vue.js ํŒŒ์ผ์ด ๋ฌด์—‡์ด๋“  ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋งํฌ์— vue.js๊ฐ€ ์—†์œผ๋ฉด 404 ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ node_modules/vue/package.json์˜ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์„ "main": "dist/vue.js"์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

RequireJS์—์„œ ๋ถˆ๋Ÿฌ์˜ค๋Š” vue.js ํŒŒ์ผ์„ ํ™•์ธํ•ด๋ณด๋‹ˆ ๋งž๋Š” ํŒŒ์ผ ์ž…๋‹ˆ๋‹ค. RequireJS๋Š” ๊ทธ๊ฒƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ํƒ€์ดํ•‘์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด(์˜ˆ: @Micene09 ์ œ๊ณต):

import { Vue } from "vue-property-decorator";

mySite/vue.js์— ๋™์ผํ•œ vue.js ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ๋‹น์‹ ์„ ์˜ณ๊ฒŒ ์ดํ•ดํ•œ๋‹ค๋ฉด ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ์— ๋ถ€๋”ช์ณค๋‹ค.

๋‚ด ์ดํ•ด์—์„œ vue.js ํŒŒ์ผ์€ vue-class-component์™€ ๊ฐ™์ด exports.default ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

vue-class-component.js(192ํ–‰):
exports['default'] = Component$1;

vue-class-component ํŒŒ์ผ์—๋Š” Vue์—์„œ ๋ˆ„๋ฝ๋œ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

vue-class-component.js(12ํ–‰):
Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue;

๋ถˆํ–‰ํžˆ๋„ TypeScript 2.5 ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ˆ„๋ฝ๋œ ๊ธฐ๋ณธ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ถœ๋ ฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TypeScript 2.7 ์—๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ƒˆ๋กœ์šด ์˜ต์…˜( esModuleInterop )์ด ์žˆ์Šต๋‹ˆ๋‹ค.

{
    "compilerOptions": {
        "module": "amd",
        "esModuleInterop": true,
        ...
    },
    ...
}

esModuleInterop ๋ฅผ true ๋กœ ์„ค์ •ํ•˜๋ฉด ์ถœ๋ ฅ์— __importDefault ๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋˜์–ด ๋ˆ„๋ฝ๋œ ๊ธฐ๋ณธ ์†์„ฑ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

var __importDefault = (this && this.__importDefault) || function (mod) {
  return (mod && mod.__esModule) ? mod : { "default": mod };
}
define(["require", "exports", "vue"], function (require, exports, vue_1) {
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  vue_1 = __importDefault(vue_1);
  var app = new vue_1.default({
        ...
  });
});

๋ชจ๋“  3 ๋Œ“๊ธ€

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฌธ์ œ์—์„œ ํ•ด๊ฒฐ๋˜์–ด์„œ๋Š” ์•ˆ ๋˜๋Š” ๋งค์šฐ ๊ตฌ์ฒด์ ์ธ ์„ค์ •์— ๋Œ€ํ•œ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” Vue ์ž์ฒด์—์„œ ๋ฐœ์ƒํ•œ ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ์—๋งŒ ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค.

@80LevelElf -- ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ (์ง€๊ธˆ์€) ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

import { VueConstructor } from "vue";
const Vue = require("vue") as VueConstructor;  // cast as VueConstructor to get typings. 

const app = new Vue({
  template: "<h1>Hello World</h1>
});

@yyx990803 -- ์ €๋„ ๋น„์Šทํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. TypeScript์˜ commonjs ์ถœ๋ ฅ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(์›นํŒฉ ์—†์Œ). OP์™€ I์˜ ํ•œ ๊ฐ€์ง€ ์œ ์‚ฌ์ ์€ ๋‘˜ ๋‹ค TypeScript baseUrl ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. TypeScript์˜ ํ‘œ์ค€ ๊ฐ€์ ธ์˜ค๊ธฐ์— ํ™•์‹คํžˆ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋„ Vue 2.5.13์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋…ธ๋“œ 8.9.3 ๋ฐ TypeScript 2.6์—์„œ SSR์„ ์„ค์ •ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด tsconfig.json ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
  "compilerOptions": {
    "outDir": "build",
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "rootDir": "./src",
    "baseUrl": "./src",
    "noUnusedLocals": true
  },
  "exclude": [
    "node_modules",
    "typings"
  ]
}

compilerOptions.paths ์†์„ฑ์„ ํ†ตํ•ด vue.esm.js ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. OP์™€ ๋˜‘๊ฐ™์€ vue_1.default is not a constructor ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ๊ธฐ์— ์žฌํ˜„์„ ๋ชจ์•„์„œ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ์— ๋ถ€๋”ช์ณค๋‹ค.

๋‚ด ์ดํ•ด์—์„œ vue.js ํŒŒ์ผ์€ vue-class-component์™€ ๊ฐ™์ด exports.default ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

vue-class-component.js(192ํ–‰):
exports['default'] = Component$1;

vue-class-component ํŒŒ์ผ์—๋Š” Vue์—์„œ ๋ˆ„๋ฝ๋œ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

vue-class-component.js(12ํ–‰):
Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue;

๋ถˆํ–‰ํžˆ๋„ TypeScript 2.5 ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ˆ„๋ฝ๋œ ๊ธฐ๋ณธ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ถœ๋ ฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TypeScript 2.7 ์—๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ƒˆ๋กœ์šด ์˜ต์…˜( esModuleInterop )์ด ์žˆ์Šต๋‹ˆ๋‹ค.

{
    "compilerOptions": {
        "module": "amd",
        "esModuleInterop": true,
        ...
    },
    ...
}

esModuleInterop ๋ฅผ true ๋กœ ์„ค์ •ํ•˜๋ฉด ์ถœ๋ ฅ์— __importDefault ๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋˜์–ด ๋ˆ„๋ฝ๋œ ๊ธฐ๋ณธ ์†์„ฑ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

var __importDefault = (this && this.__importDefault) || function (mod) {
  return (mod && mod.__esModule) ? mod : { "default": mod };
}
define(["require", "exports", "vue"], function (require, exports, vue_1) {
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  vue_1 = __importDefault(vue_1);
  var app = new vue_1.default({
        ...
  });
});
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰