Archive for 十二月 2016

Angular2 Material Design开发环境搭建

Angular2和Angular1有什么区别?就是Java和Javascript,雷锋和雷锋塔的区别。刚会用Angular1做些小项目,发现Angular2来了,据说性能上提升还是蛮多,所以还是从0开始吧。Angular2虽然还是支持用es5代码开发,但连官方教程都已经用TypeScript,对于之前没有接触过的人来说,学习还是有些成本的。

作为一个新手,搭建环境还是折腾了很久,所以记录下来方便其他新手。

流程:

  1. 使用angular-cli创建项目
  2. 集成Angular Material

angular-cli和Angular Material目前都还在beta阶段,毕竟Angular2正式发布也没有很久,用于生产请自己斟酌。

创建Angular2项目

  1. 安装angular-cli
    npm install -g angular-cli
    
  2. 在适当的位置创建项目
    ng new angular2Demo
    cd angular2Demo
    ng serve
    

创建过程会自动使用npm下载依赖,ng serve即启动内置的服务器,默认端口4200。使用浏览器打开 http://localhost:4200,可以看到项目已经启起来了。

此时打开chrome的network,可以发现有个vendor.bundle.js特别大,有2M多,图上4M多是因为我已经加了Material库。这是webpack把所有依赖的库都打包在一起了,而且没有任何压缩。

image

显然这么大的文件放到生产环境中是不合适的。这是因为默认情况下,启动的是开发模式。

生成生产环境代码:

ng build --prod --env=prod

执行后,会在项目根目录下生成dist目录,所有优化后的代码

以生产模式启动服务器

ng serve --prod

再看network,发现所有资源自动打上了版本号vendor.xxx.bundle.js也被压到了200多k。

集成Material

  1. 安装

Material是以组件的形式开发的,所以安装也使用npm

npm install --save @angular/material

2.修改app.module.ts

打开src/app/app.module.ts,引入material模块

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { MaterialModule } from '@angular/material';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MaterialModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. 引入css样式

在src目录下新建material-design.scss:

@import '~@angular/material/core/theming/all-theme';

// NOTE: Theming is currently experimental and not yet publically released!
@include md-core();
$primary: md-palette($md-deep-purple);
$accent:  md-palette($md-amber, A200, A100, A400);
$theme: md-light-theme($primary, $accent);
@include angular-material-theme($theme);
.m2app-dark {
  $dark-primary: md-palette($md-pink, 700, 500, 900);
  $dark-accent:  md-palette($md-blue-grey, A200, A100, A400);
  $dark-warn:    md-palette($md-deep-orange);
  $dark-theme: md-dark-theme($dark-primary, $dark-accent, $dark-warn);
  @include angular-material-theme($dark-theme);
}

打开根目录下的angular-cli.json,styles配置增加刚刚的文件

"apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "mobile": false,
      "styles": [
        "styles.css",
        "material-design.scss"
      ],
      "scripts": [],
      "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  1. 配置MaterialDesign字体

index.html增加:

    <link href="//fonts.lug.ustc.edu.cn/icon?family=Material+Icons" rel="stylesheet">

使用了中科大的google font镜像

  1. 如果需要用到md-slider(可拖动的进度条)和md-slide-toggle(带滑动动画的开关),还需要安装HammerJS,否则到此环境搭建已完成。
    
    npm install hammerjs  --save 
    npm install @types/hammerjs --save-dev 
    

修改src/app/app,module.ts,引入hammerjs

import 'hammerjs';

修改src/tsconfig.json,配置types增加hammerjs

{
  "compilerOptions": {
    "baseUrl": "",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es6", "dom"],
    "mapRoot": "./",
    "module": "es6",
    "moduleResolution": "node",
    "outDir": "../dist/out-tsc",
    "sourceMap": true,
    "target": "es5",
    "typeRoots": [
      "../node_modules/@types"
    ],
    "types": [
      "hammerjs"
    ]
  }
}

所有配置到此结束,我们写一段简单的代码测试一下。
编辑src/app/app.component.html:

<md-progress-spinner mode="indeterminate" ></md-progress-spinner>

启动服务器,如果所有配置没有错,页面上应该显示旋转的进度圈。

使用SSH实现内网穿透

前面写过一篇使用ngrok实现外网访问内网的文章,但实现起来稍复杂,而且我在实际使用过程中也发现经常断线,ngrok+nginx 实现内网穿透 共用80端口,ngrok的优点在于独立于任何其他服务,需要转发什么域名直接改客户端配置。

今天介绍的是通过SSH穿透内网

SSH内网穿透优点

  1. 无需额外安装服务端客户端(ssh你机器上肯定有)
  2. 可以转发到所以你的机器能直接访问的机器上(你可以给在同一局域网的前端妹子配个外网可访问域名,不用在她的电脑上配置,如果觉得浪费了搭讪机会,可以在她电脑上随便敲点啥)

缺点

如果要将这个功能开放给别人,要注意配置ssh账号权限,自己用无所谓。

一条命令实现

ssh -CfnNT -R 6666:192.168.10.120:8080 fff@server1.pocketdigi.com -p 4356
  • 6666:外网服务器的端口号,外网服务器所有6666的请求会转发
  • 192.168.10.120 转发目标机器,本机就是localhost
  • fff ssh账号
  • server1.pocketdigi.com 外网服务器域名
  • 4356 外网服务器的ssh端口号,默认是22,总有一班人天天扫,所以改了

此时所有访问server1.pocketdigi.com:6666的请求会转发到192.168.10.120:8080,可在外网服务器上执行

curl http://localhost:6666

查看,如果192.168.10.120:8080启了http服务,应该能看到.
鉴于ssh会超时断开,建议使用autossh,断开会自动重连

配置nginx

参考 ngrok+nginx 实现内网穿透 共用80端口

开机自启

  1. 增加启动文件 /usr/local/bin/nat_forward

    !/bin/bash

    autossh -M 5678 -CfnNT -R 6666:localhost:8080 fff@server1.pocketdigi.com -p 4356

2.增加执行权限

sudo chmod +x /usr/local/bin/nat_forward

3.增加启动项

偏好设置--用户与群组--登录项,添加/usr/local/bin/nat_forward

阿里云oss grunt上传插件

最近在研究前端工程化,准备把项目里的静态文件全传到阿里云 oss上,构建工具我们选的是grunt,npm里也有两三个oss上传插件,但是更新时间都比较久了,一一试过后都不能用,于是自己写了个插件。托管在 https://github.com/pocketdigi/grunt-aliyun-oss , 欢迎体验。
支持ContentType自动识别,Cache Control设置,上传路径设置。

grunt-aliyun-oss

aliyun oss plugin for grunt

Getting Started

This plugin requires Grunt ~0.4.5

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-aliyun-oss --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-aliyun-oss');

The "aliyun_oss" task

Overview

In your project's Gruntfile, add a section named aliyun_oss to the data object passed into grunt.initConfig().

grunt.initConfig({
  aliyun_oss: {
    options: {
      accessKeyId: 'accessKeyId',
      secretAccessKey: 'secretAccessKey',
      endpoint: 'http://oss-cn-hangzhou.aliyuncs.com',
      bucketName:'bucket',
      cacheControl:'no-cache'
    },
    your_target: {
      // Target-specific file lists and/or options go here.
    },
  },
});

AliYun OSS Api doc

Options

options.accessKeyId

Type: String

AliYun OSS accessKeyId

options.secretAccessKey

Type: String

AliYun OSS secretAccessKey

options.endpoint

Type: String

AliYun OSS endpoint

options.bucketName

Type: String

AliYun OSS bucketName

options.bucketName

Type: String Default value:no-cache

Cache Control in the Http Header,default value is no-cache

See Http Cache

Usage Examples

Default Options

In this example, the default options are used to upload all file expect html file in dist directory to oss bucket1 bucket,and the oss root path is static/

grunt.initConfig({
   aliyun_oss: {
              default_options: {
                  options: {
                      accessKeyId: 'xxxx',
                      secretAccessKey: 'xxxx',
                      endpoint: 'http://oss-cn-hangzhou.aliyuncs.com',
                      bucketName:'bucket1',
                      cacheControl:'no-cache'
                  },
                  files: [
                      {
                          expand: true,
                          cwd: 'dist',
                          src: ['**/*','!**/*.html'],
                          dest:'static/'
                      }
                  ]
              }
          }
});

Release History

  • v0.2.0 fix upload bug,support ContentType,cache control.
  • v0.1.0 first version