# 将 CLI 挂钩迁移到 NativeScript 6.0

·

如您所知,即将发布的 NativeScript 6.0 版本仅支持捆绑的版本,如果不使用 webpack,您将不再能够运行您的应用程序。这些工作流程更改还会影响 NativeScript CLI 中的挂钩机制。
在本文中,我们将研究什么是 NativeScript 挂钩,以及如何迁移挂钩以运行 NativeScript 6.0 CLI。

# 简而言之,NativeScript 挂钩

NativeScript 挂钩是可执行的代码段或 Node.js 脚本,可以由应用程序或插件开发人员添加,以自定义特定 NativeScript 命令的执行。通过插入应用程序构建过程的不同部分,它们使您能够执行特殊活动。NativeScript CLI 支持两种不同的执行挂钩的方式:

  • 流程执行
  • 通过 Node.js 衍生函数生成执行
# 钩子的进程内执行

进程内执行仅适用于 JavaScript 挂钩。NativeScript CLI in-process根据该module.exports语句确定是否应执行该挂钩。因此,为了启用进程内执行,您只需要module.exports =在钩子中使用 …语句即可。例如,如果挂钩脚本为:

module.exports = function($logger) {};

然后,CLI 将需要钩子脚本,并且将通过注入器调用导出的函数。在in-process执行让你使用任何可用的服务从 NativeScript CLI 的灵活性。

# 产生钩子的执行

如果 NativeScript CLI 无法找到module.exports = statement,它将使用 Node.js childProcess.spawn 函数执行挂钩。使用这种方法时,您将无法使用 NativeScript CLI 中的任何服务。

# hookArgs

NativeScript CLI 支持名为的特殊参数hookArgs。的hookArgs是包含所有传递到钩状方法的参数的对象。例如,假设 NativeScript CLI 的方法checkForChanges具有以下定义:

@hook("checkForChanges")
public async checkForChanges(platformData: IPlatformData,
  projectData: IProjectData, prepareData: IPrepareData) { }

然后,hookArgs将具有以下结构:

hookArgs: {
  platformData, projectData, prepareData;
}

TIP

注意:hookArgs每个挂钩的对象都不相同。

# 我需要迁移吗?

考虑到这一背景,让我们看看您(应用程序或插件开发人员)将您的钩子迁移到 NativeScript 6.0 所需执行的操作。

如果您的应用程序或插件不使用挂钩,则无需迁移,也不需要其他操作。您现在可以停止阅读。

如果您的应用程序或插件具有挂钩,则需要检查挂钩是否受 NativeScript 6.0 更改的影响。

# NativeScript 挂钩中的确切变化是什么?

NativeScript CLI 6.0 不会更改挂钩的加载,处理和执行方式,但是,整个 NativeScript CLI 都经过了重构,这种重构可能会影响您的挂钩。以下是与挂钩相关的主要更改:

  • 挂钩工作流程
  • 的结构 hookArgs
  • 通过 NativeScript CLI 注入的服务的名称

TIP

注意:有关 hookArgs 的结构和注入的服务的名称的更改仅影响 in-process 钩子。

在以下情况下,您可以安全地跳过接下来的两个部分:

  1. 您是一名应用程序开发人员,所有的想法都来自插件。在这种情况下,如果仍然存在与 6.0 CLI 不兼容的插件,则应更新到最新版本的插件,并在插件的存储库中记录问题。
  2. 您是应用程序开发人员,所有自定义的挂钩都缺少该module.exports =语句,例如,挂钩将不会执行in-process
  3. 您是一名插件开发人员,所有的挂钩都在插件{ inject: false }内部标记了package.json,例如,挂钩将不会执行in-process

# 挂钩工作流程

NativeScript CLI 中的挂钩机制旨在允许在执行 CLI 的某些特定部分之前和之后执行其他操作。如果返回具体值或 Promise,则该挂钩被视为之前/之后挂钩。

以下挂钩将作为之前/之后挂钩执行:

module.exports = function($logger) {
  return new Promise((resolve, reject) => {
    $logger.info('Executed before/after some CLI action/function.');
  });
};

这是 NativeScript CLI 支持的所有挂钩:

# 准备

正是在 NativeScript CLI 启动 Webpack 编译和本机文件的监视程序之前/之后执行此挂钩,例如,实际准备应用程序。

  • 使用旧版工作流程时,它将在应用程序的初始同步以及 NativeScript CLI 在监视模式下运行时的每次更改上执行。
  • 在 6.0 CLI 中,挂钩仅在应用程序的初始同步上执行。

# checkForChanges

该挂钩在 NativeScript CLI 检查应用程序中是否有更改之前/之后执行。NativeScript CLI 保留应用程序的状态,并基于此状态决定是否应在设备上重建,重新安装或重新启动应用程序。该挂钩是在使用旧版工作流程准备挂钩之前执行的,但是将在之后使用 6.0 CLI 执行。

  • 使用旧版工作流,此钩子将在应用程序的初始同步以及在 NativeScript CLI 以监视模式运行时的每次更改上执行。
  • 在 6.0 CLI 中,此挂钩在应用程序的初始同步上执行。NativeScript CLI 检查自上次执行以来是否更改了本机文件。本机文件是 App_Resources 和 platform 文件夹中的所有文件。当更改了本机文件时,NativeScript CLI 将重建应用程序。

# 预览前同步

当执行预览命令时,NativeScript CLI 将显示 QR 码。当使用设备扫描 QR 码并将设备报告给 CLI 时,将执行此挂钩。

# watchPatterns

正是在 NativeScript CLI 尝试确定用于监视应用程序的全局模式之前,将执行此挂钩。此处的目的是,这允许您更改模式,以防您要监视其他目录或从监视中排除目录。

# 观看前

恰好在 NativeScript CLI 开始监视项目目录之前执行此挂钩。

# 观察后

当 NativeScript CLI 停止监视项目目录时,将执行此挂钩。在以下情况下可能会发生这种情况:

  • 在运行 NativeScipt CLI 的终端中按 Ctrl + C 时
  • 当用于 LiveSync 进程的所有设备都断开连接时
  • 当 LiveSync 进程出现问题并且 NativeScript CLI 无法实时同步所做的更改时。

# after-createProject

从模板创建项目后,将执行此挂钩。

# buildAndroidPlugin

该挂钩是在构建 Android 插件的.aar 之前/之后执行的。

# 安装

该挂钩在应用程序安装在连接的设备或仿真器/模拟器上之前/之后执行。

# 应该准备

该挂钩在 NativeScript CLI 决定是否需要准备应用程序的任何部分之前/之后执行。该挂钩已在 NativeScript 6.0 中删除。

# cleanApp

该挂钩在 NativeScript CLI 清理 platform 目录中的 app 目录之前/之后执行。此挂钩已在 NativeScript 6.0 中删除。

# hookArgs 的结构

hookArgs是含有钩状方法的所有参数的对象。更多信息可以在这里找到。

TIP

注意:hookArgs 每个挂钩的对象都不相同。

例如,假设checkForChanges我们的插件或应用程序中有一个钩子。当前,hookArgsfor checkForChangeshook 的结构如下:

{
    checkForChangesOpts: {
        platform,
        projectData,
        projectChangesOptions: {
            nativePlatformStatus,
            provision,
            teamId,
            bundle,
            release
        }
    }
}

在即将发布的 6.0 版本中,以上结构将更改为以下内容:

{
  projectData, platformData, prepareData;
}

让我们看看钩子使用来自的平台属性的情况hookArgs

module.exports = function(hookArgs) {
  const platform = hookArgs.checkForChangesOpts.platform;
  console.log(`The hook will be executed for ${platform} platform.`);
};

在 NativeScript 6.0 中,以上代码需要更改为:

module.exports = function(hookArgs) {
  const platform = hookArgs.prepareData.platform;
  console.log(`The hook will be executed for platform ${platform}.`);
};

您可以轻松地使代码向后和向前兼容,如下所示:

module.exports = function(hookArgs) {
  const platform = (hookArgs.checkForChangesOpts && hookArgs.checkForChangesOpts.platform) || (hookArgs.prepareData && hookArgs.prepareData.platform);
};

我们已经迁移了以下挂钩,以使其向后和向前兼容:

  • 原生脚本
  • 本地脚本
  • nativescript 单元测试运行程序
  • nativescript-plugin-firebase
  • Kinvey-Nativescript-SDK

这是 NativeScript CLI 支持的所有挂钩的完整映射:

HookArgs 6.0 之前的版本 HookArgs 6.0 状态
准备 {config} {prepareData} CHANGED 更多信息,可以发现在这里。
checkForChanges {platform,projectData,projectChangesOptions} {platformData,projectData,prepareData} CHANGED 更多信息,可以发现在这里。
预览前同步 {projectData,hmrData,config,externals} {platform,projectDir,projectData,useHotModuleReload,env} CHANGED 更多信息,可以发现在这里。
watchPatterns {liveSyncData,projectData} {platformData,projectData} CHANGED 更多信息,可以发现在这里。
观看前 {projectData,config,filesToSync,filesToRemove,hmrData} {platformData,projectData,prepareData} CHANGED 更多信息,可以发现在这里。
观察后 {projectData} 同前 未更改 更多信息可以在这里找到。
after-createProject {projectCreationSettings} 同前 未更改 更多信息可以在这里找到。
之前的 AndroidPlugin {pluginBuildSettings} 同前 未更改 更多信息可以在这里找到。
安装 {packageFilePath,appIdentifier} 同前 未更改 更多信息可以在这里找到。
应该准备 {shouldPrepareInfo} 在这里可以找到更多信息。
cleanApp {platformInfo} HOOK DELETED 在这里可以找到更多信息。

TIP

注意:如果您的挂钩属于 CHANGED 类别并且使用hookArgs,则需要迁移挂钩。

注意:如果您的钩子属于“未更改”类别 ,则仍然必须从钩子中检查注入的服务的名称。

注意:如果您的钩子在 DELETED 类别中,则可以打开一个问题并描述您的情况,以便我们可以帮助您找到适合您情况的钩子。

# 从 NativeScript CLI 注入的服务

NativeScript CLI 提供了非常强大 in-process 的钩子执行功能,使您可以使用注入器中可用的 NativeScript CLI 中的所有注册服务。的完整列表可以在此处找到。当前的解析机制基于名称而不是对象类型。如果从 NativeScript CLI 中删除或重命名了注入的服务,并且未根据该更改迁移该挂钩,则 NativeScript CLI 将不会执行该挂钩并显示警告。

让我们看一下具有以下注入服务的钩子:

module.exports = function($logger, $platformsData, $projectData, hookArgs) {};

上面的挂钩将无法通过 NativeScript 6.0 CLI 执行,因为$platformsData由于将其$platformsData重命名为,因此无法解析$platformsDataService

TIP

注意:NativeScript CLI 将警告您挂钩将不会执行,因为它具有无效的参数-$ platformsData。

在这种情况下,我们需要迁移钩子:

module.exports = function($logger, $projectData, $injector, hookArgs) {
  const platformsData = getPlatformsData($injector);
};
function getPlatformsData($injector) {
  try {
    return $injector.resolve('platformsData');
  } catch (err) {
    return $injector.resolve('platformsDataService');
  }
}

这是从 NativeScript CLI 注入最频繁的服务的映射:

先前的服务名称 6.0 在 6.0 中替换
$ platformsData $ platformsDataService
$ liveSyncService $ runController
$ platformService $ runController
$ projectData $ projectData
$ logger $ logger

TIP

注意:该$logger.out方法在 NativeScript 6.0 中删除,并替换为$logger.info

# 摘要

这就是 NativeScript 6.0 版本挂钩的所有更改。我们鼓励您迁移钩子并使它们向后兼容。这样,如果您是插件作者,其他开发人员将能够同时使用 5.4 和 6.0 CLI 来使用您的插件,并且您不会强迫他们升级其现有应用程序。处理重大更改可能很烦人,但是我们在这里,将帮助您使过渡更加顺畅。只需创建一个描述您的问题的新问题,我们将协助您找到解决方案!