forked from NG-ZORRO/ng-zorro-antd
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ng:schematic): support ng add & ng generate (NG-ZORRO#1430)
close NG-ZORRO#1405
- Loading branch information
Showing
35 changed files
with
2,022 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# ng-zorro-antd Schematics | ||
|
||
## Schematics | ||
|
||
### ng-add | ||
|
||
添加 ng-zorro-antd 与它的依赖,并根据需要自动配置。 | ||
|
||
- 添加 ng-zorro-antd 到 `package.json` | ||
- 替换 `app.component.html` 引导内容 | ||
- 在根模块导入必要的模块 | ||
- 进行国际化配置 | ||
- 将用于自定义的 `theme.less` 或编译后的 css 导入 `angular.json` | ||
|
||
```bash | ||
$ ng add ng-zorro-antd [--locale=zh-CN] [--theme] [--skipPackageJson] | ||
``` | ||
|
||
## 开发 | ||
|
||
### 脚本 | ||
|
||
- `npm run schematic:build` 编译到 publish 文件夹 | ||
- `npm run schematic:demo` 从 demo 生成 schematics | ||
- `node ./schematics_script/set-version.js` 从 package.json 设置版本号 | ||
- `node ./schematics_script/set-theme.js` 从 site_scripts/_site/src/theme.less 设置自定义样式内容 | ||
|
||
### 开发 | ||
|
||
只有首次运行才需要以下步骤。 | ||
|
||
1. 运行 `npm run generate` 生成 `publish` 文件夹 | ||
2. `cd publish && npm link` | ||
3. `ng new schematic-debug` | ||
4. `cd schematic-debug && npm link ng-zorro-antd` | ||
|
||
调试 | ||
|
||
1. `cd schematic-debug` | ||
1. `git checkout . && git clean -fd` | ||
1. `ng g ng-zorro-antd:[schematics]` | ||
|
||
发布 | ||
|
||
原有发布流程不变,但是 `schematics/utils/custom-theme.ts` 和 `schematics/utils/lib-versions.ts` 内容为动态生成,不提交到版本管理。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"$schema": "./node_modules/@angular-devkit/schematics/collection-schema.json", | ||
"schematics": { | ||
"ng-add": { | ||
"description": "add NG-ZORRO", | ||
"factory": "./ng-add", | ||
"schema": "./ng-add/schema.json" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
import { chain, noop, Rule, SchematicsException, SchematicContext, Tree } from '@angular-devkit/schematics'; | ||
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; | ||
import * as ts from 'typescript'; | ||
import { addModuleImportToRootModule, getSourceFile } from '../utils/ast'; | ||
import { createCustomTheme } from '../utils/custom-theme'; | ||
import { addSymbolToNgModuleMetadata, findNodes, insertAfterLastOccurrence } from '../utils/devkit-utils/ast-utils'; | ||
import { InsertChange } from '../utils/devkit-utils/change'; | ||
import { getProjectFromWorkspace, getWorkspace, Project, Workspace } from '../utils/devkit-utils/config'; | ||
import { getAppModulePath } from '../utils/devkit-utils/ng-ast-utils'; | ||
import { insertImport } from '../utils/devkit-utils/route-utils'; | ||
import { zorroVersion } from '../utils/lib-versions'; | ||
import { addPackageToPackageJson } from '../utils/package'; | ||
import { Schema } from './schema'; | ||
|
||
export default function (options: Schema): Rule { | ||
return chain([ | ||
options && options.skipPackageJson ? noop() : addZorroToPackageJson(), | ||
options && options.theme ? downgradeLess() : noop(), | ||
setBootstrapPage(), | ||
addThemeToAppStyles(options), | ||
addModulesToAppModule(options), | ||
addI18n(options), | ||
(options && !options.skipPackageJson) || (options && !options.theme) ? installNodeDeps() : noop() | ||
]); | ||
} | ||
|
||
/** 添加 i18n 配置, 取决于 options.locale */ | ||
function addI18n(options: Schema): (host: Tree) => Tree { | ||
return function (host: Tree): Tree { | ||
const workspace = getWorkspace(host); | ||
const project = getProjectFromWorkspace(workspace, options.project); | ||
const modulePath = getAppModulePath(host, project.architect.build.options.main); | ||
const moduleSource = getSourceFile(host, modulePath); | ||
const locale = options.locale; | ||
const localePrefix = locale.split('_')[0]; | ||
|
||
if (!moduleSource) { | ||
throw new SchematicsException(`Module not found: ${modulePath}`); | ||
} | ||
|
||
if (!locale) { | ||
throw new SchematicsException(`Invalid locale-symbol`); | ||
} | ||
|
||
const allImports = findNodes(moduleSource, ts.SyntaxKind.ImportDeclaration); | ||
|
||
const changes = [ | ||
insertImport(moduleSource, modulePath, 'NZ_I18N', 'ng-zorro-antd'), | ||
insertImport(moduleSource, modulePath, locale, 'ng-zorro-antd'), | ||
insertImport(moduleSource, modulePath, 'registerLocaleData', '@angular/common'), | ||
insertImport(moduleSource, modulePath, localePrefix, `@angular/common/locales/${localePrefix}`, true), | ||
...addSymbolToNgModuleMetadata(moduleSource, modulePath, 'providers', `{ provide: NZ_I18N, useValue: ${locale} }`, null), | ||
insertAfterLastOccurrence(allImports, `\n\nregisterLocaleData(${localePrefix});`, modulePath, 0) | ||
]; | ||
|
||
const recorder = host.beginUpdate(modulePath); | ||
changes.forEach((change) => { | ||
if (change instanceof InsertChange) { | ||
recorder.insertLeft(change.pos, change.toAdd); | ||
} | ||
}); | ||
|
||
host.commitUpdate(recorder); | ||
return host; | ||
}; | ||
} | ||
|
||
/** 降级 less */ | ||
function downgradeLess(): (host: Tree) => Tree { | ||
return (host: Tree) => { | ||
addPackageToPackageJson(host, 'dependencies', 'less', '^2.7.3'); | ||
return host; | ||
}; | ||
} | ||
|
||
/** 添加 ng-zorro-antd 到 package.json 的 dependencies */ | ||
function addZorroToPackageJson(): (host: Tree) => Tree { | ||
return (host: Tree) => { | ||
addPackageToPackageJson(host, 'dependencies', 'ng-zorro-antd', zorroVersion); | ||
return host; | ||
}; | ||
} | ||
|
||
/** 添加 BrowserAnimationsModule FormsModule HttpClientModule NgZorroAntdModule 到 app.module */ | ||
function addModulesToAppModule(options: Schema): (host: Tree) => Tree { | ||
return (host: Tree) => { | ||
const workspace = getWorkspace(host); | ||
const project = getProjectFromWorkspace(workspace, options.project); | ||
|
||
addModuleImportToRootModule(host, 'BrowserAnimationsModule', '@angular/platform-browser/animations', project); | ||
addModuleImportToRootModule(host, 'FormsModule', '@angular/forms', project); | ||
addModuleImportToRootModule(host, 'HttpClientModule', '@angular/common/http', project); | ||
addModuleImportToRootModule(host, 'NgZorroAntdModule.forRoot()', 'ng-zorro-antd', project); | ||
|
||
return host; | ||
}; | ||
} | ||
|
||
/** 添加样式配置 */ | ||
export function addThemeToAppStyles(options: Schema): (host: Tree) => Tree { | ||
return function (host: Tree): Tree { | ||
const workspace = getWorkspace(host); | ||
const project = getProjectFromWorkspace(workspace, options.project); | ||
if (options.theme) { | ||
insertCustomTheme(project, host, workspace); | ||
} else { | ||
insertCompiledTheme(project, host, workspace); | ||
} | ||
return host; | ||
}; | ||
} | ||
|
||
/** 将预设样式写入 theme.less,并添加到 angular.json */ | ||
function insertCustomTheme(project: Project, host: Tree, workspace: Workspace): void { | ||
const themePath = 'src/theme.less'; | ||
host.create(themePath, createCustomTheme()); | ||
if (project.architect) { | ||
addStyleToTarget(project.architect.build, host, themePath, workspace); | ||
addStyleToTarget(project.architect.test, host, themePath, workspace); | ||
} else { | ||
throw new SchematicsException(`${project.name} does not have an architect configuration`); | ||
} | ||
} | ||
|
||
/** 设置引导页面到 app.component.ts */ | ||
function setBootstrapPage(): (host: Tree) => Tree { | ||
return (host: Tree) => { | ||
host.overwrite('src/app/app.component.html', `<a href="https://github.com/NG-ZORRO/ng-zorro-antd" target="_blank" style="display: flex;align-items: center;justify-content: center;height: 100%;width: 100%;"> | ||
<img height="400" src="https://img.alicdn.com/tfs/TB1MGSRv21TBuNjy0FjXXajyXXa-89-131.svg"> | ||
</a> | ||
`); | ||
return host; | ||
}; | ||
|
||
} | ||
|
||
/** 安装依赖 */ | ||
function installNodeDeps(): (host: Tree, context: SchematicContext) => void { | ||
return (host: Tree, context: SchematicContext) => { | ||
context.addTask(new NodePackageInstallTask()); | ||
}; | ||
} | ||
|
||
/** 将编译的 css 添加到 angular.json */ | ||
function insertCompiledTheme(project: Project, host: Tree, workspace: Workspace): void { | ||
const themePath = `node_modules/ng-zorro-antd/src/ng-zorro-antd.min.css`; | ||
|
||
if (project.architect) { | ||
addStyleToTarget(project.architect.build, host, themePath, workspace); | ||
addStyleToTarget(project.architect.test, host, themePath, workspace); | ||
} else { | ||
throw new SchematicsException(`${project.name} does not have an architect configuration`); | ||
} | ||
} | ||
|
||
/** Adds a style entry to the given target. */ | ||
function addStyleToTarget(target: any, host: Tree, asset: string, workspace: Workspace): void { | ||
const styleEntry = asset; | ||
|
||
// We can't assume that any of these properties are defined, so safely add them as we go | ||
// if necessary. | ||
if (!target.options) { | ||
target.options = { styles: [ styleEntry ] }; | ||
} else if (!target.options.styles) { | ||
target.options.styles = [ styleEntry ]; | ||
} else { | ||
const existingStyles = target.options.styles.map(s => typeof s === 'string' ? s : s.input); | ||
const hasGivenTheme = existingStyles.find(s => s.includes(asset)); | ||
|
||
if (!hasGivenTheme) { | ||
target.options.styles.splice(0, 0, styleEntry); | ||
} | ||
} | ||
|
||
host.overwrite('angular.json', JSON.stringify(workspace, null, 2)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"$schema": "http://json-schema.org/schema", | ||
"id": "ngAdd", | ||
"title": "add NG-ZORRO", | ||
"type": "object", | ||
"properties": { | ||
"skipPackageJson": { | ||
"type": "boolean", | ||
"default": false, | ||
"description": "Do not add ng-zorro dependencies to package.json (e.g., --skipPackageJson)" | ||
}, | ||
"locale": { | ||
"type": "string", | ||
"default": "zh_CN", | ||
"enum": ["ar_EG","bg_BG","ca_ES","cs_CZ","de_DE","el_GR","en_GB","en_US","es_ES","et_EE","fa_IR","fi_FI","fr_BE","fr_FR","is_IS","it_IT","ja_JP","ko_KR","nb_NO","nl_BE","nl_NL","pl_PL","pt_BR","pt_PT","sk_SK","sr_RS","sv_SE","th_TH","tr_TR","ru_RU","uk_UA","vi_VN","zh_CN","zh_TW"], | ||
"description": "add locale code to module (e.g., --locale=en_US)" | ||
}, | ||
"theme": { | ||
"type": "boolean", | ||
"default": false, | ||
"description": "add theme.less" | ||
} | ||
}, | ||
"required": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
export interface Schema { | ||
/** Whether to skip package.json install. */ | ||
skipPackageJson: boolean; | ||
|
||
theme: boolean; | ||
|
||
/** Name of the project to target. */ | ||
project?: string; | ||
|
||
locale: 'ar_EG' | 'bg_BG' | 'ca_ES' | 'cs_CZ' | 'de_DE' | 'el_GR' | 'en_GB' | 'en_US' | 'es_ES' | 'et_EE' | 'fa_IR' | 'fi_FI' | 'fr_BE' | 'fr_FR' | 'is_IS' | 'it_IT' | 'ja_JP' | 'ko_KR' | 'nb_NO' | 'nl_BE' | 'nl_NL' | 'pl_PL' | 'pt_BR' | 'pt_PT' | 'sk_SK' | 'sr_RS' | 'sv_SE' | 'th_TH' | 'tr_TR' | 'ru_RU' | 'uk_UA' | 'vi_VN' | 'zh_CN' | 'zh_TW'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"compilerOptions": { | ||
"lib": ["es2017", "dom"], | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"outDir": "../publish/schematics", | ||
"noEmitOnError": false, | ||
"skipDefaultLibCheck": true, | ||
"skipLibCheck": true, | ||
"sourceMap": true, | ||
"target": "es6", | ||
"types": [ | ||
"jasmine", | ||
"node" | ||
] | ||
}, | ||
"include": [ | ||
"**/*" | ||
], | ||
"exclude": [ | ||
"**/*.component.ts", | ||
"**/*spec*", | ||
"template/**/*" | ||
] | ||
} |
Oops, something went wrong.