angular第三方包开发整理(小结)

 更新时间:2018年04月19日 09:13:05   作者:Yitimo  
本篇文章主要介绍了angular第三方包开发整理(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

近日笔者维护自己的几个无名小repo时,发觉想要创作一个第三方angular包,着实有一些不难但易乱的小问题,故作此文总结。本文将完成以下内容:

  1. 从空白开始搭建一个基于angular的第三方包
  2. 在本地测试待发布的包
  3. 在npm或yarn发布包中指定内容
  4. 在普通angular应用中引入并使用发布的包

基本项目搭建

一般的angular app使用angular-cli创建,直接ng new name搞定,生成的项目把webpack、AOT、dev server等细节都隐藏了,还支持各种参数来配置测试和sass等,使用起来直接npm run start、npm run build,可以说是非常傻瓜了,跳过了学习webpack等的许多大坑。

不过,如果是要搭建angular第三方包,预编译样式和打包部署这些一般就用不着了,取而代之的要熟悉npm(yarn)、tsconfig。

初始化

项目搭建命令如下:

mkdir my-ng-lib
cd my-ng-lib
yarn init

一路回车(实际情况中还是要编辑好包的基本信息)最终得到一个package.json,然后vscode打开:

初始化npm包

依赖

作为angular的第三方包,首先需要安装如下依赖:

依赖安装

其中typescript指定了版本是为了和当前angular-cli使用的版本保持一致,实际可能不必要这么做。

现在安装了开发时要用到的包,但这些包并不用在发布以后,实际上发布的时候我们想要的只是发布自己写的代码,而不是依赖的代码,这需要在package.json中配置peerDependencies作为前置依赖,但包本身不会实际安装这些依赖,实际的包应该由应用项目来安装。现在把peerDependencies添加进package.json:

"peerDependencies": {
  "@angular/common": ">=5.0.0",
  "@angular/core": ">=5.0.0",
  "rxjs": ">=5.0.0"
 }

项目编写

基本项目搭建好后,我们应该只有package.json、node_modules和一个lock文件在项目中,现在要加上真正的项目代码了。

无论这个包是用来实现什么目的的,作为一个第三方包,都应该要导出自己的功能以让其他项目引入使用,所以在项目根目录首先要有一个index.js文件,而我们要开发的是基于angular的TypeScript包,使用的自然是index.ts了,内容就是各种export导出类型、接口、方法等。作为示例这里只导出一个常量:

export const myNgLib: string = 'Hello, thie is my angular 3rd part lib';

为了支持TypeScript我们还需要一个tsconfig.json:

{
 "compilerOptions": {
  "baseUrl": ".", // 基于哪个目录编译ts
  "declaration": true, // 是否生成声明文件即*.d.ts文件,有了它才有TS的代码提示
  "experimentalDecorators": true, // 用于支持TS装饰器如angular中的 @NgModule({}) 之类
  "emitDecoratorMetadata": true, // 用于支持TS装饰器如angular中的 @NgModule({}) 之类
  "module": "commonjs", // 模块化形式
  "moduleResolution": "node", // 模块化形式
  "rootDir": ".", // 以哪个目录为根
  "lib": ["es2015", "dom"], // 支持编译的内置库
  "skipDefaultLibCheck": true, // 是否跳过内置库检查
  "skipLibCheck": true, // 跳过库检查
  "target": "es5", // 编译目标版本
  "suppressImplicitAnyIndexErrors": true, // 几个检查代码的规则
  "strictNullChecks": true, // 几个检查代码的规则
  "noImplicitAny": true, // 几个检查代码的规则
  "sourceMap": true, // 是否生成 .js.map
  "removeComments": true, // 移除注释
  "noFallthroughCasesInSwitch": true // 几个检查代码的规则
 },
 "exclude": [ // 编译时排除以下内容
  "node_modules",
  "*.d.ts",
  "**/*.d.ts"
 ]
}

其中的规则各有各效果,有些为了确定编译路径,有些为了语法检查,有些为了输出声明,还有排除规则等,现在可以tsc看看效果了,不过要先把tsc添加到package.json的scripts中:

"scripts": {
  "tsc": "tsc"
 }

编译得到.js、js.map、.d.ts

发布

完美,这么厉害的包,接下来赶紧发布它。发布命令是

yarn publish

不过在此之前,要准备几件事:

npm账号

发布之前自然得先有npm账号,添加了就可以,最后用npm whoami确认身份。

包的基本信息

也就是要完善package.json,让全网知道这么厉害的包是我们开发的,包括开源许可、包名、作者、版本号等,最重要直接影响发布的是版本号。

选择性发布

基于angular的第三方包区别与普通的js包最大的地方就在于,不能直接把整个包都发布到npm,这样会导致奇怪错误,原因在于.ts文件,实际上需要发布的只是.js、.js.map、.d.ts这三种类型的文件就够了。

因为在其他项目中不一定会使用TypeScript,即使用了也不会刻意包含node_modules目录,也就是说其他项目只管使用,编译的活由我们得包自己来做,相反要是我们还发布多余的.ts文件,只会导致错误。

为了做到选择性发布,需要一个.npmignore文件,和.gitignore配合用来忽略上传的文件,一般这些编译输出我们会添加在.gitignore中,若项目不存在.npmignore,发布到npm时也会使用.gitignore,这不是我们想要的,所以需要再创建这个.npmignore来忽略.ts文件而包含编译输出:

node_modules
yarn-error.log
tsconfig.json
.gitignore
.npmignore
yarn.lock
*.ts
!*.d.ts

现在我们的项目看起来是这样的:

待发布项目

使用yarn pack命令得到本地打包看看效果如何:

本地打包

看起来非常完美,该有的都有了,不该有的都忽略了,那就可以发布了,不过这里就不发布这个没什么用处的包了 : )
打包至此完成,现在看看用起来怎么样。

本地测试

angular的第三方包要做本地测试的话,与普通的包比有一点不足,就是用不了npm link,这会导致错误,特别是在第三方包使用到依赖注入的情况下,原因是运行时实际是在两个angular环境下,再进一步说是因为第三方包依赖的是自己的node_modules,解决办法也很粗暴,删掉第三方包的node_modules即可,不过这代价显然有点大。找遍GitHub发现的另一个办法是配合--preserve-symlinks参数,不过可能是笔者使用姿势不对一直没效果。

最后笔者自己的曲线救国办法是手动写package.json的scripts,本地测试步骤是:

  1. 执行 yarn pack得到本地打包
  2. 解压到测试项目的node_modules中假装是安装的项目
  3. 测试项目中像使用普通安装包一样使用这个直接复制进来的包

参考脚本如下:

"scripts": {
  "prepublish": "npm run clean && tsc", // 清理并编译
  "clean": "rimraf index.js index.js.map index.d.ts src/**/*.js src/**/*.js.map src/**/*.d.ts linktest.tgz", // 清理编译文件
  "link": "npm run pack && tar -zxf linktest.tgz && rimraf ../lib-test-app/node_modules/my-ng-lib && mv package ../lib-test-app/node_modules/my-ng-lib", // 打包后解压并移动到测试项目node_modules中
  "pack": "npm run prepublish && yarn pack --filename linktest.tgz" // 执行编译并打包
 }

总结

  1. 发布基于angular的第三方包的两个难点:一是如何处理好TypeScript的编译,二是如何处理好angular运行上下文。
  2. 本文的命令均使用yarn完成,npm版本命令大同小异均有其对应命令,且发布的包都是在npm托管。
  3. 另外本文仅涉及发布最基本的基于angular的第三方包,包的实际功能方面没有做深入。其实对于不同功能的第三方包,仍有需要学习的内容。

参考资料:

How to create an Angular component library, and how to consume it using SystemJs or Webpack
stories linked library
npm link doesn't work with 1.5.4 version

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Angular2学习笔记——详解NgModule模块

    Angular2学习笔记——详解NgModule模块

    这篇文章主要介绍了Angular2学习笔记——详解NgModule模块,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • angular学习之从零搭建一个angular4.0项目

    angular学习之从零搭建一个angular4.0项目

    本篇文章主要介绍了从零搭建一个angular4.0项目,主要用到的工具angular4.0、angular-cli、npm(v3.10.8)、node(v6.2.0),有兴趣的可以了解一下
    2017-07-07
  • AngularJS通过$http和服务器通信详解

    AngularJS通过$http和服务器通信详解

    相信大家都知道AngularJS是一个前端框架,实现了可交互式的页面,但是对于一个web应用,页面上进行展示的数据从哪里来,肯定需要服务端进行支持,那么AngularJS是如何同服务端进行交互的呢?通过这篇文章大家一起来看看吧。
    2016-09-09
  • angular同一页面跳转重新执行的实现方法

    angular同一页面跳转重新执行的实现方法

    这篇文章主要介绍了angular同一页面跳转重新执行的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • angularjs实现table表格td单元格单击变输入框/可编辑状态示例

    angularjs实现table表格td单元格单击变输入框/可编辑状态示例

    这篇文章主要介绍了angularjs实现table表格td单元格单击变输入框/可编辑状态,涉及AngularJS事件响应及页面table元素属性动态操作相关实现技巧,需要的朋友可以参考下
    2019-02-02
  • AngularJS中update两次出现$promise属性无法识别的解决方法

    AngularJS中update两次出现$promise属性无法识别的解决方法

    最近在工作中用AngularJS中update了两次之后发现$promise属性无法识别了,后来通过查找相关的资料终于解决了,想着记录下方便自己或者有需要的朋友,所以本文主要介绍了AngularJS中update两次出现了$promise属性无法识别的解决方法,需要的朋友可以参考借鉴。
    2017-01-01
  • angularJs中$http获取后台数据的实例讲解

    angularJs中$http获取后台数据的实例讲解

    今天小编就为大家分享一篇angularJs中$http获取后台数据的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • angular.js分页代码的实例

    angular.js分页代码的实例

    本文用实例详细给大家展示了angular.js分页代码,代码很详细,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Angular2 组件交互实例详解

    Angular2 组件交互实例详解

    Angular2应用程序实际上是有很多父子组价组成的组件树,因此,了解组件之间如何通信,特别是父子组件之间,对编写Angular2应用程序具有十分重要的意义。下面通过本文给大家介绍Angular2 组件交互知识,感兴趣的朋友一起看看吧
    2017-08-08
  • Angular中点击li标签实现更改颜色的核心代码

    Angular中点击li标签实现更改颜色的核心代码

    这篇文章主要介绍了Angular中点击li标签实现更改颜色的核心代码,需要的朋友可以参考下
    2017-12-12

最新评论