在库中使用schematics——ng add与ng update

创建一个angular库

ng new demo --create-application=false ng g library my-lib

可见如下目录结构

├── node_modules/ ├── projects │ └── my-lib │ ├── src │ │ ├── lib │ │ ├── public-api.ts │ │ └── test.ts │ ├── karma.conf.js │ ├── ng-package.json │ ├── package.json │ ├── README.md │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── README.md ├── package.json ├── .editorconfig ├── angular.json ├── tsconfig.base.json ├── tslint.json └── tsconfig.json

添加projects/my-lib/schematics/collection.json文件

{ "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "ng-add": { "description": "Add my library to the project.", "factory": "./ng-add/index#ngAdd" } } }

修改projects/my-lib/package.json文件

{ "name": "my-lib", "version": "0.0.1", "schematics": "./schematics/collection.json", }

添加projects/my-lib/schematics/ng-add/index.ts文件

import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { strings } from '@angular-devkit/core'; // Just return the tree export function ngAdd(options: any): Rule { return (tree: Tree, context: SchematicContext) => { context.addTask(new NodePackageInstallTask()); // 如果不是 Angular 项目则抛出错误 const workspaceConfig = tree.read('angular.json'); if (!workspaceConfig) { throw new SchematicsException('Not an Angular CLI workspace'); } const templateSource = apply(url('./files'), [ applyTemplates({ ...strings }), move(normalize('')), ]); return chain([mergeWith(templateSource)]); }; }

添加projects/my-lib/schematics/ng-add/files 文件

└── files └──index.ts

index.ts内容如下

// #docregion template import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class <%= classify(name) %>Service { constructor(private http: HttpClient) { } }

定义依赖类型,在projects/my-lib/package.json中添加

"ng-add": { "save": "devDependencies" }

修改projects/my-lib/tsconfig.schematics.json

{ "compilerOptions": { "baseUrl": ".", "lib": [ "es2018", "dom" ], "declaration": true, "module": "commonjs", "moduleResolution": "node", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, "noImplicitThis": true, "noUnusedParameters": true, "noUnusedLocals": true, "rootDir": "schematics", "outDir": "../../dist/my-lib/schematics", "skipDefaultLibCheck": true, "skipLibCheck": true, "sourceMap": true, "strictNullChecks": true, "target": "es6", "types": [ "jasmine", "node" ] }, "include": [ "schematics/**/*" ], "exclude": [ "schematics/*/files/**/*" ] } 属性 说明
rootDir   指出在你的 schematics/ 文件夹中包含要编译的输入文件。  
outDir   映射到了库的输出目录下。默认情况下,这是工作空间根目录下的 dist/my-lib 文件夹  

修改projects/my-lib/package.json

{ "name": "my-lib", "version": "0.0.1", "scripts": { "build": "../../node_modules/.bin/tsc -p tsconfig.schematics.json", "copy:files": "cp --parents -p -r schematics/*/files/** ../../dist/my-lib/", "copy:collection": "cp schematics/collection.json ../../dist/my-lib/schematics/collection.json", "postbuild":"npm run copy:files && npm run copy:collection" }, "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0" }, "schematics": "./schematics/collection.json", "ng-add": { "save": "devDependencies" } } 属性 说明
build   脚本使用自定义的 tsconfig.schematics.json 文件来编译你的原理图。  
copy   *语句将已编译的原理图文件复制到库的输出目录下的正确位置,以保持目录的结构。  
postbuild   脚本会在 build 脚本完成后复制原理图文件。  

修改根目录下的package.json,在scripts下加入

"build": "ng build my-lib --prod && cd ./projects/my-lib && npm run build", "publish": "cd ./dist/my-lib && npm publish"

开始发布

npm publish

试一试ng add吧!

使用schematics修改项目 如何使用schematics修改项目中的package.json

方法

说明


tree.overwrite()   重新编排package.json  
tree.read()   读取文件内容  

修改projects/my-lib/schematics/ng-add/index.ts

//读取angular.json的文件内容 const workspaceConfig = tree.read('angular.json'); // 如果不是 Angular 项目则抛出错误 if (!workspaceConfig) { throw new SchematicsException('Not an Angular CLI workspace'); } // 读取package.json的文件内容 const workspaceJson = tree.read('package.json'); let json=JSON.parse(workspaceJson) json.script.hello="print('123')" tree.overwrite('./package.json',JSON.stringify(json)) 在node_modules添加引入与注入项 方法 说明
addImportToModule(source: ts.SourceFile, modulePath: string, classifiedName: string, importPath: string): Change[]   添加引入到module  
ts.createSourFile   创建资源文件  
import * as ts from '@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript'; import { addImportToModule } from '@schematics/angular/utility/ast-utils'; ...... const modulePath = `/app.module.ts`; const sourText = _tree.read(modulePath).toString('utf-8'); const sourceFile = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true); const importPath = '@fortawesome/angular-fontawesome'; const moduleName = 'FontAwesomeModule'; //文件名为驼峰命名 const declarationChanges = addImportToModule(sourceFile, modulePath, moduleName, importPath); const declarationRecorder = _tree.beginUpdate(modulePath); for (const change of declarationChanges) { if (change instanceof InsertChange) { declarationRecorder.insertLeft(change.pos, change.toAdd); } } _tree.commitUpdate(declarationRecorder); 更新文件 方法 说明
tree.beginUpdate()   更新内容  
const htmlPath = `./app/src/app.component.html`; const htmlStr = `\n\n`; const modulePath = `/app.module.ts`; const sourText = _tree.read(htmlPath).toString('utf-8'); const htmlSourceFile = ts.createSourceFile(htmlPath, sourceText, ts.ScriptTarget.Latest, true); const htmlRecorder = _tree.beginUpdate(htmlPath); htmlRecorder.insertLeft(htmlSourceFile.end, htmlStr); _tree.commitUpdate(htmlRecorder); package.json依赖项安装 方法 说明
addPackageToPackageJson   添加依赖支持  
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; ...... const dependencies = [{ name: '@fortawesome/fontawesome-svg-core', version: '~1.2.25' }], addPackageToPackageJson( _tree, dependency.name, //依赖包名 dependency.version,//版本 ); ng Update使用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfjyx.html