本文将从头开始编写实际的代码来完成一个angular2的demo。

题外话是其实angular2官网的快速开始项目已经很酷炫了,但其侧重快速二字,只够拿来练习玩耍,倒是github上确实已经有了一些不错的angular2-starter。

1. 安装必要的node环境与npm

当然TS环境也是必须的,目前TS已经更新到了2.1.5+,笔者使用的就是2.1.5版本,且最好使用2.0以上版本的TS,否则会有一些尴尬的问题(包括类型定义以及编译错误)。

2.关于编辑器

笔者使用的是VSCode,使用其他热门的编辑器都可以自己喜欢就行,甚至可以用VisualStudio(但是在网上见过有人用VS2015来开发涉及到npm包的项目,即使是Mac顶配版也能卡爆炸)。

3. 底层目录结构

想象自己在写一个后台语言项目,我们所写的文件最终都要经过编译生成目标文件才运行,ng2也是这样,编写的是.ts文件,最终由我们配置好的编译器(webpack)进行编译生成目标代码并运行。

所以除了angular2依赖以外,必须配置好底层的webpack。所有的依赖包都通过前面安装的npm来安装。下面给出package.json:

  1. {
  2. "name": "angular2-demo-yitim",
  3. "version": "1.0.0",
  4. "description": "angular2 demo by yitim",
  5. "keywords": [
  6. "angular2",
  7. "webpack",
  8. "typescript"
  9. ],
  10. "author": "yitim <635928008@qq.com>",
  11. "license": "MIT",
  12. "scripts": {
  13. "build:aot:prod": "npm run clean:dist && npm run clean:aot && webpack --config config/webpack.prod.js --progress --profile --bail",
  14. "build:aot": "npm run build:aot:prod",
  15. "build:dev": "npm run clean:dist && webpack --config config/webpack.dev.js --progress --profile",
  16. "build:docker": "npm run build:prod && docker build -t angular2-webpack-start:latest .",
  17. "build:prod": "npm run clean:dist && webpack --config config/webpack.prod.js --progress --profile --bail",
  18. "build": "npm run build:dev",
  19. "clean:dll": "npm run rimraf -- dll",
  20. "clean:aot": "npm run rimraf -- compiled",
  21. "clean:dist": "npm run rimraf -- dist",
  22. "clean:install": "npm set progress=false && npm install",
  23. "clean": "npm cache clean && npm run rimraf -- node_modules doc coverage dist compiled dll",
  24. "docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
  25. "lint": "npm run tslint \"src/**/*.ts\"",
  26. "server:dev:hmr": "npm run server:dev -- --inline --hot",
  27. "server:dev": "webpack-dev-server --config config/webpack.dev.js --open --progress --profile --watch --content-base src/",
  28. "server:prod": "http-server dist -c-1 --cors",
  29. "server": "npm run server:dev",
  30. "start": "npm run server:dev",
  31. "tslint": "tslint",
  32. "version": "npm run build",
  33. "watch:dev:hmr": "npm run watch:dev -- --hot",
  34. "watch:dev": "npm run build:dev -- --watch",
  35. "watch:prod": "npm run build:prod -- --watch",
  36. "watch": "npm run watch:dev",
  37. "webdriver-manager": "webdriver-manager",
  38. "webdriver:start": "npm run webdriver-manager start",
  39. "webdriver:update": "webdriver-manager update",
  40. "webpack-dev-server": "webpack-dev-server",
  41. "webpack": "webpack"
  42. },
  43. "dependencies": {
  44. "@angular/common": "2.4.6",
  45. "@angular/compiler": "2.4.6",
  46. "@angular/core": "2.4.6",
  47. "@angular/forms": "2.4.6",
  48. "@angular/http": "2.4.6",
  49. "@angular/platform-browser": "2.4.6",
  50. "@angular/platform-browser-dynamic": "2.4.6",
  51. "@angular/platform-server": "2.4.6",
  52. "@angular/router": "3.4.6",
  53. "@angularclass/conventions-loader": "^1.0.2",
  54. "@angularclass/hmr": "~1.2.2",
  55. "@angularclass/hmr-loader": "~3.0.2",
  56. "core-js": "^2.4.1",
  57. "crypto-browserify": "^3.11.0",
  58. "crypto-js": "^3.1.9-1",
  59. "http-server": "^0.9.0",
  60. "ie-shim": "^0.1.0",
  61. "reflect-metadata": "^0.1.9",
  62. "rxjs": "5.0.2",
  63. "zone.js": "0.7.6"
  64. },
  65. "devDependencies": {
  66. "@angular/compiler-cli": "2.4.6",
  67. "@types/hammerjs": "^2.0.33",
  68. "@types/node": "^7.0.0",
  69. "@types/selenium-webdriver": "~2.53.39",
  70. "@types/source-map": "^0.5.0",
  71. "@types/uglify-js": "^2.0.27",
  72. "@types/webpack": "^2.0.0",
  73. "add-asset-html-webpack-plugin": "^1.0.2",
  74. "angular2-template-loader": "^0.6.0",
  75. "assets-webpack-plugin": "^3.5.1",
  76. "awesome-typescript-loader": "~3.0.0-beta.18",
  77. "codelyzer": "~2.0.0-beta.4",
  78. "copy-webpack-plugin": "^4.0.0",
  79. "css-loader": "^0.26.0",
  80. "exports-loader": "^0.6.3",
  81. "expose-loader": "^0.7.1",
  82. "extract-text-webpack-plugin": "~2.0.0-rc.2",
  83. "file-loader": "^0.10.0",
  84. "find-root": "^1.0.0",
  85. "gh-pages": "^0.12.0",
  86. "html-webpack-plugin": "^2.28.0",
  87. "imports-loader": "^0.7.0",
  88. "istanbul-instrumenter-loader": "1.2.0",
  89. "json-loader": "^0.5.4",
  90. "ng-router-loader": "^2.1.0",
  91. "ngc-webpack": "1.1.0",
  92. "npm-run-all": "^4.0.1",
  93. "optimize-js-plugin": "0.0.4",
  94. "parse5": "^3.0.1",
  95. "protractor": "^4.0.14",
  96. "raw-loader": "0.5.1",
  97. "rimraf": "~2.5.4",
  98. "sass-loader": "^4.1.1",
  99. "script-ext-html-webpack-plugin": "^1.5.0",
  100. "source-map-loader": "^0.1.5",
  101. "string-replace-loader": "1.0.5",
  102. "style-loader": "^0.13.1",
  103. "to-string-loader": "^1.1.4",
  104. "ts-node": "^2.0.0",
  105. "tslib": "^1.5.0",
  106. "tslint": "~4.4.2",
  107. "tslint-loader": "^3.3.0",
  108. "typedoc": "^0.5.3",
  109. "typescript": "~2.1.5",
  110. "url-loader": "^0.5.7",
  111. "webpack": "2.2.0",
  112. "webpack-dev-middleware": "^1.10.0",
  113. "webpack-dev-server": "2.2.1",
  114. "webpack-dll-bundles-plugin": "^1.0.0-beta.5",
  115. "webpack-merge": "~2.6.1"
  116. }
  117. }

package.json

package.json用于管理npm依赖,然后还需要tsconfig.json来配置TS,以及tsconfig.webpack.json来配合webpack编译:

  1. {
  2. "compilerOptions": {
  3. "target": "es5",
  4. "module": "commonjs",
  5. "moduleResolution": "node",
  6. "emitDecoratorMetadata": true,
  7. "experimentalDecorators": true,
  8. "allowSyntheticDefaultImports": true,
  9. "sourceMap": true,
  10. "noEmit": true,
  11. "noEmitHelpers": true,
  12. "importHelpers": true,
  13. "strictNullChecks": false,
  14. "lib": [
  15. "dom",
  16. "es6"
  17. ],
  18. "typeRoots": [
  19. "node_modules/@types",
  20. "./typings/**/*.d.ts",
  21. "../vendor/tslib/tslib.d.ts"
  22. ],
  23. "types": [
  24. "hammerjs",
  25. "node",
  26. "source-map",
  27. "uglify-js",
  28. "webpack"
  29. ]
  30. },
  31. "exclude": [
  32. "node_modules",
  33. "dist"
  34. ],
  35. "awesomeTypescriptLoaderOptions": {
  36. "forkChecker": true,
  37. "useWebpackText": true
  38. },
  39. "compileOnSave": false,
  40. "buildOnSave": false,
  41. "atom": {
  42. "rewriteTsconfig": false
  43. }
  44. }

tsconfig.json

  1. {
  2. "compilerOptions": {
  3. "target": "es5",
  4. "module": "es2015",
  5. "moduleResolution": "node",
  6. "emitDecoratorMetadata": true,
  7. "experimentalDecorators": true,
  8. "allowSyntheticDefaultImports": true,
  9. "sourceMap": true,
  10. "noEmit": true,
  11. "noEmitHelpers": true,
  12. "importHelpers": true,
  13. "strictNullChecks": false,
  14. "lib": [
  15. "es2015",
  16. "dom"
  17. ],
  18. "typeRoots": [
  19. "node_modules/@types"
  20. ],
  21. "types": [
  22. "hammerjs",
  23. "node"
  24. ]
  25. },
  26. "exclude": [
  27. "node_modules",
  28. "dist",
  29. "src/**/*.spec.ts",
  30. "src/**/*.e2e.ts"
  31. ],
  32. "awesomeTypescriptLoaderOptions": {
  33. "forkChecker": true,
  34. "useWebpackText": true
  35. },
  36. "angularCompilerOptions": {
  37. "genDir": "./compiled",
  38. "skipMetadataEmit": true
  39. },
  40. "compileOnSave": false,
  41. "buildOnSave": false,
  42. "atom": {
  43. "rewriteTsconfig": false
  44. }
  45. }

tsconfig.webpack.json

然后是webpack的配置文件,入口为webpack.config.js:

  1. // Look in ./config folder for webpack.dev.js
  2. switch (process.env.NODE_ENV) {
  3. case 'prod':
  4. case 'production':
  5. module.exports = require('./config/webpack.prod')({env: 'production'});
  6. break;
  7. case 'dev':
  8. case 'development':
  9. default:
  10. module.exports = require('./config/webpack.dev')({env: 'development'});
  11. }

webpack.config.js

此配置文件将根据运行编译时的参数决定使用开发环境的编译方式还是生产环境的编译方式,具体的编译配置就不贴上来了,可以到文末给出的github地址查看整个项目。

4. angular2的配置

第3节的配置是项目npm依赖、TypeScript以及webpack的配置,给整个项目提供了依赖,并帮助编译以后会写的实际项目代码,与angular2的关系其实不大,但是是angular2项目运行的前提。现在要来配置angular2了,以webpack作为模块化工具的话,需要一个入口文件index.html以及几个入口脚本:

  1. /*
  2. * Angular bootstraping
  3. */
  4. import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
  5. import { decorateModuleRef } from './app/environment';
  6. import { bootloader } from '@angularclass/hmr';
  7. /*
  8. * App Module
  9. * our top level module that holds all of our components
  10. */
  11. import { AppModule } from './app';
  12.  
  13. /*
  14. * Bootstrap our Angular app with a top level NgModule
  15. */
  16. export function main(): Promise<any> {
  17. return platformBrowserDynamic()
  18. .bootstrapModule(AppModule)
  19. .then(decorateModuleRef)
  20. .catch((err) => console.error(err));
  21. }
  22.  
  23. // needed for hmr
  24. // in prod this is replace for document ready
  25. bootloader(main);

main.browser.ts

  1. // TODO(gdi2290): switch to DLLs
  2.  
  3. // Polyfills
  4.  
  5. // import 'ie-shim'; // Internet Explorer 9 support
  6.  
  7. // import 'core-js/es6';
  8. // Added parts of es6 which are necessary for your project or your browser support requirements.
  9. import 'core-js/es6/symbol';
  10. import 'core-js/es6/object';
  11. import 'core-js/es6/function';
  12. import 'core-js/es6/parse-int';
  13. import 'core-js/es6/parse-float';
  14. import 'core-js/es6/number';
  15. import 'core-js/es6/math';
  16. import 'core-js/es6/string';
  17. import 'core-js/es6/date';
  18. import 'core-js/es6/array';
  19. import 'core-js/es6/regexp';
  20. import 'core-js/es6/map';
  21. import 'core-js/es6/set';
  22. import 'core-js/es6/weak-map';
  23. import 'core-js/es6/weak-set';
  24. import 'core-js/es6/typed';
  25. import 'core-js/es6/reflect';
  26. // see issue https://github.com/AngularClass/angular2-webpack-starter/issues/709
  27. // import 'core-js/es6/promise';
  28.  
  29. import 'core-js/es7/reflect';
  30. import 'zone.js/dist/zone';
  31.  
  32. if ('production' === ENV) {
  33. // Production
  34.  
  35. } else {
  36.  
  37. // Development
  38. Error.stackTraceLimit = Infinity;
  39.  
  40. /* tslint:disable no-var-requires */
  41. require('zone.js/dist/long-stack-trace-zone');
  42.  
  43. }

polyfills.browser.ts

前者的作用是引导angular2程序的运行,后者的作用是管理angular2的所有依赖(由于angular2使用了很多ES新特性,所以需要一些依赖来扩展不支持新特性的浏览器的功能)。

实际代码可能还需要有aot模式的引导文件(预编译模式,更适用于生产环境,效率高非常多),以及一个自定义的类型声明文件(帮助编写TS代码)。

5. 实际要写的代码——app目录与assets目录

配置好所有东西后,就轮到亲手来写angular2代码了,专门新建一个app目录来存放这些代码,以及一个assets文件来存放静态资源。

一个最简单的angular2项目需要以下几个文件:

  1. import { BrowserModule } from '@angular/platform-browser';
  2. import { NgModule } from '@angular/core';
  3.  
  4. import { AppComponent } from './app.component';
  5. import { ENV_PROVIDERS } from './environment';
  6.  
  7. @NgModule({
  8. bootstrap: [ AppComponent ],
  9. declarations: [ AppComponent],
  10. imports: [
  11. BrowserModule
  12. ],
  13. providers: [ ENV_PROVIDERS ]
  14. })
  15. export class AppModule { }

app.module.ts

  1. import {
  2. Component, OnInit, ViewEncapsulation
  3. } from '@angular/core';
  4.  
  5. @Component({
  6. selector: 'my-app',
  7. template: `<h1>Hello World!</h1>`,
  8. })
  9. export class AppComponent implements OnInit {
  10.  
  11. public ngOnInit() {
  12. console.log('load app.component');
  13. }
  14. }

app.component.ts

一个是根模块一个是根组件,在此先不提angular2具体语法,先把项目成功运行起来为重。

为了让webpack找到我们的angular2代码,以及成功引导angular2项目,还必须添加一个环境文件以及一个索引文件:

  1. // App
  2. export * from './app.module';

index.ts

  1. // Angular 2
  2. import {
  3. enableDebugTools,
  4. disableDebugTools
  5. } from '@angular/platform-browser';
  6. import {
  7. ApplicationRef,
  8. enableProdMode
  9. } from '@angular/core';
  10. // Environment Providers
  11. let PROVIDERS: any[] = [
  12. // common env directives
  13. ];
  14.  
  15. // Angular debug tools in the dev console
  16. // https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md
  17. let _decorateModuleRef = <T>(value: T): T => { return value; };
  18.  
  19. if ('production' === ENV) {
  20. enableProdMode();
  21.  
  22. // Production
  23. _decorateModuleRef = (modRef: any) => {
  24. disableDebugTools();
  25.  
  26. return modRef;
  27. };
  28.  
  29. PROVIDERS = [
  30. ...PROVIDERS,
  31. // custom providers in production
  32. ];
  33.  
  34. } else {
  35.  
  36. _decorateModuleRef = (modRef: any) => {
  37. const appRef = modRef.injector.get(ApplicationRef);
  38. const cmpRef = appRef.components[0];
  39.  
  40. let _ng = (<any> window).ng;
  41. enableDebugTools(cmpRef);
  42. (<any> window).ng.probe = _ng.probe;
  43. (<any> window).ng.coreTokens = _ng.coreTokens;
  44. return modRef;
  45. };
  46.  
  47. // Development
  48. PROVIDERS = [
  49. ...PROVIDERS,
  50. // custom providers in development
  51. ];
  52.  
  53. }
  54.  
  55. export const decorateModuleRef = _decorateModuleRef;
  56.  
  57. export const ENV_PROVIDERS = [
  58. ...PROVIDERS
  59. ];

environment.ts

下面是现在的文件目录结构:

现在只要先运行 npm install 安装好所有npm包,然后运行指令 npm run server:dev 就可以运行起第一个angular2项目了!

后记:

此angular2 demo的配置有使用到AngularClass的hmr插件,并且搭建的目的以学习与总结为主,实际开发中还需要配置单元测试等东西,可以直接查看AngularClass的angular-webpack-starter开源项目,其给出了一套非常完善的angular2启动项目,值得花费一些时间来看懂。

最后给出此demo的github地址:

https://github.com/yitimo/angular2-demo-yitim

Angular2 + Webpack项目搭建Demo的更多相关文章

  1. angular2+webpack的搭建过程遇到的问题记录

    最近在由于公司的项目要重构,Superiors要求将原先的Ionic1+angular1+gulp用全新的Ionic2+angular2+webpack重构.苦逼的Google了好久,环境搭建还是不太 ...

  2. (转)windows环境vue+webpack项目搭建

    首先,vue.js是一种前端框架,一般利用vue创建项目是要搭配webpack项目构建工具的,而webpack在执行打包压缩的时候是依赖node.js的环境的,所以,要进行vue项目的开发,我们首先要 ...

  3. vue-cli2.0+webpack 项目搭建

    一:准备工作 安装nodejs + 安装webpack + 配置环境变量 => 确保在dos界面的任何路径都都可直接使用命令 二:搭建项目 1.全局安装vue脚手架  [DOS界面] npm i ...

  4. webpack项目搭建

    1.新建一个文件目录,命令行进入当前目录,输入npm init 创建package.json文件 2.安装项目依赖webpack模块: npm install webpack --save-dev 3 ...

  5. 从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(一)

    摘要:随着前端技术的飞速发展,越来越多的技术领域开始被前端工程师踏足.从NodeJs问世至今,各种前端工具脚手架.服务端框架层出不穷,“全栈工程师”对于前端开发者来说,再也不只是说说而已.在NodeJ ...

  6. 【原创】从零开始搭建Electron+Vue+Webpack项目框架(六)Electron打包,同时构建客户端和web端

    导航: (一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更 ...

  7. 使用 webpack 手动搭建 vue 项目

    webpack 是一个前端工程化打包工具,对于前端工程师来说 webpack 是一项十分重要的技能.下面我们就通过搭建一个 vue 项目来学习使用 webpack 主要环境: node v14.15. ...

  8. 从零搭建基于webpack的Electron-Vue3项目(1)——基于webpack的Vue3项目搭建

    从零搭建基于webpack的Electron-Vue3项目(1)--基于webpack的Vue3项目搭建 前言 本篇文章内容,主要是基于webpack的Vue3项目开发环境进行搭建,暂时还不涉及到El ...

  9. 搭建自己的Webpack项目

    五,搭建自己的Webpack项目  https://www.jianshu.com/p/42e11515c10f

随机推荐

  1. 支付宝WAP支付接口开发

    支付宝WAP支付接口开发 因项目需要,要增加支付宝手机网站支付功能,找了支付宝的样例代码和接口说明,折腾两天搞定,谨以此文作为这两天摸索的总结.由于公司有自己的支付接口,并不直接使用这个接口,所以晚些 ...

  2. MySQL-基本sql命令

    关于环境的搭建和数据库的连接,我直接跳过,假设电脑上已经安装好了MySQL的环境,接下来直接进行数据库的操作:(虽然数据库不区分大小写,但是本文约定:命令用大写,用户变量和字段用小写) 1.创建数据库 ...

  3. oracle系列--级联删除和级联更新

    必须声明:此博客转载于Oracle外键级联删除和级联更新http://www.2cto.com/database/201507/417496.html 鉴于此前收藏的精彩博客无料被删除了,很是痛心,所 ...

  4. Python3基础 使用id() 查询变量的存储位置

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  5. HTML5学习笔记 二:article和section

    在HTML5中,article可以看做特殊种类的section,它比section更强调独立性. section元素强调分段或分块,而article强调独立性: 如果一块内容相对独立.完整,应该使用a ...

  6. OC--设置视图控制器,从导航栏的下边缘开始

    self.edgesForExtendedLayout = UIRectEdgeNone;

  7. 黄聪:VPS用轻松备份工具备份Wordpress,文件夹通配符

    db;log;wp-admin;wp-includes;temp;upgrade;twentyfourteen;twentyfifteen;twentysixteen;twentythirteen;t ...

  8. IOS 使用GCD改善性能

    1.GCD介绍 GCD:Grand Central Dispathch,核心中央调度,是一种异步技术.但是它是系统级的. 负责管理队列,是线程之上的抽象层.队列可以并行或串行运行,能够在系统级自动管理 ...

  9. iOS 之 KVC KVO

    KVC:键值编码,是一种间接访问对象实例变量的机制,可以不通过存取方法(getter setter)就可以访问实例变量. KVO: 属性变化的通知机制

  10. 与文件上传到的三个类:FileItem类、ServletFileUpload 类、DiskFileItemFactory类

    文件上传: ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中, 在使用ServletFileUpload对象解析请求时需要根据DiskFi ...