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 相关文章推荐
jquery zTree异步加载简单实例分享
Feb 05 Javascript
简单实例处理url特殊符号&处理(2种方法)
Apr 02 Javascript
jQuery之选择组件的深入解析
Jun 19 Javascript
jquery 扑捉回车键事件代码
Apr 24 Javascript
Javascript核心读书有感之语言核心
Feb 01 Javascript
javascript 闭包详解
Feb 15 Javascript
Angular Js文件上传之form-data
Aug 28 Javascript
Bootstrap实现登录校验表单(带验证码)
Jun 23 Javascript
微信小程序开发之圆形菜单 仿建行圆形菜单实例
Dec 12 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
Dec 13 Javascript
vue自定义全局共用函数详解
Sep 18 Javascript
js编写简易的计算器
Jul 29 Javascript
如何从零开始利用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+MYSQL的文章管理系统(二)
2006/10/09 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
2013/06/24 PHP
获取URL文件名后缀
2013/10/24 PHP
PHP入门经历和学习过程分享
2014/04/11 PHP
discuz图片顺序混乱解决方案
2015/07/29 PHP
php+flash+jQuery多图片上传源码分享
2020/07/27 PHP
PHP实现json_decode不转义中文的方法
2017/05/20 PHP
thinkphp 中的volist标签在ajax操作中的特殊性(推荐)
2018/01/15 PHP
Javascript面向对象之四 继承
2011/02/08 Javascript
node.js中的fs.fstatSync方法使用说明
2014/12/15 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
javaScript数组迭代方法详解
2016/04/14 Javascript
浅谈JS函数定义方式的区别
2016/10/30 Javascript
纯js实现隔行变色效果
2017/11/29 Javascript
vue实现中部导航栏布局功能
2019/07/30 Javascript
100行代码实现vue表单校验功能(小白自编)
2019/11/19 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
微信小程序学习总结(一)项目创建与目录结构分析
2020/06/04 Javascript
js+h5 canvas实现图片验证码
2020/10/11 Javascript
vue如何使用rem适配
2021/02/06 Vue.js
Python内建数据结构详解
2016/02/03 Python
Python编程中装饰器的使用示例解析
2016/06/20 Python
windows下python安装paramiko模块和pycrypto模块(简单三步)
2017/07/06 Python
Numpy array数据的增、删、改、查实例
2018/06/04 Python
python自定义函数def的应用详解
2020/06/03 Python
Python使用xpath实现图片爬取
2020/09/16 Python
Deux par Deux官方网站:设计师童装
2020/01/03 全球购物
法学研究生自我鉴定范文
2013/12/04 职场文书
公司庆典活动邀请函
2014/01/09 职场文书
低碳环保演讲稿
2014/08/28 职场文书
讲文明知礼仪演讲稿
2014/09/13 职场文书
公司员工管理制度
2015/08/04 职场文书
清明节随笔
2015/08/15 职场文书
pytorch 实现在测试的时候启用dropout
2021/05/27 Python
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫
HTML5基础学习之文本标签控制
2022/03/25 HTML / CSS