使用ng-packagr打包Angular的方法示例


Posted in Javascript onSeptember 21, 2018

写在前面

为了让 Angular 类库应用范围更自由,Angular 提出一套打包格式建议名曰:Angular Package Format,包括 FESM2015、FESM5、UMD、ESM2015、ESM5、ES2015 格式,不同格式可以在不同的环境(Angular Cli、Webpack、SystemJS等)中使用。

传统方式需要对这些格式逐一打包,一个示例打包脚本写法。这种写法只能针对不同项目的配置,而且除非你了解这些格式的本质否则很难维护;后来社区根据 APF 规范实现了类库 ng-packagr,通过简单的配置可以将你的类库打包成 APF 规范格式。

至 V6 以后 Angular Cli 也基于 ng-packagr 实现了另一个 @angular-devkit/build-ng-packagr 应用构建器。

如何使用

既然 ng-packagr 被 Angular Cli 内置,这让我们进一步简化了生产一个 APF 规范格式的类库的成本。在 Angualr Cli 里使用 ng g library 来创建一个类库模板,例如在一个新的 Angular 应用里执行:

ng g library <library name>

而打包,则:

ng build <library name>

最终,将生成的 dist/<libary name> 目录下文件上传相应包管理服务器(例如:npm)提供给其他 人使用。

配置说明

由 Angular Cli 生成的类库模板大部分内容同 Angular 应用一样,只是多了一个 ng-package.json 的配置文件(对于生产环境是 ng-package.prod.json),它是专门针对 ng-packagr 的一个配置文件,如同 angular.json 一般也是基于 JSON Schema 格式,因此可以通过访问ng-package.schema.json 了解所有细节,以下描述一些重点项。

whitelistedNonPeerDependencies

ng-packagr 默认会根据 package.json 的 peerDependencies 节点清单来决定类库所需要第三方依赖包,这些依赖包是不会被打包至类库。

然而,所依赖包不存在 peerDependencies 节点里时(当然建议需要依赖的项应该在里面),就需要该属性的配置。

lib/entryFile

指定入口文件。

lib/umdModuleIds

UMD 格式采用 rollup 打包,当类库需要引用一些无法猜出正确 UMD 标识符时,就需要你手动映射这些类库的标识。

"umdModuleIds": {
  "lodash": "_"
}

angular.json

Angular Cli 配置文件 angular.json 内会增加一个以 <libary name> 命名的构建配置,绝大多数配置性同普通 Angular 应用如出一辙,唯一不同的是 builder 节点为:

"builder": "@angular-devkit/build-ng-packagr:build"

次级入口

有时候一个类库可能会包含着多个二次入口,就像 @angular/core 类库包含着一个 @angular/core/testing 模块,它只是运用于测试,因此并不希望在项目中引入 @angular/core 时也包含测试代码,但同时二者又是同一个功能性时,这种次级导入显得非常重要。

另一种像 ngx-bootstrap、@angular/cdk/ally 等都提供次级模块的导入,可以更好的优化体积。

不论出于何种目的,都可以通过 Angular Cli 简单的文件组织进一步打包出主、次级分明的类库。

ng g library 生成的结构大概如下:

<libary name>
├── src
|  ├── public_api.ts
|  └── lib/*.ts
├── ng-package.json
├── ng-package.prod.json
├── package.json
├── tsconfig.lib.json
└── tsconfig.spec.json
当根目录下包含 README.mdLICENSE 时会自动被复制到 dist 目录中,Npm 规定必须包含 README.md 文件,否则访问已发布类库页时会有未找到描述文件错误提示。

若想创建一个 <libary name>/testing 的次级入口,只需要在 <libary name> 根目录下创建一个 testing 目录:

<libary name>
├── src
|  ├── public_api.ts
|  └── lib/*.ts
├── ng-package.json
├── ng-package.prod.json
├── package.json
├── tsconfig.lib.json
├── tsconfig.spec.json
└── testing
  ├── src
  |  ├── public_api.ts
  |  └── *.ts
  └── package.json

核心是需要提供一个 package.json 文件,而且内容简单到姥姥家。

{
  "ngPackage": {}
}

最后,依然使用 ng build <libary name>,会产生一个次级导入模块。

小结

至此,基本上利用 Angular Cli 可以快速的构建一个可发布于 Npm Angular 类库,更复杂的可以构建像 ngx-bootstrap、@angular/cdk/* 类库。

自定义构建

Angular Cli 虽然提供非常便利的环境,但是对于一些复杂环境像 Delon 类库(ng-alain基建系列类库)包含着多个类库、类库又包含多个次级导入时,Angular Cli 会显得有点??拢?乇鹗嵌悦扛隼嗫獾 angular.json 配置。其实 @angular-devkit/build-ng-packagr 非常简单,如果将取进一步简化,整个实现差不多相当于:

const path = require('path');
const ngPackage = require('ng-packagr');

const target = path.resolve(__dirname, './projects/<libary name>');

ngPackage
 .ngPackagr()
 .forProject(path.resolve(target, `ng-package.prod.json`))
 .withTsConfig(path.resolve(target, 'tsconfig.lib.json'))
 .build()
 .then(() => {
   // 构建完成后干点事
 });

将上面的代码放到 ./build.js,执行:

node scripts/build.js

其结果完成是等价。

build() 返回的是一个 Promise 对象,意味着可以确保构建开始前和结束后做一点额外的事。

总结

ng-packagr 极大简化 Angular 类库被打包出一个 APF 规范建议,虽然它以 ng- 开头,但本质上并不一定非要在 Angular 中运用,也可以使用在 React、VUE。

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

Javascript 相关文章推荐
THREE.JS入门教程(6)创建自己的全景图实现步骤
Jan 25 Javascript
Dom 学习总结以及实例的使用介绍
Apr 24 Javascript
将form表单中的元素转换成对象的方法适用表单提交
May 02 Javascript
javascript 10进制和62进制的相互转换
Jul 31 Javascript
JQuery点击事件回到页面顶部效果的实现代码
May 24 Javascript
Bootstrap表单布局样式代码
May 31 Javascript
Bootstrap Modal对话框如何在关闭时触发事件
Dec 02 Javascript
javascript设计模式之模块模式学习笔记
Feb 15 Javascript
gulp加批处理(.bat)实现ng多应用一键自动化构建
Feb 16 Javascript
利用node.js制作命令行工具方法教程(一)
Jun 22 Javascript
微信小程序顶部导航栏滑动tab效果
Jan 28 Javascript
JS前后端实现身份证号验证代码解析
Jul 23 Javascript
基于vue中keep-alive缓存问题的解决方法
Sep 21 #Javascript
vue中前进刷新、后退缓存用户浏览数据和浏览位置的实例讲解
Sep 21 #Javascript
vue单页面应用打开新窗口显示跳转页面的实例
Sep 21 #Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
Sep 21 #Javascript
默认浏览器设置及vue自动打开页面的方法
Sep 21 #Javascript
详解Vue中数组和对象更改后视图不刷新的问题
Sep 21 #Javascript
详解vue 数组和对象渲染问题
Sep 21 #Javascript
You might like
使用PHP实现密保卡功能实现代码&amp;lt;打包下载直接运行&amp;gt;
2011/10/09 PHP
PHP生成压缩文件实例
2015/02/07 PHP
一段实用的php验证码函数
2016/05/19 PHP
PHP数组对象与Json转换操作实例分析
2019/10/22 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
获取任意Html元素与body之间的偏移距离 offsetTop、offsetLeft (For:IE5+ FF1 )[
2006/12/22 Javascript
js模拟select下拉菜单控件的代码
2013/05/08 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
node.js中的http.response.addTrailers方法使用说明
2014/12/14 Javascript
JS实现CheckBox复选框全选全不选功能
2015/05/06 Javascript
DOM 高级编程
2015/05/06 Javascript
js+html5实现canvas绘制简单矩形的方法
2015/06/05 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
基于Vuejs框架实现翻页组件
2020/06/29 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(同步显示图像位置信息)
2016/12/02 Javascript
JQueryEasyUI框架下的combobox的取值和绑定的方法
2017/01/22 Javascript
VueJs单页应用实现微信网页授权及微信分享功能示例
2017/07/26 Javascript
浅谈Node模块系统及其模式
2017/11/17 Javascript
详解Vue的钩子函数(路由导航守卫、keep-alive、生命周期钩子)
2018/07/24 Javascript
利用anaconda作为python的依赖库管理方法
2019/08/13 Python
基于Django统计博客文章阅读量
2019/10/29 Python
Python基础之字符串常见操作经典实例详解
2020/02/26 Python
Python编程快速上手——PDF文件操作案例分析
2020/02/28 Python
浅谈Python中的字符串
2020/06/10 Python
html5 touch事件实现触屏页面上下滑动(二)
2016/03/10 HTML / CSS
美国知名的旅游网站:OneTravel
2018/10/09 全球购物
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
聚美优品广告词改编
2014/03/14 职场文书
电气自动化求职信
2014/06/24 职场文书
销售顾问工作计划书
2014/08/15 职场文书
农村党建工作汇报材料
2014/10/27 职场文书
2014年小学少先队工作总结
2014/12/18 职场文书
导游词之清晏园
2019/11/22 职场文书
关于Javascript闭包与应用的详解
2021/04/22 Javascript
MySQL创建高性能索引的全步骤
2021/05/02 MySQL