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


Posted in Javascript onApril 19, 2018

近日笔者维护自己的几个无名小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打开:

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

初始化npm包

依赖

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

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"
 }

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

编译得到.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

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

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

待发布项目

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

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

本地打包

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

本地测试

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

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

Javascript 相关文章推荐
IE6下CSS图片缓存问题解决方法
Dec 09 Javascript
node.js下when.js 的异步编程实践
Dec 03 Javascript
javascript实现的右下角弹窗实例
Apr 24 Javascript
jQuery拖动布局其结果保存到数据库
Oct 09 Javascript
Jquery on方法绑定事件后执行多次的解决方法
Jun 02 Javascript
js传值后台中文出现乱码的解决方法
Jun 30 Javascript
js生成随机数(指定范围)的实例代码
Jul 10 Javascript
解决微信内置浏览器返回上一页强制刷新问题方法
Feb 05 Javascript
基于js Canvas实现二次贝塞尔曲线
Dec 25 Javascript
JavaScript实现简单的图片切换功能(实例代码)
Apr 10 Javascript
three.js 如何制作魔方
Jul 31 Javascript
Vue实现随机验证码功能
Dec 29 Vue.js
如何从零开始利用js手写一个Promise库详解
Apr 19 #Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
Apr 18 #Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
Apr 18 #Javascript
原生js实现拖拽功能基本思路详解
Apr 18 #Javascript
一个基于react的图片裁剪组件示例
Apr 18 #Javascript
JS实现对json对象排序并删除id相同项功能示例
Apr 18 #Javascript
Angular ng-animate和ng-cookies用法详解
Apr 18 #Javascript
You might like
七款最流行的PHP本地服务器分享
2013/02/19 PHP
php图形jpgraph操作实例分析
2017/02/22 PHP
浅析js设置控件的readonly与enabled属性问题
2013/12/25 Javascript
javascript打开word文档的方法
2014/04/16 Javascript
jquery实现鼠标滑过显示二级下拉菜单效果
2015/08/24 Javascript
浅析Node.js 中 Stream API 的使用
2015/10/23 Javascript
js运动应用实例解析
2015/12/28 Javascript
jQuery实现可以控制图片旋转角度效果(附demo源码下载)
2016/01/27 Javascript
JS实现鼠标框选效果完整实例
2016/06/20 Javascript
JSP防止网页刷新重复提交数据的几种方法
2016/11/19 Javascript
jQuery实现字符串全部替换的方法
2016/12/12 Javascript
javascript 秒表计时器实现代码
2017/03/09 Javascript
javascript基本数据类型和转换
2017/03/17 Javascript
原生JS实现的跳一跳小游戏完整实例
2019/01/27 Javascript
微信小程序图片左右摆动效果详解
2019/07/13 Javascript
python用列表生成式写嵌套循环的方法
2018/11/08 Python
Python整数对象实现原理详解
2019/07/01 Python
Python 3 实现定义跨模块的全局变量和使用教程
2019/07/07 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
用python介绍4种常用的单链表翻转的方法小结
2020/02/24 Python
Python基于Dlib的人脸识别系统的实现
2020/02/26 Python
python利用pytesseract 实现本地识别图片文字
2020/12/14 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
详解Java中一维、二维数组在内存中的结构
2021/02/11 Python
html5-canvas中使用clip抠出一个区域的示例代码
2018/05/25 HTML / CSS
教育专业个人求职信
2013/12/02 职场文书
公务员培训自我鉴定
2014/02/01 职场文书
食品采购员岗位职责
2014/04/14 职场文书
优秀护士先进事迹
2014/05/08 职场文书
法定代表人授权委托书范本
2014/10/07 职场文书
2014年世界艾滋病日演讲稿
2014/11/28 职场文书
十八大观后感
2015/06/12 职场文书
学生会部长竞选稿
2015/11/19 职场文书
教师法制教育培训学习心得体会
2016/01/14 职场文书
同学联谊会邀请函
2019/06/24 职场文书
Windows Server 版本 20H2 于 8 月 9 日停止支持,Win10 版本 21H1 将于 12 月结束支
2022/07/23 数码科技