Angular2 + Webpack項目搭建Demo

来源:http://www.cnblogs.com/yitim/archive/2017/02/18/angular2-demo-1.html
-Advertisement-
Play Games

本文將從頭開始編寫實際的代碼來完成一個angular2的demo。 題外話是其實angular2官網的快速開始項目已經很酷炫了,但其側重快速二字,只夠拿來練習玩耍,倒是github上確實已經有了一些不錯的angular2-starter。 1. 安裝必要的node環境與npm 當然TS環境也是必須的 ...


本文將從頭開始編寫實際的代碼來完成一個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 <[email protected]>",
 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以及幾個入口腳本:

/*
 * Angular bootstraping
 */
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { decorateModuleRef } from './app/environment';
import { bootloader } from '@angularclass/hmr';
/*
 * App Module
 * our top level module that holds all of our components
 */
import { AppModule } from './app';

/*
 * Bootstrap our Angular app with a top level NgModule
 */
export function main(): Promise<any> {
  return platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .then(decorateModuleRef)
    .catch((err) => console.error(err));
}

// needed for hmr
// in prod this is replace for document ready
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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、為什麼使用RequireJS? <script src="a.js"></script> <script src="b.js"></script> <script src="c.js"></script> <script src="b.js"></script> <script src="c.j ...
  • 個人在移動端的一些總結歸納,有新的知識點會一直更新 一.css部分 1.meta標簽 <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/> 移動端加上這個標簽才是真正的自適應,不加的 ...
  • 1 . 相對定位relative:顧名思義,相對定位是相對於自己的位置來進行偏移,如下圖: 以盒子中心為基準,為每條邊的正方向,例: 向右移動20px : 代碼為left:20px;或者right:-20px; 向下移動20px : 代碼為top:20px;或者bottom:-20px; 2 . 絕 ...
  • 直入正題,JS打開攝像頭並截圖上傳至後端的一個完整步驟 1. 打開攝像頭主要用到getUserMedia方法,然後將獲取到的媒體流置入video標簽 2. 截取圖片主要用到canvas繪圖,使用drawImage方法將video的內容繪至canvas中 3. 將截取的內容上傳至伺服器,將canvas ...
  • 下麵舉一些小例子: 先假設的創建一個上下文環境 1.canvas做灰色圖像: 個人認為主要的知識點在於: (1)獲取當前畫布中圖像的各個像素點的值; (2)灰色圖像的求解方式(r+g+b)/3,再將這個值賦給原來的像素的R、G、B; (3)在用新的顏色值畫一張圖片 2.canvas刮刮樂 個人認為主 ...
  • No1. 必須搭建java環境 只需要最基礎的java環境,也就是cmd下可以運行java和javac即可, 具體教程請自行百度,都會有很詳細的教程,這裡不重點介紹。 No2. 下載安裝HBuilder 請在這裡下載HBuilder:http://www.dcloud.io/, 下載完成後請將zip ...
  • [1]效果演示 [2]原理解釋 [3]具體實現 [4]插件代碼 ...
  • 一、this.xx 和 xx 是兩回事 受後端語言影響,總把this.xx 和xx 當中一回事,認為在function中,xx 就是this.xx,其實完全兩回事; this.xx 是沿著this 原型鏈找變數,xx是沿著作用域鏈找變數 var func = function(){ console. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...