Angular2本身提供了cli命令行工具, 可以生成完整的工程.
但是命令行生成的工程太過複雜, 對於新學習Angular的用戶會有太多的干擾.
我們嘗試完全脫離cli工具, 只是通過TypeScript提供的tsc命令, 純手工構造一個極簡的Angular2示例.
完整代碼: http://git.oschina.net/chai2010/hello-ng2
配置淘寶的鏡像
通過以下命令安裝:
npm install -g cnpm --registry=https://registry.npm.taobao.org
完成後用 cnpm
代替 npm
命令.
HTML啓動頁面
首先構造一個 hello-ng2 目錄, 用於存放工程文件.
在目錄下創建 demo.html 頁面, 內容如下:
<!DOCTYPE html>
<head>
<title>Angular2應用</title>
</head>
<body>
<my-app>加載UI組件</my-app>
<script>require('./demo').main()</script>
</body>
我們採用的是HTML5語法, 完全省略了最外層沒有任何意義的<html></html>
標籤.
其中包含了一個我們自定義的<my-app>
標籤, 對應我們要創建的 Angular 窗口組件.
然後通過require
加載當前目錄下的demo
模塊(對應demo.js文件), 然後運行其中的main
函數啓動Angular程序.
Angular組件
Angular嚴重依賴ES7中的註解語法, 如果要在JS中使用該特性, 將需要一個轉碼工具將ES7註解語法轉爲ES2015或更早的格式, 因爲只有這樣才能在瀏覽器中正常運行.
雖然JS社區中已經存在了很多類似的轉碼工具(我本人將這個看作是一個編譯過程, 和將C/C++代碼轉爲exe類似), 但是依賴太多.
既然必需要引入一個轉碼工具, 強烈推薦使用TypeScript語言提供的tsc工具. 因爲TypeScript語言本身是Angular官方採用的語言, 同時也提供了註解等特性, 而且其提供的tsc工具沒有任何外部依賴(失控的依賴絕對是一個災難).
創建 demo.ts 文件, 並針對<my-app>
標籤創建一個 Angular 窗口組件:
import * as ngCore from '@angular/core'
@ngCore.Component({
selector: 'my-app',
template: `
<h1>你好, {{name}}! - V1</h1>
`,
styles: [
`h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}`,
],
})
export class MainComponent {
name = '世界'
}
Angular模塊
爲了使用該窗口部件, 我們需要將其組織到一個 Angular 模塊中:
import * as ngPlatformBrowser from '@angular/platform-browser'
@ngCore.NgModule({
imports: [ ngPlatformBrowser.BrowserModule ],
declarations: [ MainComponent ],
bootstrap: [ MainComponent ],
})
export class MainModule {
//
}
同樣, 我們通過 @ngCore.NgModule
註解將 Angular 的運行時模塊和 MainModule 類進行了關聯.
在模塊中, 我們導入了 ngPlatformBrowser.BrowserModule
瀏覽器模塊.
同時, declarations
部分聲明瞭我們自己創建的Angular組件.
最後, bootstrap
部分將 MainComponent 指定爲該模塊的引導組件.
需要說明的是, NgModule 修飾的模塊是一種運行時模塊, 同時用於其中各種組件名字空間的管理.
啓動Angular模塊
一個應用中可以有多個Angular 模塊, 同樣要指定一個引導模塊, 通過以下代碼完成:
import * as ngPlatformBrowserDynamic from '@angular/platform-browser-dynamic'
export function main() {
ngPlatformBrowserDynamic.platformBrowserDynamic().bootstrapModule(MainModule)
}
到此, 一個極簡的Angular2示例已經完成了. 但是還不能運行!
不能運行的原因主要有2個:
- 瀏覽器環境不支持模塊方式啓動頁面, 同樣需要通過外部js庫輔助.
- Angular 依賴一些高級的特性, 很多瀏覽器環境並不支持, 需要通過外部js庫模擬.
爲了簡化, 我們採用了Electron環境運行應用, 因爲在Electron環境我們可以直接使用NodeJS中的模塊. 對於第二點, 我們可以通過以下外部js庫模擬缺少的特性:
import 'core-js/es6/reflect'
import 'core-js/es7/reflect'
import 'zone.js/dist/zone'
Electron環境
現在 Angular2 部分的代碼已經完整. 我們還需要給 Electron 創建一個啓動腳本.
新建一個 index.ts 文件, 用於啓動Angular2程序:
import * as fs from 'fs'
import * as electron from 'electron'
let win: Electron.BrowserWindow = null
function createWindow() {
win = new electron.BrowserWindow({width: 800, height: 600})
win.loadURL(`file://${__dirname}/demo.html`)
win.webContents.openDevTools()
win.on('closed', () => { win = null })
}
function main() {
electron.app.on('ready', () => {
createWindow()
})
electron.app.on('activate', () => {
createWindow()
})
electron.app.on('window-all-closed', () => {
if(process.platform !== 'darwin') {
electron.app.quit()
}
})
}
if(require.main === module) {
main()
}
其中 BrowserWindow
對應一個 Electron 窗口, 創建窗口後通過 win.loadURL
加載了 demo.html
頁面.
其他配置文件
爲了運行應用, 我們還需要package.json和tsconfig.json文件, 分別對應NodeJS包和TypeScript的配置信息.
其中 package.json 文件千篇一律, 並沒有什麼特別之處. tsconfig.json文件則有一些需要定製的特性.
tsconfig.json 內容如下:
{
"include": [
"./**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
],
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"lib": ["dom", "es2016"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"suppressImplicitAnyIndexErrors":true,
"noStrictGenericChecks": true,
"noImplicitAny": false,
"target": "es5"
}
}
其中 include
表示用通配符選擇文件, exclude
表示排除的文件, compilerOptions
對應編譯選項.
在編譯選項中, 我們需要指定依賴的dom和es2016庫, experimentalDecorators表示註解功能也必須打開, emitDecoratorMetadata表示生成元信息也必須打開(元信息是反射特性所需要的).
其它的編譯參數用於可以根據需要自行調整.
運行
克隆完整代碼, 進入到對應目錄的命令行, 然後安裝依賴並運行:
cnpm install
node_modules\.bin\tsc
node_modules\.bin\electron .
運行效果圖:
OK!