返回博客首页
← 所有文章

将 CLI 钩子迁移到 NativeScript 6.0

2019 年 7 月 9 日 - 作者:Fatme Zeyneva

您可能知道,即将发布的 NativeScript 6.0 版本只 支持捆绑构建,您将无法再运行您的应用程序,除非使用 webpack。这些工作流程更改也会影响 NativeScript CLI 中的钩子机制。

在本文中,我们将探讨什么是 NativeScript 钩子,以及如何将您的钩子迁移到 NativeScript 6.0 CLI。

简而言之的 NativeScript 钩子

NativeScript 钩子是可执行的代码段或 Node.js 脚本,应用程序或插件开发者可以添加它们来定制特定 NativeScript 命令的执行。它们赋予您通过将不同的部分插入应用程序的构建过程来执行特殊活动的能力。NativeScript CLI 支持两种不同的执行钩子方式

  • 进程内执行
  • 通过 Node.js spawn 函数执行生成

钩子的进程内执行

进程内执行仅适用于 JavaScript 钩子。NativeScript CLI 根据 module.exports 语句来确定是否应该进程内执行钩子。因此,要启用进程内执行,您只需要在钩子中有一个 module.exports = ... 语句。例如,如果钩子脚本是

module.exports = function($logger) { }

然后,钩子脚本将被 CLI 要求,并且导出的函数将通过注入器调用。进程内执行赋予您使用 NativeScript CLI 中任何可用服务的灵活性。

钩子的生成执行

如果 NativeScript CLI 找不到 module.exports = 语句,它将使用 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
}

**注意**: hookArgs 对象对于每个钩子都是不同的。

我是否需要迁移?

有了这些背景知识,让我们看看您,应用程序或插件开发者,需要做什么才能将您的钩子迁移到 NativeScript 6.0。

如果您的应用程序或插件没有使用钩子,则无需迁移,也不需要采取任何其他措施。您可以现在停止阅读。

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

NativeScript 钩子中的确切更改是什么?

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

  • 钩子工作流程
  • hookArgs 的结构
  • NativeScript CLI 中注入服务的名称

**注意**: 关于 hookArgs 结构和注入服务名称的更改只影响进程内钩子。

您可以在以下情况下安全地跳过接下来的两节

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

钩子工作流程

NativeScript CLI 中的钩子机制旨在允许在 CLI 代码的某些特定部分执行之前和之后执行额外的操作。如果您返回具体的值或 Promise,则钩子被认为是 before/after 钩子。

下面的钩子将被作为 before/after 钩子执行

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

以下是 NativeScript CLI 支持的所有钩子

prepare

此钩子在 NativeScript CLI 启动 webpack 编译和本机文件监视器(例如,应用程序的实际准备工作)之前/之后执行。

  • 使用传统工作流程时,它在应用程序的初始同步时执行,并且在 NativeScript CLI 在监视模式下运行时,在每次更改时执行。
  • 在 6.0 CLI 中,钩子仅在应用程序的初始同步时执行。

checkForChanges

此钩子在 NativeScript CLI 检查应用程序中是否存在更改之前/之后执行。NativeScript CLI 保持应用程序的状态,并根据该状态来决定是否应该重建、重新安装或重新启动设备上的应用程序。该钩子在使用传统工作流程时在 prepare 钩子之前执行,但在 6.0 CLI 中将在其之后执行。

  • 使用传统工作流程时,该钩子在应用程序的初始同步时执行,并且在 NativeScript CLI 在监视模式下运行时,在每次更改时执行。
  • 在 6.0 CLI 中,该钩子在应用程序的初始同步时执行。NativeScript CLI 检查从上次执行开始是否有更改的本机文件。本机文件是 App_Resources 和 platforms 文件夹中的所有文件。当有更改的本机文件时,NativeScript CLI 会重建应用程序。

before-preview-sync

当执行 preview 命令时,NativeScript CLI 会显示一个二维码。当用设备扫描二维码并将设备报告给 CLI 时,此钩子会执行。

watchPatterns

此钩子在 NativeScript CLI 尝试确定用于监视应用程序的 glob 模式之前执行。此处的目的是允许您在您想要监视其他目录或从监视中排除目录的情况下更改模式。

before-watch

此钩子在 NativeScript CLI 启动对项目目录的监视之前执行。

after-watch

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

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

after-createProject

此钩子在从模板创建项目后执行。

buildAndroidPlugin

此钩子在构建 Android 插件的 .aar 文件之前/之后执行。

install

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

shouldPrepare

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

cleanApp

此钩子在 NativeScript CLI 清理 platforms 目录中的 app 目录之前/之后执行。该钩子在 NativeScript 6.0 中被删除了。

hookArgs 的结构

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

**注意**: hookArgs 对象对于每个钩子都是不同的。

例如,假设我们在插件或应用程序中有一个 checkForChanges 钩子。目前 checkForChanges 钩子的 hookArgs 结构如下

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

随着即将发布的 6.0 版本,上面的结构将更改为以下结构

{
    projectData,
    platformData,
    prepareData
}

让我们看看钩子使用 hookArgs 中的 platform 属性的情况

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 CLI 支持的所有钩子的完整映射

6.0 之前的 HookArgs 6.0 的 HookArgs 状态
prepare { config } { prepareData } 已更改
更多信息可以在 这里找到。
checkForChanges { platform, projectData, projectChangesOptions } { platformData, projectData, prepareData } 已更改
更多信息可以在 这里找到。
before-preview-sync { projectData, hmrData, config, externals } { platform, projectDir, projectData, useHotModuleReload, env } 已更改
更多信息可以在 这里找到。
watchPatterns { liveSyncData, projectData } { platformData, projectData } 已更改
更多信息可以在 这里找到。
before-watch { projectData, config, filesToSync, filesToRemove, hmrData } { platformData, projectData, prepareData } 已更改
更多信息可以在 这里找到。
after-watch { projectData } 未更改
更多信息可以在 这里找到。
after-createProject { projectCreationSettings } 未更改
更多信息可以在 这里找到。
beforeAndroidPlugin { pluginBuildSettings } 未更改
更多信息可以在 这里找到。
install { packageFilePath, appIdentifier } 未更改
更多信息可以在 这里找到。
shouldPrepare { shouldPrepareInfo } - 钩子已删除
更多信息可以在 这里找到。
cleanApp { platformInfo } - 钩子已删除
更多信息可以在 这里找到。

**注意**: 如果您的钩子属于 已更改 类别并且使用 hookArgs,则需要迁移钩子。

**注意**: 如果您的钩子属于 未更改 类别,您仍然需要检查钩子内部注入服务的名称。

**注意**: 如果您的钩子属于 已删除 类别,您可以打开一个问题并描述您的场景,以便我们帮助您找到适合您的情况的钩子。

NativeScript CLI 中的注入服务

NativeScript CLI 提供了一个非常强大的进程内钩子执行功能,允许您使用 NativeScript CLI 中注入器中可用的任何注册服务。完整列表可以在 这里找到。当前的解析机制基于名称,而不是对象类型。如果注入服务从 NativeScript CLI 中删除或重命名,并且钩子没有根据该更改进行迁移,NativeScript CLI 将不会执行钩子,并且会显示警告。

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

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

上面的钩子将不会使用 NativeScript 6.0 CLI 执行,因为它将无法解析 $platformsData,因为 $platformsData 已重命名为 $platformsDataService

**注意**: 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

注意$logger.out 方法在 NativeScript 6.0 中被删除,并被 $logger.info 替换。

总结

以上是关于 NativeScript 6.0 版本钩子更改的所有内容。我们建议您迁移您的钩子并使其向后兼容。这样,如果您是插件作者,其他开发者就可以使用您的插件与 5.4 和 6.0 CLI 兼容,您也不会强迫他们升级现有的应用程序。处理重大更改可能会很烦人,但我们在这里,将帮助您更顺利地过渡。只需 创建一个新问题 描述您的问题,我们会帮助您找到解决方案!