作为 NativeScript 插件作者,在更新您的插件以适应 NativeScript 7 时,需要了解 6 个要点
dependencies
更新tns-core-modules
的出现,并将所有导入扁平化为仅来自 @nativescript/core
tns-platform-declarations
的出现,并替换为 @nativescript/types
我们将很快推出一个新的插件种子,它具有改进的架构(优于当前的插件种子)、构建工具和设置,以帮助您更轻松地维护所有插件。它还允许您轻松地将现有的插件导入并使用它(我们将在其可用后的两周内发布一篇博客文章)。
让我们分别解决这些问题。
"devDependencies": {
"@nativescript/core": "~7.0.0",
"@nativescript/types": "~7.0.0",
"@nativescript/webpack": "~3.0.0",
"typescript": "~3.9.0",
更新您的 tsconfig.json。这里突出显示了关键部分,因此仅显示最重要的部分。
之前
"compilerOptions": {
"target": "es5",
"module": "commonjs",
之后
"compilerOptions": {
"target": "ES2017",
"module": "esnext",
"moduleResolution": "node",
对于您使用 TypeScript 的 extends SomeNativeClass
语法扩展的任何原生类,您都希望进行装饰。例如
之前
iOS
export class MyPluginDelegateImpl extends NSObject {
Android
export class ListViewItemClickListenerImpl extends java.lang.Object
之后
iOS
@NativeClass()
export class MyPluginDelegateImpl extends NSObject {
Android
@NativeClass()
export class ListViewItemClickListenerImpl extends java.lang.Object {
NativeClass
装饰器是 @nativescript/core
全局的一部分,因此您无需从任何地方导入它,因为它只要您使用 @nativescript/core
就应该可用。
注意:根据您的使用情况,请参阅 此处的 NativeClass 最佳实践,其中概述了一些其他有用的说明。
为了使您的插件能够正确处理 NativeClass
装饰器,您可以通过 ts-patch
包向 typescript 和 tsconfig.json 添加一个不错的扩展。这与来自最新 @nativescript/webpack
(3.0.0
及更高版本)的新转换器结合使用,这也是上述 devDependencies 中列出该包的原因。
npm i ts-patch -D
修改 package.json
脚本以在清理插件后包含安装。
这是一个示例
"scripts": {
"setup": "npm i && ts-patch install"
}
tsconfig.json
以支持转换(在 compilerOptions
中的任何位置添加 plugins
部分)"compilerOptions": {
"plugins": [{
"transform": "@nativescript/webpack/transformers/ns-transform-native-classes",
"type": "raw"
}]
}
现在,当您使用 tsc
构建插件时,任何使用 NativeClass
装饰的类都将被正确编译以供 NativeScript 运行时使用。
tns-core-modules
的出现,并将所有导入扁平化为仅来自 @nativescript/core
您现在可以使用 @nativescript/core
进行所有导入。一些符号已被封装到方便的汇总中,以避免在代码库中出现太多通用符号。您可以 使用此导入参考指南来合并用法。
这是一个示例
之前
import * as app from 'tns-core-modules/application';
import { messageType, write } from 'tns-core-modules/trace';
import { ObservableArray } from 'tns-core-modules/data/observable-array';
import { GridLayout } from 'tns-core-modules/ui/layouts/grid-layout';
import { KeyedTemplate, View } from 'tns-core-modules/ui/core/view';
import { layout } from 'tns-core-modules/utils/utils';
// sample code
const rootView = app.getRootView();
write('Some message', 'a category');
layout.getDisplayDensity();
alert('Hi');
之后
import {
Application,
Trace,
ObservableArray,
GridLayout,
KeyedTemplate,
View,
Dialogs,
Utils
} from '@nativescript/core';
// sample code
const rootView = Application.getRootView();
Trace.write('Some message', 'a category');
Utils.layout.getDisplayDensity();
// you can still use global alert just fine but to better identify {N} dialog usage you can now use the `Dialogs` rollup which contains all the dialog methods and interfaces
Dialogs.alert('Hi');
tns-platform-declarations
的出现,并替换为 @nativescript/types
在您的 references.d.ts
中
之前
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
之后
/// <reference path="./node_modules/@nativescript/types/index.d.ts" />
如果需要,您还可以根据需要包含特定的平台类型;例如,假设您想要不同的 Android sdk 类型
/// <reference path="./node_modules/@nativescript/types-ios/index.d.ts" />
/// <reference path="./node_modules/@nativescript/types-android/lib/android-29.d.ts" />
NativeScript 7 带来了官方的 Angular 10 支持。这一点很重要,因为 Angular 10 取消了官方的 es5 支持,并且还针对 es2017+。
为了编译您的 Angular 特定插件部分,我们可以使用 ng-packagr 来协助构建。
npm i ng-packagr -D
使用 ng-packagr
有几个有趣的事情,即 Angular 部分需要自包含,因此从其实际的捆绑导入包名称引用其他“外部”依赖项。例如
import { MyPluginClass } from '../some/vanilla-plugin-code';
这将不起作用,因为 ../
将代码引入 Angular 构建中,而该代码不是“打包”的 dist 的一部分。要修复,这将变为
import { MyPluginClass } from '@nativescript-community/your-plugin';
因此,您可以对插件组织做出几个架构选择,这也是我们引入新的插件种子以在此提供帮助的原因之一。
A. 您可以创建与插件的 src
文件夹平行的 src-angular
文件夹,并且它将依赖于您的插件本身。B. 您可以将 angular
文件夹保留在插件的 src
内部,但应该以单存储库样式架构构建您的插件,这有助于以更智能的方式管理依赖项以及构建配置设置。
我们最喜欢选项 B,因为它不仅优雅地解决了该问题,而且还解决了其他许多问题,例如简化维护多个插件的便捷性,这些插件都是从依赖项和构建配置的单一事实来源开发的。
无论您选择哪种方向,在插件的 Angular 源代码中,您都希望为 ng-packagr
提供以下内容
{
"name": "nativescript-community-your-plugin-angular",
"ngPackage": {
"lib": {
"entryFile": "index.ts",
"umdModuleIds": {
"@nativescript/core": "ns-core",
"@nativescript/angular": "ns-angular",
"@nativescript-community/your-plugin": "ns-community-your-plugin"
}
},
"whitelistedNonPeerDependencies": [
"."
]
}
}
名称可以是任何标识符,但我们只是使用插件名称的标准扁平化并在末尾附加 -angular
来表示这是插件的 Angular 部分。
entryFile
在这里至关重要,为了安全起见,它应该命名为 index.ts
。您可以将其命名为其他名称,但如果将其命名为与插件本身相同的名称,则它将失败,因此只需使用 index.ts
。
以下是我们自己的内部插件 @nativescript/datetimepicker
的 package.json
结构示例
datetimepicker
/ angular
index.ts
nativescript-datetimepicker.accessors.ts
nativescript-datetimepicker.directives.ts
以及 index.ts
的内容 可以在这里看到。
请注意,它从其完整的插件桶名称 @nativescript/datetimepicker
而不是相对导入路径导入普通 {N} 插件代码。这对于正确打包 Angular 构建非常重要。
一旦 ng-packagr 完成构建,它会在 Angular 源代码内部默认放置一个 dist
目录,其内容可以复制到插件的输出中,以准备发布。
您可以按如下方式启动 Angular 源代码构建
ng-packagr -p angular/package.json
如前所述,我们将引入一个新的插件种子,其中包含已准备就绪的架构来扩展插件开发(以及导入现有插件),并比以前的插件种子更好地处理此类细节。请在未来两周内关注此公告。