zxhfighter
5/12/2017 - 7:37 AM

angular cli 生成模板定制化

angular cli 生成模板定制化

angular-cli 生成模板定制化

使用 ng g c 命令生成组件或者其他模块时,默认使用两个空格,并且 {} 左右都有空格。

如果公司规范需要使用四个空格,并且大括号旁边不能有空格怎么办?

人肉修复

最低级的方式,就是定位到各个地方去手动修改,耗时耗力!

格式化修复

比较高级点的方式,就是使用编辑器来进行自动格式化,例如使用 vscode。不过在使用 vscode 格式化之前,还需要修改相关配置,例如:

// 大括号两边不出现空格
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false

该方式只需要在写好代码后,最后运行一次格式化就行,相对来说比较省心。

高级修复

再高级一点的方式,就是修改 angular-cli 源码的模板!!!

angular-cli 的模板位于 node_modules/@angular/cli/blueprints 中。

.
├── class
├── component
├── directive
├── enum
├── guard
├── interface
├── module
├── ng
├── pipe
└── service

打开 node_modules/@angular/cli/blueprints/component/files/__name__.component.ts

import { Component, OnInit<% if(viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection) { %>, ChangeDetectionStrategy<% }%> } from '@angular/core';

@Component({
  selector: '<%= selector %>',<% if(inlineTemplate) { %>
  template: `
    <p>
        <%= dasherizedModuleName %> Works!
    </p>
  `,<% } else { %>
  templateUrl: './<%= dasherizedModuleName %>.component.html',<% } if(inlineStyle) { %>
  styles: []<% } else { %>
  styleUrls: ['./<%= dasherizedModuleName %>.component.<%= styleExt %>']<% } %><% if(viewEncapsulation) { %>
  encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection) { %>,
  changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
export class <%= classifiedModuleName %>Component implements OnInit {

  constructor() { }

  ngOnInit() {
  }
}

不难看出,这里使用的都是两个空格,将其修改如下:

import {Component, OnInit<% if(viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection) { %>, ChangeDetectionStrategy<% }%>} from '@angular/core';

@Component({
    selector: '<%= selector %>',<% if(inlineTemplate) { %>
    template: `
        <p>
            <%= dasherizedModuleName %> Works!
        </p>
    `,<% } else { %>
    templateUrl: './<%= dasherizedModuleName %>.component.html',<% } if(inlineStyle) { %>
    styles: []<% } else { %>
    styleUrls: ['./<%= dasherizedModuleName %>.component.<%= styleExt %>']<% } %><% if(viewEncapsulation) { %>,
    encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection) { %>,
    changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
export class <%= classifiedModuleName %>Component implements OnInit {

    constructor() { }

    ngOnInit() {

    }
}

完美!

不过完美中的不完美是,每次启动一个新项目时,都需要进行一次配置,不过这里配置的时间,与你每次去修改文件格式的时间,完全可以忽略不计!

更高级修复

那就是,自己写个模板生成脚本!

首先定义一个模板文件,例如:

/**
 * @file component <%= name %>
 * @author xiaoming
 */

import {Component, Input, Output} from '@angular/core';

@Component({
    selector: '<%= name %>',
    templateUrl: './<%= name %>.component.tpl.html',
    styleUrls: ['./<%= name %>.component.less']
})
export class <%= upperCaseName %>Component {
    name = '<%= name %>';
}

其中的 <%= name %> 参数是生成时指定需要替换的名称。

const gulp = require('gulp');
const template = require('gulp-template');
const rename = require('gulp-rename');
const yargs = require('yargs');

// 快捷生成组件,使用方式:
// 1. gulp component --name region-list
//    默认会在 app/src/ui 目录下新建 region-list 组件
//
// 2. gulp component --name region-list --parent ../common/component
//    这样会在与 app/src/common/component 下新建 region-list 组件
gulp.task('component', () => {
    const cap = val => {
        return val
            .split('-')
            .map(item => item.charAt(0).toUpperCase() + item.slice(1))
            .join('');
    };
    const ui = resolve('app/src/ui');
    const name = yargs.argv.name;
    const parentPath = yargs.argv.parent || '';
    const destPath = path.join(ui, parentPath, name);
    const tpl = resolve('config/generator/component/**/*.**');

    return gulp.src(tpl)
        .pipe(template({
            name: name,
            upperCaseName: cap(name)
        }))
        .pipe(rename(path => {
            path.basename = path.basename.replace('temp', name);
        }))
        .pipe(gulp.dest(destPath));
});

此方法由于适用范围广,可以定制任意项目任意格式文件,因此属于最高级的方式。