Angular第三方库开发实践

从接触Angular到如今,做了不少Angular项目,使用了不少第三方库,但是却没有勇气触碰第三方库的开发,一是没有太多的积累,二是没有找到合适的“Hello world”的文档。
最近有机会要把项目中常用的Component做成第三方库,方便更多的项目使用。根据网上找到的各种资料,加上走的各种弯路,终于摸清楚了开发第三方库的流程。

搭建项目框架

为了方便第三方库的开发,我们首先要创建一个主应用A:

ng new projectnameA    //创建主应用

主应用A创建好之后,创建Lib:

cd projectnameA
ng g library libName --prefix  prefixName //--prefix是Lib使用的前缀

上述命令会对主应用如下改变:

  1. 在主应用A下创建 projects/libName 目录,并将Lib的相关文件放于此;

  2. 在 angular.json 文件中添加 libName 项目;

     "libName": {
       "root": "projects/libName",
       "sourceRoot": "projects/libName/src",
       "projectType": "library",
       "prefix": "dteam-top",
       "architect": {
         "build": {
           "builder": "@angular-devkit/build-ng-packagr:build",
           "options": {
             "tsConfig": "projects/libName/tsconfig.lib.json",
             "project": "projects/libName/ng-package.json"
           },
           "configurations": {
             "production": {
               "project": "projects/libName/ng-package.prod.json"
             }
           }
         },
         "test": {...},
         "lint": {...}
       }
     }
    

    其中:
    root为Lib的根目录;
    sourceRoot为Lib的源代码目录;
    projectType为项目的类型;
    prefix为组件使用的前缀;
    architect为Angular的构建配置,可设置 build、test 和 lint。

  3. 在 package.json 文件中添加 ng-packagr 依赖;

  4. 在 tsconfig.json 文件中添加 libName 库的引用;

        {    
            ...
            "paths": {
                "libName": [
                    "dist/libName"
                ]
            }
            ...
        }
    

这样项目框架就搭建好了,可以开始写Lib的代码了。

Lib开发

在Lib中需要注意一个文件:public_api.ts,这个文件是Lib的入口文件,取代了之前使用的index.ts文件,其中定义了Export的内容:

````
export * from './app/libName.component';
export * from './app/libName.module';
````

主应用A要使用Lib,在app.module.ts文件中直接引用:

import { LibNameModule } from '../../../../projects/libName/src/app/libName.module'

imports: [
    ...
    LibNameModule,
    ...
]

对于Lib中使用的其他组件,可在主应用A下通过npm安装,这里提醒下,这里是安装到主应用A的目录下,修改的是主应用A的package.json和package.lock.json文件。
这样,就可以开发自己的Lib了。

测试Lib的安装

Lib开发好之后,需要先在本地试安装。这时有疑问了,Lib中用到的其他组件的引入都是在主应用A的package.json中声明的,这对于Lib是不对滴。
细心的开发者会发现,在Lib的目录下也有一个package.json文件,其缺省内容为:

{
    "name": "libName",
    "version": "0.0.1",
    "peerDependencies": {
        "@angular/common": "7.0.2",
        "@angular/core": "7.0.2",
    }
}

我们需要把这个文件补充完整,将Lib中用到的其他第三方组件在peerDependencies中引入,并将Lib的其他属性也加入。例如:

{
    "name": "ligName",
    "version": "0.0.1",
    "keywords": ["keyword1","keyword2"],
    "license": "MIT",
    "author": "authorName",
    "description": "description",
    "peerDependencies": {
        "@angular/common": "7.0.2",
        "@angular/core": "7.0.2",
        "@angular/forms": "7.0.2",
        "@angular/router": "7.0.2", 
        "@angular/cdk": "7.0.2",
        "@angular/material": "7.0.2",
        "ngx-spinner": "7.0.0",
        "ngx-clipboard": "12.0.0", 
        "ethers": "4.0.27",
        "rxjs": "6.3.3"
    }
}

同时,还可以添加一个README.md文件,介绍Lib的使用方法。
准备工作做好之后,将Lib编译成产品:

ng build libName --prod

编译后的文件会放置在主应用A的dist/libName目录下。另外创建一个Angular应用B,在此应用下执行:

npm install 主应用A/dist/libName 

安装时会对libName使用的其他第三方库给出类似如下的提示:

npm WARN libName@0.0.1 requires a peer of @angular/core@^7.2.0 but none is installed. You must install peer dependencies yourself.

根据提示,自行安装缺少的组件即可。
在应用B的package.json中会看到对libName的引入:

 "libName": "file:../projectnameA/dist/

在应用B的package-lock.json文件中加入如下内容:

"libName": {
  "version": "file:../projectnameA/dist/libName",
  "requires": {
    "tslib": "^1.9.0"
  },
  "dependencies": {
    "tslib": {
      "version": "1.9.3",
      "bundled": true
    }
  }
}

在应用B的app.module.ts文件中引入libName:

import { LibNameModule } from 'libName';

...
imports: [
    ...
    LibNameModule,
    ...
],
...

在应用B中可以测试libName能否正常使用。

Lib发布

上述过程结束后,就可以将应用发布到npm上。准备工作:

  1. npm上注册账号。
  2. 在命令行下执行:npm adduser,将账号添加到本地。

好了,可以发布libName了。进入到projectnameA/dist/libName目录下执行:

npm publish

看到了发布成功提示,还有点小激动。进入到npm中,可以看到已经发布成功的libName。
如果想删除这个libName,可以使用如下命令:

npm unpublish libNamet@0.0.1 --force

这里需要特别注意的是:删除后的libName,在24小时内不能再发布了,见如下提示:

npm ERR! libName cannot be republished until 24 hours have passed. 

总结

npm为第三方库的开发还提供了一些便利的方法,如npm link命令。这些都有待我们在今后的开发中摸索和体验,以便更好的打磨精品组件。

附录

在开发过程中遇到了几个错误,现汇总如下:

  1. 权限错误:

     npm ERR! publish Failed PUT 403
     npm ERR! code E403
     npm ERR! You do not have permission to publish "libName". Are you logged in as the correct user? : libName
    

    解决办法,执行: npm adduser

  2. libName若注入了其第三方的服务,主应用调用时出现如下错误:

    Error: inject() must be called from an injection context 
    

    解决方法,在主应用的angular.json文件中添加:

    "projects": {
        "projectName": {
            "architect": {
                "build": {
                    "options": {
                        "preserveSymlinks":true
                    },
                },
            }
        }
      }
    },
    
  3. 若libName定义了自己的route,需要在主应用中注入RouterModule。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354