Angular2是Google下一代MV*框架,用于构建复杂浏览器应用。Angular2给WEB或移动Apps带来了一揽子解决方案,从模板渲染到数据绑定,从Http服务到表单处理等等,总之,你想要的,Angular2基本上都已封装好了。
  万事始于Hello World,不论Angular2怎么牛,咱们先得把官方的例子跑起来再说。这里使用基于webpack创建Angular应用。

环境准备
  node v5.x.x
  npm v3.x.x
step1:创建并配置本项目
创建项目目录:

mkdir angular2Demo
cd angular2Demo

创建配置文件
典型的 Angular 项目需要一系列配置文件
package.json 用来标记出本项目所需的 npm 依赖包。
tsconfig.json 定义了 TypeScript 编译器如何从项目源文件生成 JavaScript 代码。
typings.json 为那些 TypeScript 编译器无法识别的库提供了额外的定义文件。
webpack.config.js为构建Angular应用所进行的一系列webpack配置。

package.json

{
  "name": "angular2demo","version": "1.0.0","description": "Angular 2 demo.","main": "index.js","scripts": { "start": "webpack-dev-server --inline --progress --port 8080","test": "karma start","build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail","postinstall": "typings install" },"dependencies": { "@angular/common": "2.0.0","@angular/compiler": "2.0.0","@angular/core": "2.0.0","@angular/forms": "2.0.0","@angular/http": "2.0.0","@angular/platform-browser": "2.0.0","@angular/platform-browser-dynamic": "2.0.0","@angular/router": "3.0.0","core-js": "^2.4.1","rxjs": "5.0.0-beta.12","zone.js": "^0.6.23" },"devDependencies": { "angular2-template-loader": "^0.4.0","awesome-typescript-loader": "^2.2.4","css-loader": "^0.23.1","extract-text-webpack-plugin": "^1.0.1","file-loader": "^0.8.5","html-loader": "^0.4.3","html-webpack-plugin": "^2.15.0","jasmine-core": "^2.4.1","karma": "^1.2.0","karma-jasmine": "^1.0.2","karma-phantomjs-launcher": "^1.0.2","karma-sourcemap-loader": "^0.3.7","karma-webpack": "^1.8.0","null-loader": "^0.1.1","phantomjs-prebuilt": "^2.1.7","raw-loader": "^0.5.1","rimraf": "^2.5.2","style-loader": "^0.13.1","typescript": "^2.0.2","typings": "^1.3.2","webpack": "^1.13.0","webpack-dev-server": "^1.14.1","webpack-merge": "^0.14.0" },"repository": { "type": "git","url": "git+https://github.com/HalZhan/angular2Demo.git" },"author": "halzhan","license": "MIT","bugs": { "url": "https://github.com/HalZhan/angular2Demo/issues" },"homepage": "https://github.com/HalZhan/angular2Demo#readme" }

tsconfig.json

{
  "compilerOptions": { "target": "es5","module": "commonjs","moduleResolution": "node","sourceMap": true,"emitDecoratorMetadata": true,"experimentalDecorators": true,"removeComments": false,"noImplicitAny": true,"suppressImplicitAnyIndexErrors": true } }

typings.json

{
  "globalDependencies": { "core-js": "registry:dt/core-js#0.0.0+20160725163759","jasmine": "registry:dt/jasmine#2.2.0+20160621224255","node": "registry:dt/node#6.0.0+20160909174046" } }

webpack.config.js

module.exports = require('./config/webpack.dev.js'); // 待补充

karma.conf.js

module.exports = require('./config/karma.conf.js'); // 待补充

下面我们继续完善配置文件。
公共配置
  我们可以为开发、产品和测试环境定义分别各自的配置文件。 但三者总会有一些公共配置。 于是我们把那些公共的配置收集到一个名叫 webpack.common.js 的独立文件中。

config/webpack.common.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');

module.exports = {
  entry: {
    'polyfills': './src/polyfills.ts',// 运行Angular时所需的一些标准js
    'vendor': './src/vendor.ts',// Angular、Lodash、bootstrap.css......
    'app': './src/main.ts' // 应用代码
  },resolve: {
    extensions: ['','.js','.ts'] // 加载的文件类型(明确的扩展名、.js、.ts)
  },module: {
    loaders: [
      {
        test: /\.ts$/,loaders: ['awesome-typescript-loader','angular2-template-loader' // 用于加载 Angular 组件的模板和样式
        ]
      },// ts - 将typescript代码转译成es5的加载器,由tsconfig.json文件指导
      {
        test: /\.html$/,loader: 'html' // 为组件模板准备的加载器
      },{
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,loader: 'file?name=assets/[name].[hash].[ext]' // 图片和字体文件也能被打包
      },{
        test: /\.css$/,exclude: helpers.root('src','app'),loader: ExtractTextPlugin.extract('style','css?sourceMap')
      },// 模式匹配应用级样式
      {
        test: /\.css$/,include: helpers.root('src',loader: 'raw'
      } // 模式匹配组件局部样式 ( 在组件元数据的 styleUrls 属性中指定的那些 ) 
    ]
  },plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: ['app','vendor','polyfills']
    }),// 提取公共代码

    new HtmlWebpackPlugin({
      template: 'src/index.html'
    }) // 自动向目标.html文件注入script和link标签
  ]
};

config/helpers.js

var path = require('path');
var _root = path.resolve(__dirname,'..');
function root(args) {
  args = Array.prototype.slice.call(arguments,0);
  return path.join.apply(path,[_root].concat(args));
}
exports.root = root;

开发环境配置
config/webpack.dev.js

var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

module.exports = webpackMerge(commonConfig,{
  devtool: 'cheap-module-eval-source-map',output: {
    path: helpers.root('dist'),publicPath: 'http://localhost:8080/',filename: '[name].js',chunkFilename: '[id].chunk.js'
  },plugins: [
    new ExtractTextPlugin('[name].css')
  ],devServer: {
    historyApiFallback: true,stats: 'minimal'
  }
});

产品环境配置
config/webpack.prod.js

var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig,{
  devtool: 'source-map',output: {
    path: helpers.root('dist'),publicPath: '/',filename: '[name].[hash].js',chunkFilename: '[id].[hash].chunk.js'
  },htmlLoader: {
    minimize: false // workaround for ng2
  },plugins: [
    new webpack.NoErrorsPlugin(),// 如果出现任何错误,就终止构建
    new webpack.optimize.DedupePlugin(),// 检测完全相同 ( 以及几乎完全相同 ) 的文件,并把它们从输出中移除
    new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
                                          // 最小化 (minify) 生成的包
      mangle: {
        keep_fnames: true
      }
    }),new ExtractTextPlugin('[name].[hash].css'),// 把内嵌的 css 抽取成外部文件,并为其文件名添加“缓存无效哈希”
    new webpack.DefinePlugin({ // 用来定义环境变量,以便我们在自己的程序中引用它
      'process.env': {
        'ENV': JSON.stringify(ENV)
      }
    })
  ]
});

(可选)测试环境配置
config/webpack.test.js

var helpers = require('./helpers');

module.exports = {
  devtool: 'inline-source-map',resolve: {
    extensions: ['','.ts','.js']
  },module: {
    loaders: [
      {
        test: /\.ts$/,loaders: ['awesome-typescript-loader','angular2-template-loader']
      },{
        test: /\.html$/,loader: 'html'

      },{
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,loader: 'null'
      },{
        test: /\.css$/,exclude: helpers.root('src',include: helpers.root('src',loader: 'raw'
      }
    ]
  }
}

(可选)Karma单元测试配置
config/karma.conf.js

var webpackConfig = require('./webpack.test');

module.exports = function (config) {
  var _config = {
    basePath: '',frameworks: ['jasmine'],files: [
      {pattern: './config/karma-test-shim.js',watched: false}
    ],preprocessors: {
      './config/karma-test-shim.js': ['webpack','sourcemap']
    },webpack: webpackConfig,webpackMiddleware: {
      stats: 'errors-only'
    },webpackServer: {
      noInfo: true
    },reporters: ['progress'],port: 9876,colors: true,logLevel: config.LOG_INFO,autoWatch: false,browsers: ['PhantomJS'],singleRun: true
  };

  config.set(_config);
};

config/karma-test-shim.js
  告诉 Karma 哪些文件需要预加载,首要的是:带有“测试版提供商”的 Angular 测试框架是每个应用都希望预加载的。

Error.stackTraceLimit = Infinity;

require('core-js/es6');
require('core-js/es7/reflect');

require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');

var appContext = require.context('../src',true,/\.spec\.ts/);

appContext.keys().forEach(appContext);

var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');

testing.Testbed.initTestEnvironment(browser.browserDynamicTestingModule,browser.platformbrowserDynamicTesting());

step2:编写源码
src/index.html

<!DOCTYPE html>
<html>
  <head>
    <base href="/">
    <title>Angular With Webpack</title>
    <Meta charset="UTF-8">
    <Meta name="viewport" content="width=device-width,initial-scale=1">
  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

src/main.ts

import { platformbrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app/app.module';
if (process.env.ENV === 'production') {
  enableProdMode();
}
platformbrowserDynamic().bootstrapModule(AppModule);

public/css/styles.css

body { background: #0147A7; color: #fff; }

src/app/app.component.ts

import { Component } from '@angular/core';
import '../../public/css/styles.css';
@Component({
  selector: 'my-app',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})
export class AppComponent { }

src/app/app.component.html
这里需要用到Angular Logo,下载后放入”public/images/”目录下。

<main>
  <h1>Hello from Angular App with Webpack</h1>
  <img src="../../public/images/angular.png">
</main>

src/app/app.component.css

main { padding: 1em; font-family: Arial,Helvetica,sans-serif; text-align: center; margin-top: 50px; display: block; }

(用于单元测试,可选)src/app/app.component.spec.ts

import { Testbed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('App',() => { beforeEach(() => { Testbed.configureTestingModule({ declarations: [AppComponent]}); }); it ('should work',() => { let fixture = Testbed.createComponent(AppComponent); expect(fixture.componentInstance instanceof AppComponent).toBe(true,'should create AppComponent'); }); });

src/app/app.module.ts

import { NgModule } from '@angular/core';
import { browserModule }  from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
  imports: [
    browserModule
  ],declarations: [
    AppComponent
  ],bootstrap: [ AppComponent ]
})
export class AppModule { }

src/vendor.ts

// Angular
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
// RxJS
import 'rxjs';
// Other vendors for example jQuery,Lodash or Bootstrap
// You can import js,ts,css,sass,...

src/polyfills.ts

import 'core-js/es6';
import 'core-js/es7/reflect';
require('zone.js/dist/zone');
if (process.env.ENV === 'production') {
  // Production
} else {
  // Development
  Error['stackTraceLimit'] = Infinity;
  require('zone.js/dist/long-stack-trace-zone');
}

step3:编译运行
1. 在项目根目录下,执行

webpack --progress --colors

(–progress –colors是为了查看进度,可以不用加)
2. 全局安装webpack-dev-server

npm install -g webpack-dev-server --verbose

(–verbose可以显示安装详细信息,可以不用加上)
3. 启动webpack server

webpack-dev-server --content-base dist/

(设置静态文件访问路径)

step4:查看结果
访问localhost:8080,如果一切顺利,我们能够看到最终的结果:

样例源码已托管至github,如有兴趣可自行clone

git clone https://github.com/HalZhan/angular2Demo.git

Angular2初探的更多相关文章

  1. html5录音功能实战示例

    这篇文章主要介绍了html5录音功能实战示例的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. 基于 HTML5 WebGL 实现的医疗物流系统

    物联网( IoT ),简单的理解就是物体之间通过互联网进行链接。这篇文章给大家介绍基于 HTML5 WebGL 实现的医疗物流系统,感兴趣的朋友跟随小编一起看看吧

  3. HTML5页面无缝闪开的问题及解决方案

    这篇文章主要介绍了HTML5页面无缝闪开方案,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. HTML5跳转小程序wx-open-launch-weapp的示例代码

    这篇文章主要介绍了HTML5跳转小程序wx-open-launch-weapp的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. iOS 10 Safari问题在DOM中不再包含元素

    使用此链接,您可以重现该错误.https://jsfiddle.net/pw7e2j3q/如果您点击元素并从dom中删除它,然后单击链接测试.你应该看到旧的元素弹出选择.是否有一些黑客来解决这个问题?解决方法我能够重现这个问题.问题是,每当您尝试删除其更改事件上的选择框时,iOS10都无法正确解除对选择框的绑定.要解决此问题,您需要将代码更改事件代码放在具有一些超时

  6. ios – 有没有办法针对存档版本(.ipa)运行XCTest(UI)?

    要么我们可以单独构建和测试,以便我们可以先构建并在以后对该构建进行测试吗?

  7. ios app如何“知道”运行单元测试

    我知道我可以用xcodebuild开始我的应用程序的单元测试,但我想知道是什么告诉应用程序在启动期间运行测试,它是一个发送到应用程序的特殊参数,还是以不同的方式编译以运行测试?

  8. ios – 如何在Swift中正确转换为子类?

    我有一个带有许多不同单元格的UITableView,基于数据源内容数组中的内容,它们应该显示自定义内容.在这里我得到了错误UITableViewCell没有属性customLabelQuestionTableViewCell有哪些.我的演员到QuestionTableViewCell有什么问题?解决方法问题不是你的演员,而是你的细胞宣言.您将其声明为可选的UITableViewCell,并且该声明

  9. xcode – 添加OCMock会导致Test启动主应用程序而不是运行测试

    我正在尝试将Ocmock添加到我现有的Cocoa项目中,但我遇到了一个我没有看到其他人覆盖的奇怪问题.我最终将它分离到以下内容:如果我只是将Ocmock.framework引用添加到我的项目中(即以某种方式将其拖到LinkBinaryWithLibraries构建阶段),当我运行测试时,真正的应用程序将被启动.没有Ocmock,输出正常:使用Ocmock框架链接(部分输出):此后,其他应用程序输出

  10. Xcode:用于条件DEBUG / TEST代码的预处理器宏

    我在我的代码(例如AppDelegate.m)中有不应该为单元测试编译的部分,例如当您在创建新项目时选择“添加单元测试”时,目标是由Xcode设置的.在项目文件中,我已将标志CONfigURATION_TESTS添加到内置目标的MyAppTests的预处理器宏中,但未添加到MyApp目标.这是我发现的许多帖子中的建议方式.但是这不起作用,因为(我猜)MyAppTests目标将MyApp目标作为依赖

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部