Angular2 + Webpack项目搭建Demo
本文将从头开始编写实际的代码来完成一个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:
{
"name": "angular2-demo-yitim",
"version": "1.0.0",
"description": "angular2 demo by yitim",
"keywords": [
"angular2",
"webpack",
"typescript"
],
"author": "yitim <635928008@qq.com>",
"license": "MIT",
"scripts": {
"build:aot:prod": "npm run clean:dist && npm run clean:aot && webpack --config config/webpack.prod.js --progress --profile --bail",
"build:aot": "npm run build:aot:prod",
"build:dev": "npm run clean:dist && webpack --config config/webpack.dev.js --progress --profile",
"build:docker": "npm run build:prod && docker build -t angular2-webpack-start:latest .",
"build:prod": "npm run clean:dist && webpack --config config/webpack.prod.js --progress --profile --bail",
"build": "npm run build:dev",
"clean:dll": "npm run rimraf -- dll",
"clean:aot": "npm run rimraf -- compiled",
"clean:dist": "npm run rimraf -- dist",
"clean:install": "npm set progress=false && npm install",
"clean": "npm cache clean && npm run rimraf -- node_modules doc coverage dist compiled dll",
"docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
"lint": "npm run tslint \"src/**/*.ts\"",
"server:dev:hmr": "npm run server:dev -- --inline --hot",
"server:dev": "webpack-dev-server --config config/webpack.dev.js --open --progress --profile --watch --content-base src/",
"server:prod": "http-server dist -c-1 --cors",
"server": "npm run server:dev",
"start": "npm run server:dev",
"tslint": "tslint",
"version": "npm run build",
"watch:dev:hmr": "npm run watch:dev -- --hot",
"watch:dev": "npm run build:dev -- --watch",
"watch:prod": "npm run build:prod -- --watch",
"watch": "npm run watch:dev",
"webdriver-manager": "webdriver-manager",
"webdriver:start": "npm run webdriver-manager start",
"webdriver:update": "webdriver-manager update",
"webpack-dev-server": "webpack-dev-server",
"webpack": "webpack"
},
"dependencies": {
"@angular/common": "2.4.6",
"@angular/compiler": "2.4.6",
"@angular/core": "2.4.6",
"@angular/forms": "2.4.6",
"@angular/http": "2.4.6",
"@angular/platform-browser": "2.4.6",
"@angular/platform-browser-dynamic": "2.4.6",
"@angular/platform-server": "2.4.6",
"@angular/router": "3.4.6",
"@angularclass/conventions-loader": "^1.0.2",
"@angularclass/hmr": "~1.2.2",
"@angularclass/hmr-loader": "~3.0.2",
"core-js": "^2.4.1",
"crypto-browserify": "^3.11.0",
"crypto-js": "^3.1.9-1",
"http-server": "^0.9.0",
"ie-shim": "^0.1.0",
"reflect-metadata": "^0.1.9",
"rxjs": "5.0.2",
"zone.js": "0.7.6"
},
"devDependencies": {
"@angular/compiler-cli": "2.4.6",
"@types/hammerjs": "^2.0.33",
"@types/node": "^7.0.0",
"@types/selenium-webdriver": "~2.53.39",
"@types/source-map": "^0.5.0",
"@types/uglify-js": "^2.0.27",
"@types/webpack": "^2.0.0",
"add-asset-html-webpack-plugin": "^1.0.2",
"angular2-template-loader": "^0.6.0",
"assets-webpack-plugin": "^3.5.1",
"awesome-typescript-loader": "~3.0.0-beta.18",
"codelyzer": "~2.0.0-beta.4",
"copy-webpack-plugin": "^4.0.0",
"css-loader": "^0.26.0",
"exports-loader": "^0.6.3",
"expose-loader": "^0.7.1",
"extract-text-webpack-plugin": "~2.0.0-rc.2",
"file-loader": "^0.10.0",
"find-root": "^1.0.0",
"gh-pages": "^0.12.0",
"html-webpack-plugin": "^2.28.0",
"imports-loader": "^0.7.0",
"istanbul-instrumenter-loader": "1.2.0",
"json-loader": "^0.5.4",
"ng-router-loader": "^2.1.0",
"ngc-webpack": "1.1.0",
"npm-run-all": "^4.0.1",
"optimize-js-plugin": "0.0.4",
"parse5": "^3.0.1",
"protractor": "^4.0.14",
"raw-loader": "0.5.1",
"rimraf": "~2.5.4",
"sass-loader": "^4.1.1",
"script-ext-html-webpack-plugin": "^1.5.0",
"source-map-loader": "^0.1.5",
"string-replace-loader": "1.0.5",
"style-loader": "^0.13.1",
"to-string-loader": "^1.1.4",
"ts-node": "^2.0.0",
"tslib": "^1.5.0",
"tslint": "~4.4.2",
"tslint-loader": "^3.3.0",
"typedoc": "^0.5.3",
"typescript": "~2.1.5",
"url-loader": "^0.5.7",
"webpack": "2.2.0",
"webpack-dev-middleware": "^1.10.0",
"webpack-dev-server": "2.2.1",
"webpack-dll-bundles-plugin": "^1.0.0-beta.5",
"webpack-merge": "~2.6.1"
}
}
package.json
package.json用于管理npm依赖,然后还需要tsconfig.json来配置TS,以及tsconfig.webpack.json来配合webpack编译:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"noEmit": true,
"noEmitHelpers": true,
"importHelpers": true,
"strictNullChecks": false,
"lib": [
"dom",
"es6"
],
"typeRoots": [
"node_modules/@types",
"./typings/**/*.d.ts",
"../vendor/tslib/tslib.d.ts"
],
"types": [
"hammerjs",
"node",
"source-map",
"uglify-js",
"webpack"
]
},
"exclude": [
"node_modules",
"dist"
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"noEmit": true,
"noEmitHelpers": true,
"importHelpers": true,
"strictNullChecks": false,
"lib": [
"es2015",
"dom"
],
"typeRoots": [
"node_modules/@types"
],
"types": [
"hammerjs",
"node"
]
},
"exclude": [
"node_modules",
"dist",
"src/**/*.spec.ts",
"src/**/*.e2e.ts"
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"angularCompilerOptions": {
"genDir": "./compiled",
"skipMetadataEmit": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
tsconfig.webpack.json
然后是webpack的配置文件,入口为webpack.config.js:
// Look in ./config folder for webpack.dev.js
switch (process.env.NODE_ENV) {
case 'prod':
case 'production':
module.exports = require('./config/webpack.prod')({env: 'production'});
break;
case 'dev':
case 'development':
default:
module.exports = require('./config/webpack.dev')({env: 'development'});
}
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
// TODO(gdi2290): switch to DLLs // Polyfills // import 'ie-shim'; // Internet Explorer 9 support // import 'core-js/es6';
// Added parts of es6 which are necessary for your project or your browser support requirements.
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/weak-map';
import 'core-js/es6/weak-set';
import 'core-js/es6/typed';
import 'core-js/es6/reflect';
// see issue https://github.com/AngularClass/angular2-webpack-starter/issues/709
// import 'core-js/es6/promise'; import 'core-js/es7/reflect';
import 'zone.js/dist/zone'; if ('production' === ENV) {
// Production } else { // Development
Error.stackTraceLimit = Infinity; /* tslint:disable no-var-requires */
require('zone.js/dist/long-stack-trace-zone'); }
polyfills.browser.ts
前者的作用是引导angular2程序的运行,后者的作用是管理angular2的所有依赖(由于angular2使用了很多ES新特性,所以需要一些依赖来扩展不支持新特性的浏览器的功能)。
实际代码可能还需要有aot模式的引导文件(预编译模式,更适用于生产环境,效率高非常多),以及一个自定义的类型声明文件(帮助编写TS代码)。
5. 实际要写的代码——app目录与assets目录
配置好所有东西后,就轮到亲手来写angular2代码了,专门新建一个app目录来存放这些代码,以及一个assets文件来存放静态资源。
一个最简单的angular2项目需要以下几个文件:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import { AppComponent } from './app.component';
import { ENV_PROVIDERS } from './environment'; @NgModule({
bootstrap: [ AppComponent ],
declarations: [ AppComponent],
imports: [
BrowserModule
],
providers: [ ENV_PROVIDERS ]
})
export class AppModule { }
app.module.ts
import {
Component, OnInit, ViewEncapsulation
} from '@angular/core'; @Component({
selector: 'my-app',
template: `<h1>Hello World!</h1>`,
})
export class AppComponent implements OnInit { public ngOnInit() {
console.log('load app.component');
}
}
app.component.ts
一个是根模块一个是根组件,在此先不提angular2具体语法,先把项目成功运行起来为重。
为了让webpack找到我们的angular2代码,以及成功引导angular2项目,还必须添加一个环境文件以及一个索引文件:
// App
export * from './app.module';
index.ts
// Angular 2
import {
enableDebugTools,
disableDebugTools
} from '@angular/platform-browser';
import {
ApplicationRef,
enableProdMode
} from '@angular/core';
// Environment Providers
let PROVIDERS: any[] = [
// common env directives
]; // Angular debug tools in the dev console
// https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md
let _decorateModuleRef = <T>(value: T): T => { return value; }; if ('production' === ENV) {
enableProdMode(); // Production
_decorateModuleRef = (modRef: any) => {
disableDebugTools(); return modRef;
}; PROVIDERS = [
...PROVIDERS,
// custom providers in production
]; } else { _decorateModuleRef = (modRef: any) => {
const appRef = modRef.injector.get(ApplicationRef);
const cmpRef = appRef.components[0]; let _ng = (<any> window).ng;
enableDebugTools(cmpRef);
(<any> window).ng.probe = _ng.probe;
(<any> window).ng.coreTokens = _ng.coreTokens;
return modRef;
}; // Development
PROVIDERS = [
...PROVIDERS,
// custom providers in development
]; } export const decorateModuleRef = _decorateModuleRef; export const ENV_PROVIDERS = [
...PROVIDERS
];
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的更多相关文章
- angular2+webpack的搭建过程遇到的问题记录
最近在由于公司的项目要重构,Superiors要求将原先的Ionic1+angular1+gulp用全新的Ionic2+angular2+webpack重构.苦逼的Google了好久,环境搭建还是不太 ...
- (转)windows环境vue+webpack项目搭建
首先,vue.js是一种前端框架,一般利用vue创建项目是要搭配webpack项目构建工具的,而webpack在执行打包压缩的时候是依赖node.js的环境的,所以,要进行vue项目的开发,我们首先要 ...
- vue-cli2.0+webpack 项目搭建
一:准备工作 安装nodejs + 安装webpack + 配置环境变量 => 确保在dos界面的任何路径都都可直接使用命令 二:搭建项目 1.全局安装vue脚手架 [DOS界面] npm i ...
- webpack项目搭建
1.新建一个文件目录,命令行进入当前目录,输入npm init 创建package.json文件 2.安装项目依赖webpack模块: npm install webpack --save-dev 3 ...
- 从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(一)
摘要:随着前端技术的飞速发展,越来越多的技术领域开始被前端工程师踏足.从NodeJs问世至今,各种前端工具脚手架.服务端框架层出不穷,“全栈工程师”对于前端开发者来说,再也不只是说说而已.在NodeJ ...
- 【原创】从零开始搭建Electron+Vue+Webpack项目框架(六)Electron打包,同时构建客户端和web端
导航: (一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更 ...
- 使用 webpack 手动搭建 vue 项目
webpack 是一个前端工程化打包工具,对于前端工程师来说 webpack 是一项十分重要的技能.下面我们就通过搭建一个 vue 项目来学习使用 webpack 主要环境: node v14.15. ...
- 从零搭建基于webpack的Electron-Vue3项目(1)——基于webpack的Vue3项目搭建
从零搭建基于webpack的Electron-Vue3项目(1)--基于webpack的Vue3项目搭建 前言 本篇文章内容,主要是基于webpack的Vue3项目开发环境进行搭建,暂时还不涉及到El ...
- 搭建自己的Webpack项目
五,搭建自己的Webpack项目 https://www.jianshu.com/p/42e11515c10f
随机推荐
- iOS通过代码关闭程序
//-------------------------------- 退出程序 -----------------------------------------// - (void)exitAppl ...
- mysql 安装错误 解决方法
错误及警告信息:TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_time ...
- RTMP开发记录 测试服务器搭建篇
nginx-rtmp-module 安装 最近在做直播功能,为了方便调试,在本地搭建一个rtmp server吧~ 我的配置环境是Ubuntu12.04 64 安装编译环境所需库 sudo apt-g ...
- JavaScript DOM节点操作总结
节点类型 节点类型主要有三种:元素节点,属性节点和文本节点. 而对DOM的主要也就是围绕元素节点和属性节点的增删改查.下面就分别从对元素节点的操作和对属性节点的操作来介绍. 元素节点 查 在对DOM进 ...
- Java XML解析器
使用Apache Xerces解析XML文档 一.技术概述 在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组 ...
- bzoj2120: 数颜色 &&bzoj2453: 维护队列
题目大意: 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好 ...
- javascript 备忘录
JS语法 javascript 对象: var cars=new Array("Audi","BMW","Volvo"); 声明变量类型 当 ...
- DELPHI中MessageBox的用法
MessageBox对话框 输入控件的 ImeName属性把输入法去掉就默认为英文输入了 MessageBox对话框是比较常用的一个信息对话框,其不仅能够定义显示的信息内容.信息提示图标,而且可以 ...
- PHP 绘图技术
1.图片格式:目前网站开发常见的图片格式有gif,jpg/jpeg,png ..... 区别: gif 图片压缩率高,但是只能显示256色,可能造成颜色的丢失,可以显示动画 jpg/jpeg 图片压缩 ...
- HDU1217:Arbitrage(SPFA)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1217 题目大意 在每种钱币间进行各种交换,最后换回自己如果能赚,那么就Yes,否则No 注意应为有负权 ...