备受期待的 NativeScript 6.0 版本即将发布!此版本中最大的两个变化是 AndroidX 支持和捆绑包 (仅限 webpack) 工作流程。这两个变化都可能需要对现有项目进行更改。请阅读本文,了解如何将您的应用程序代码迁移到 NativeScript 6.0。
tns migrate
是一个新的 CLI 命令,旨在帮助进行 NativeScript 6.0 迁移过程。在现有项目中执行此命令将更新
更新您的 NativeScript CLI 并执行项目中的迁移命令
npm install --global nativescript@latest
tns migrate
然后,使用熟悉的命令运行应用程序
tns run
如果您在开发工作流程中遇到问题,则可能需要更改应用程序代码以使其与 NativeScript 6.0 兼容。阅读本文的其余部分以了解如何操作。如果您的问题未提及,请在 Github 上提交问题。
NativeScript 6.0 支持 Android 扩展库 (AndroidX)。不再支持 Android 支持库。任何依赖于支持库的应用程序和插件代码都必须改为使用 AndroidX。要了解如何迁移,请参阅专门的博文。
NativeScript CLI 钩子允许您自定义 CLI 命令的执行。它们广泛用于 NativeScript 插件中。钩子 API 在 6.0 版本中发生了更改。如果您的构建失败并出现以下错误,则可能使用了过时的插件
Cannot read property X of undefined.
要了解如何更新过时的钩子,请参阅本文。
在 6.0 版本之前,NativeScript 用于支持两种构建应用程序的方式:
tns build
- 传统工作流程,它将源代码目录 (src/) 的完整内容复制到构建的应用程序中;
tns build --bundle
- 捆绑包工作流程,它依赖于 webpack 将源代码目录 (src/) 捆绑到几个输出文件中。
NativeScript 6.0 仅支持捆绑包工作流程。更新项目时,您需要确保它可以使用 webpack 进行构建。NativeScript 团队付出了很多努力来缩小传统工作流程和捆绑包工作流程之间的差距。但是,这两种方法非常不同,它们的行为无法完全统一。下面将列出它们之间最常见的差异,以及每个差异的迁移步骤。
全部
以下代码尝试加载本地文件 - /assets/shipping.json。
export class CartService {
...
getShippingPrices() {
return this.http.get('/assets/shipping.json');
}
}
源目录中的所有文件都是构建应用程序的一部分。因此,/assets/shipping.json 文件将可用并成功加载。
Webpack 仅编译源代码中明确需要的或由 webpack 插件包含的文件。使用默认设置,/assets/shipping.json 将不会在构建的应用程序中,并且请求将失败。
配置 CopyWebpackPlugin
以将静态资源从您的项目移动到构建的应用程序中。
webpack.config.js
module.exports = env => {
…
const config = {
...
plugins: [
...
new CopyWebpackPlugin([
{ from: { glob: "assets/*.json" } },
{ from: { glob: "fonts/**" } },
{ from: { glob: "**/*.jpg" } },
{ from: { glob: "**/*.png" } },
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
}
全部
您需要使用 nativescript-worker-loader 插件来创建工作线程。确保使用下一个标记安装软件包
npm install nativescript-worker-loader@next --save-dev
请参阅文档以根据项目类型迁移您的代码。
Angular
考虑以下位于 app/item/items.component.ts 中的代码,它对 templateUrl
使用绝对路径
@Component({
selector: "ns-items",
templateUrl: "app/item/items.component.html"
})
export class ItemsComponent {
...
传统工作流程用于支持上述语法。
捆绑包工作流程不支持上述语法。templateUrl
和 styleUrls
路径相对于当前模块解析。
将绝对路径转换为相对路径
@Component({
selector: "ns-items",
templateUrl: "./items.component.html"
})
export class ItemsComponent {
...
TypeScript
以下代码使用 exports
对象导出函数
exports.onTap = function () {
alert("Hi there");
}
传统工作流程用于支持上述语法。
捆绑包工作流程不支持上述语法。
改为使用 export
关键字
export function onTap() {
alert("Hi there");
}
使用捆绑包工作流程,您现在可以在所有类型的项目中使用 ES6 模块语法 (导入和导出)。优先使用它而不是 CommonJS (require 和 exports),以帮助 webpack 从捆绑包中消除所有未使用的导出。
全部
考虑以下位于 app/nested-folder/test.ts 中的代码
console.log("__dirname", __dirname);
console.log("__filename", __filename);
在传统工作流程中,项目结构在构建的应用程序中保持不变。执行上述代码将导致以下控制台输出
__dirname /data/data/org.nativescript.ns5/files/app/nested-folder
__filename /data/data/org.nativescript.ns5/files/app/nested-folder/main-page.js
在捆绑包工作流程中,构建的应用程序打包在几个输出文件中。文件位置不会持久化。上述代码的输出将为
__dirname /data/data/org.nativescript.ns6/files/app
__filename /index.js
您可以使用 module.id
获取原始文件路径。
console.log(module.id) // ./nested-folder/main-page.ts
但是,如果您构建生产版本,则 module.id
将为一个数字。要强制 webpack 继续对模块 ID 使用文件路径,请将 namedModules
优化属性设置为 true
module.exports = env => {
…
const config = {
...
optimization: {
namedModules: true
}
}
__dirname
将指向捆绑包文件的绝对路径。使用 __dirname
和 module.id
,您可以计算模块的原始绝对文件路径和目录。
TypeScript
以下代码声明了一个枚举,但未定义它,然后使用它
declare const enum TestEnum {
value1 = 1,
value2 = 2
}
console.log("Printing the second enum value: ", TestEnum.value2);
上述语法受支持。传统工作流程用于依赖于 nativescript-dev-typescript 插件来执行 TypeScript 编译。该插件用于启动 TypeScript 编译器 - tsc
。
捆绑包工作流程在 transpileOnly
模式下使用 ts-loader
。枚举值未内联。运行上述代码会导致引用错误
ReferenceError: TestEnum is not defined
您需要修改 webpack.config.js
文件中的几个设置。在 ts-loader
的配置中,将 transpileOnly
设置为 false
。此外,请确保删除 ForkTypeChecking
插件。