잊지 않겠습니다.

Angular2 + webpack

기본 npm package 준비

{
  "name": "angular2-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "angular2": "^2.0.0-beta.15",
    "bluebird": "^3.3.5",
    "core-js": "^2.2.2",
    "lodash": "^4.11.1",
    "reflect-metadata": "^0.1.3",
    "rxjs": "^5.0.0-beta.6",
    "zone.js": "^0.6.11"
  },
  "devDependencies": {
    "awesome-typescript-loader": "^0.17.0-rc.6",
    "copy-webpack-plugin": "^2.1.1",
    "html-webpack-plugin": "^2.15.0"
  }
}

기본적으로 reflect-metadata, rxjs, zone.jsangular2와 같이 설치되어야지 된다.

npm install rxjs --save
npm install reflect-metadata --save
npm install zone.js --save

typescript 설정

npm install typings --global
  • tsd는 deprecated되었기 때문에 더이상 사용되지 않는다.

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true
  },
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts",
    "bower_components"
  ]
}

webpack 설정

기본적으로 다음 folder 구조를 따른다. (maven 과 유사)

├── dist
├── src
│   ├── app
│   └── public
├── package.json
├── tsconfig.json
├── typings.json
└── webpack.config.js
  • src/app: javascript application
  • src/public: html,css,image와 같이 static resource 구성

typescript를 지원하기 위해서 awesome-typescript-loader을 설치하고 loader에 다음과 같이 등록한다.

{
  test: /\.ts$/,
  loader: 'awesome-typescript-loader',
  exclude: /node_modules/
}

webpack.config.js

'use strict';

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');

function buildConfig() {
  var isProd = false;
  const config = {
    output: {
      path: __dirname + '/dist',
      publicPath: isProd ? '/' : 'http://localhost:8080/',
      filename: isProd ? '[name].[hash].js' : '[name].bundle.js',
      chunkFilename: isProd ? '[name].[hash].js' : '[name].bundle.js'
    },
    resolve: {
      extensions: ['', '.webpack.js', '.web.js', '.ts', '.js'],
      modulesDirectories: [
        'node_modules'
      ]
    },
    devtool: 'cheap-source-map',
    module: {
      loaders: [
        {
          test: /\.ts$/,
          loader: 'awesome-typescript-loader',
          exclude: /node_modules/
        }
      ]
    },
    entry: {
      app: __dirname + '/src/app/app.ts'
    },
    plugins: [
      new webpack.NoErrorsPlugin(),
      new webpack.optimize.DedupePlugin(),
      new CopyWebpackPlugin([{ from: __dirname + '/src/public'}]),
      new HtmlWebpackPlugin({
        template: './src/public/index.html',
        inject: 'body'
      })
    ]
  };
  config.devServer = {
    contentBase: './dist',
    stats: 'minimal',
    outputPath: './dist'
  };

  return config;
}

module.exports = buildConfig();

app.ts

webpack에서 지정되는 entry point가 된다. main.ts, bootstrap.ts등 다양한 파일이름이 있지만, 개인적으로는 app.ts가 가장 좋은것 같다.

app.ts에서는 다음 세가지 기능을 한다.

  1. router 의 등록
  2. bootstrap 실행
  3. 첫페이지로 direction
/// <reference path="../../node_modules/angular2/typings/browser.d.ts" />

import 'core-js/es6';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
import { bootstrap } from 'angular2/platform/browser';
import { HTTP_PROVIDERS } from 'angular2/http';
import { enableProdMode } from 'angular2/core';
import { Component } from 'angular2/core';
import { provide } from 'angular2/core';
import { Router, RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, LocationStrategy, Location, HashLocationStrategy } from 'angular2/router';

import { HeroService } from './hero.service';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent, HeroesRouterInfo } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';

@RouteConfig([
  {
    path: '/heroes',
    name: 'Heroes',
    component: HeroesComponent,
  },
  HeroesRouterInfo,
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: DashboardComponent,
    useAsDefault: true
  },
  {
    path: '/detail/:id',
    name: 'HeroDetail',
    component: HeroDetailComponent
  },
])
@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <nav>
      <a [routerLink]="['Dashboard']">Dashboard</a>
      <a [routerLink]="['Heroes']">Heroes</a>
    </nav>
    <router-outlet></router-outlet>
  `,
  styleUrls: ['app.component.css'],
  directives: [ROUTER_DIRECTIVES]
})
class AppComponent {
  title: string;
  router: Router;
  location: Location;
  constructor(router: Router, location: Location) {
    this.title = 'This is Title';
    this.router = router;
    this.location = location;
  }
}

// enableProdMode();
bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  ROUTER_PROVIDERS,
  provide(LocationStrategy, { useClass: HashLocationStrategy }),
  HeroService
]).catch(err => console.error(err));

app.ts의 경우에는 router가 추가 되고, 여러 서비스 Provider들이 추가되는 것 이외에는 큰 차이가 없을것같다. 기본적으로 기존 angularapp.js와 동일한 기능을 갖게 된다.

lodash 추가

typings install lodash --ambient --save
import * as _ from 'lodash'
Posted by Y2K
,