끄적끄적

타입스크립트 프로젝트 만들기 - 개발환경세팅 본문

Front-end/Typescript

타입스크립트 프로젝트 만들기 - 개발환경세팅

mashko 2019. 5. 27. 20:35
반응형

타입스크립트 프로젝트는 웹팩을 이용해 구현해 보기로 합시다.

먼저 간단히 프로젝트를 구성하기 위해 NPM을 설치합니다. 프로젝트를 설정하기 위해 프로젝트폴더를 생성하고

mkdir typescript-project
$cd typescript-project
$npm init
$npm i webpack webpack-cli

npm 패키지를 이용해 타입스크립트 프로젝트를 구성합니다.

타입스크립트 패키지를 인스톨 합시다.

$npm install --save typescript ts-loader

프로젝트 구성도입니다.

typescript-project
  |- /build
    |- base.js
    |- build.js
    |- dev.js
  |- /src
    |- types
      |- index.d.ts
    |- app.ts
  |- tsconfig.json
  |- package.json
  |- index.html
  |- babelrc.json

웹팩을 셋팅해 보죠.

먼저 설정을 위해 조금 더 유용하게 설정 할 수있는 패키지들을 다운 받아보도록 하죠.

$npm install --save path webpack-merge webpack-dev-server extract-text-webpack-plugin source-map-loader extract-text-webpack-plugin babel-loader whatwg-fetch html-webpack-plugin
$npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/polyfill

.babelrc

{
    "presets": [
        "@babel/env",
        "@babel/typescript"
    ],
    "plugins": [
        "@babel/proposal-class-properties",
        "@babel/proposal-object-rest-spread"
    ]
}

플러그인들과 해당 바벨 패키지는 타입스크립트 내에 문법을 좀 더 확장되어 사용할 수 있게 도와줍니다.

자세한 내용은 구글링을 통해 확인하시길 바랍니다.

빠르게 지나가죠.. ㅜㅜ..

tsconfig.json

{
  "compilerOptions": {
    "typeRoots": ["types/*"],
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": false,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.js",
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

셋팅이 되었으면 이제 웹팩을 설정을 해볼까요?
build/base.js

var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var rootAssetPath = path.resolve(__dirname, '../dist/js/');
var port = 3000;

module.exports = {
    entry: {
        app: ['whatwg-fetch','@babel/polyfill','./src/app.ts']
    },
    output: {
        path: rootAssetPath,
        filename: '[name].js'
    },
    resolve: {
        // Add `.ts` and `.tsx` as a resolvable extension.
        extensions: [".ts", ".tsx", ".js"]
    },
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        host: 'localhost',
        port: port,
        contentBase: __dirname,
        // 해당 프록시 설정을 해야 할 경우에만 쓰시길 바랍니다 아니면 삭제~
        proxy: {
            '/api/**': {
                target: 'http://localhost:9999',
                secure: false,
                changeOrigin: true
            }
        }
    },
    devtool: "source-map",
    module: {
      rules: [
          {
            test: /\.(ts?)|(js)$/,
            loader: require.resolve('babel-loader'),
            exclude: /node_modules/
          },
          {
            test: /\.ts$/,
            loader: 'ts-loader',
            options: { reportFiles: ['src/**/*.{ts,tsx}', '!src/skip.ts'] }
          }
      ]
    }
};

build/build.js

var path = require('path');
var webpack = require('webpack');
var merge = require('webpack-merge');
var baseWebpackConfig = require('./base.js');
var HtmlWebpackPlugin = require('html-webpack-plugin');

var webpackConfig = merge(baseWebpackConfig, {
    plugins: [
        new webpack.HotModuleReplacementPlugin({
          multiStep: true
        }),
        new HtmlWebpackPlugin({
          filename: path.resolve(__dirname, '../dist/index.html'),
          template: path.resolve(__dirname, '../index.html'),
          inject: true,
          minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true
          },
          chunksSortMode: 'dependency'
        })
    ]
});

module.exports = webpackConfig;

build/dev.js

var webpack = require('webpack');
var merge = require('webpack-merge');
var baseWebpackConfig = require('./base.js');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var port = 3000;

var webpackConfig = merge(baseWebpackConfig, {
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: 'index.html',
          inject: true
        })
    ]
});


console.log('Client Server started: http://localhost:' + port + '/');

module.exports = webpackConfig;

자 준비가 다되어 갑니다. 해당 설정 내용들은 웹팩에 대한 글을 포스팅할때 조금 더 자세히 다루도록 하죠..
시간이 없어서 다음을 기약하는..

아참 index.html의 파일도 정의 해줘야겠죠?

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Cache-Control" content="no-cache"/>
    <meta http-equiv="Expires" content="0"/>
    <meta http-equiv="Pragma" content="no-cache"/>
    <meta name="viewport" content="width=1280">
    <meta name="title" content="타이틀">
    <meta name="description" content="내용">
    <meta name="keywords" content="키워드">
    <meta name="viewport" content="width=1280">
    <title>타이틀 입력</title>
    <!--[if lt IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
    <![endif]-->
</head>
<body>
    <div id="app">
    </div>
</body>
</html>

package.json에 script를 만들어주세요.
그리고 현재 자신이 셋팅되어있는 패키지도 한번 확인해주세요.

{
  "name": "typescript-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --inline --progress --config build/dev.js",
    "build": "webpack --optimize-minimize --env.platform=web --cache=false --color --progress --profile --config build/build.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "babel-loader": "^8.0.6",
    "extract-text-webpack-plugin": "^3.0.2",
    "html-webpack-plugin": "^3.2.0",
    "path": "^0.12.7",
    "source-map-loader": "^0.2.4",
    "ts-loader": "^6.0.1",
    "typescript": "^3.4.5",
    "webpack": "^4.32.2",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.4.1",
    "webpack-merge": "^4.2.1",
    "whatwg-fetch": "^3.0.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.5",
    "@babel/plugin-proposal-class-properties": "^7.4.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
    "@babel/polyfill": "^7.4.4",
    "@babel/preset-env": "^7.4.5",
    "@babel/preset-typescript": "^7.3.3"
  }
}

대충 프로젝트 구성은 끝난거 같은데요.

자 확인 한번 해볼까요?

$npm start
localhost:3000

src/app.ts

class App {
    public init() {
        alert('헬로우 타입스크립트!');
    }
}
const app = new App();
app.init();

아래 내용처럼 잘뜨셧나요?

실행 화면

여기까지 잘 따라하셨으면 다음 포스팅에는 타입스크립트를 활용하여 다음엔 간단한 to do list화면을 만들어 봅시다.

 

반응형
Comments