当尝试将 NS 6.5.1 迁移到 NS 8.1.4 TextField 时失败。
我用:
- @nativescript-cli@8.1.4
- @nativescript/core@8.1.5
- 节点 v16.13.0
- NPM v8.1.0
在 ns clean 之后,我执行 ns doctor:
$ ns doctor
Error while loading nativescript-cloud is: Default commands should be required before child commands
✔ Getting environment information
No issues were detected.
✔ Your ANDROID_HOME environment variable is set and points to correct directory.
✔ Your adb from the Android SDK is correctly installed.
✔ The Android SDK is installed.
✔ A compatible Android SDK for compilation is found.
✔ Javac is installed and is configured properly.
✔ The Java Development Kit (JDK) is installed and is configured properly.
✔ Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.
✔ Getting NativeScript components versions information...
✔ Component nativescript has 8.1.4 version and is up to date.
✔ Component @nativescript/core has 8.1.5 version and is up to date.
✖ Component @nativescript/ios is not installed.
✔ Component @nativescript/android has 8.1.1 version and is up to date.
运行应用程序时:
$ ns run android --env.development --env.api=staging --log trace --env.android
Successfully synced application com.-.app on device d4dde974.
Will emit event runOnDeviceStarted with data {
projectDir: '/home/xavier/PhpstormProjects/crmhex-app',
deviceIdentifier: 'd4dde974',
applicationIdentifier: 'com.-.app'
}
JS: {NSVue (Vue: 2.6.12 | NSVue: 2.9.0)} -> CreateElement(Frame)
....
应用程序打开但如果专注于 TextField 控制台时会出错:
JS: Received discarded exception:
JS: Calling js method afterTextChanged failed
JS: TypeError: Cannot read property 'text' of undefined
我的 Package.json 实际迁移尝试是:
{
"name": "-",
"main": "app/main.js",
"version": "0.2.3",
"description": "A native application built with NativeScript-Vue",
"author": "-",
"license": "MIT",
"nativescript": {
"id": {
"ios": "com.-.app",
"android": "com.-.app"
}
},
"dependencies": {
"@nativescript/core": "~8.1.1",
"@nativescript/firebase": "^11.1.3",
"@nativescript/localize": "^5.0.4",
"@nativescript/theme": "~3.0.1",
"@sergeymell/nativescript-svg": "^1.1.2",
"@teammaestro/nativescript-svg": "^1.0.1",
"@triniwiz/nativescript-socketio": "^5.0.1",
"@triniwiz/nativescript-toasty": "^4.1.3",
"@vue/devtools": "^5.3.3",
"axios": "^0.19.2",
"clean-webpack-plugin": "^4.0.0",
"dayjs": "^1.8.26",
"lodash.chunk": "^4.2.0",
"lokijs": "^1.5.12",
"nativescript-advanced-permissions": "^1.2.0",
"nativescript-applozic-chat-fork": "^2.2.0",
"nativescript-appversion": "^1.4.4",
"nativescript-background-http": "^4.2.1",
"nativescript-carousel": "^7.0.1",
"nativescript-clipboard": "^1.2.0",
"nativescript-email": "^1.6.0",
"nativescript-fingerprint-auth": "^7.0.2",
"nativescript-http-formdata": "^2.1.0",
"nativescript-intl": "^4.0.1",
"nativescript-iqkeyboardmanager": "^1.5.1",
"nativescript-localstorage": "^2.0.2",
"nativescript-mediafilepicker": "^4.0.2",
"nativescript-modal-datetimepicker": "^1.2.2",
"nativescript-secure-storage": "^2.6.0",
"nativescript-ui-gauge": "^8.0.0",
"nativescript-vue": "~2.9.0",
"nativescript-vue-devtools": "^1.5.1",
"nativescript-vue-navigator": "^0.2.0",
"nativescript-webview-interface": "^1.4.3",
"nativescript-windowed-modal": "^7.0.0",
"patch-package": "^6.2.2",
"vue-cli": "^2.9.6",
"vuex": "^3.3.0",
"vuex-extensions": "^1.1.5"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@babel/runtime": "^7.6.2",
"@nativescript/android": "8.1.1",
"@nativescript/webpack": "~5.0.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^24.9.0",
"babel-loader": "^8.1.0",
"babel-plugin-module-resolver": "^4.0.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^6.2.2",
"html-loader": "^0.5.5",
"nativescript-vue-template-compiler": "~2.9.0",
"prettier": "^2.0.5",
"prettier-eslint": "^10.1.1",
"sass": "~1.39.0",
"tns-android": "6.5.0",
"typescript": "~4.3.5",
"vue-loader": "^15.9.2"
},
"scripts": {
"preinstall": "chmod +x ./entitlements.sh",
"postinstall": "./entitlements.sh & patch-package",
"lint": "eslint --ext .js,.vue src test",
"lint-autofix": "eslint --ext .js,.vue src test --fix",
"eslint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check"
}
}
我的 webpack.config.js 实际迁移尝试是:
// New from migration
const webpack = require("@nativescript/webpack");
const {resolve, sep, join} = require("path");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const NsVueTemplateCompiler = require("nativescript-vue-template-compiler");
const {exec} = require("child_process");
const countryFiles = require("./lib/copy-country-files");
module.exports = (env) => {
webpack.init(env);
//Copy configuration file for applozic theme to platform android
if (env.android) {
exec('cp -Rf app/App_Resources/Android/applozic-settings.json platforms/android/app/src/main/assets/applozic-settings.json', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log('Configured applozic theme!');
});
exec('cp -Rf app/App_Resources/Android/FcmListenerService.java platforms/android/app/src/main/java/com/tns/FcmListenerService.java', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log('Configured applozic notifications!');
});
}
// Add your custom Activities, Services and other android app components here.
const appComponents = env.appComponents || [];
appComponents.push(...[
"@nativescript/core/ui/frame",
"@nativescript/core/ui/frame/activity",
]);
const platform = env && (env.android && "android" || env.ios && "ios" || env.platform || 'android');
if (!platform) {
throw new Error("You need to provide a target platform!");
}
const platforms = ["ios", "android"];
const projectRoot = __dirname;
if (env.platform) {
platforms.push(env.platform);
}
// Default destination inside platforms/<platform>/...
//const dist = resolve(projectRoot, webpack.getAppPath(platform, projectRoot));
const {
// The 'appPath' and 'appResourcesPath' values are fetched from
// the nsconfig.json configuration file.
appPath = "app",
appResourcesPath = "app/App_Resources",
// You can provide the following flags when running 'tns run android|ios'
snapshot, // --env.snapshot
production, // --env.production
report, // --env.report
hmr, // --env.hmr
sourceMap, // --env.sourceMap
hiddenSourceMap, // --env.hiddenSourceMap
unitTesting, // --env.unitTesting
verbose, // --env.verbose
snapshotInDocker, // --env.snapshotInDocker
skipSnapshotTools, // --env.skipSnapshotTools
compileSnapshot, // --env.compileSnapshot
country, // --env.country
} = env;
const useLibs = compileSnapshot;
const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
const mode = production ? "production" : "development"
if (country) {
countryFiles.checkCountryFiles(country);
}
// Learn how to customize:
// https://docs.nativescript.org/webpack
webpack.mergeWebpack({
mode: 'production',
resolve: {
fallback: {
// Disable node shims that conflict with NativeScript
http: false,
https: false,
timers: false,
setImmediate: false,
fs: false,
__dirname: false,
url: false,
zlib: false,
tty: false,
util: false,
url: false,
assert: false,
stream: false,
os: false,
fileSystem: false
}
}
})
/*const projectRoot = __dirname;
const appPath = "app";
const appFullPath = resolve(projectRoot, appPath);
const alias = env.alias || {};
alias['~'] = appFullPath;
alias['@'] = appFullPath;
alias['vue'] = 'nativescript-vue';
alias['Models'] = appFullPath + '/imports/models';
alias['Components'] = appFullPath + '/imports/components';
alias['Filters'] = appFullPath + '/imports/filters';
alias['Services'] = appFullPath + '/imports/services';
alias['Constants'] = appFullPath + '/imports/constants';
alias['Exceptions'] = appFullPath + '/imports/exceptions';
alias['Mixins'] = appFullPath + '/imports/mixins';
alias['Utils'] = appFullPath + '/utils';*/
webpack.chainWebpack(
config => {
// change the "@" alias to "app/libs"
config.resolve.alias.set('@', resolve(__dirname, 'app'))
config.resolve.alias.set('~', resolve(__dirname, 'app'))
config.resolve.alias.set('vue', 'nativescript-vue')
config.resolve.alias.set('Models', resolve(__dirname, 'app') + '/imports/models')
config.resolve.alias.set('Components', resolve(__dirname, 'app') + '/imports/components')
config.resolve.alias.set('Filters', resolve(__dirname, 'app') + '/imports/filters')
config.resolve.alias.set('Services', resolve(__dirname, 'app') + '/imports/services')
config.resolve.alias.set('Constants', resolve(__dirname, 'app') + '/imports/constants')
config.resolve.alias.set('Exceptions', resolve(__dirname, 'app') + '/imports/exceptions')
config.resolve.alias.set('Mixins', resolve(__dirname, 'app') + '/imports/mixins')
config.resolve.alias.set('Utils', resolve(__dirname, 'app') + '/utils')
config.resolve.alias.set('tns-core-modules', "@nativescript/core")
config.plugin('VueLoaderPlugin')
config.plugin('DefinePlugin').tap(args => {
Object.assign(args[0], {
'API_ENV': JSON.stringify(env.api),
'TNS_ENV': JSON.stringify(mode),
})
return args
})
/*config.module.rule([join(appFullPath, entryPath + ".js"), join(appFullPath, entryPath + ".ts")]).use('nativescript-dev-webpack/style-hot-loader').loader('nativescript-dev-webpack/android-app-components-loader').options({
modules: appComponents
}),*/
/*config.module.rule('app/css').use('nativescript-dev-webpack/style-hot-loader').loader('nativescript-dev-webpack/css2json-loader').options({
useForImports: true
}),
config.module.rule('app/scss').use('nativescript-dev-webpack/style-hot-loader').loader('nativescript-dev-webpack/css2json-loader').options({
useForImports: true
}),*/
/*config.module.rule('app/css').exclude.add('app/css').use('nativescript-dev-webpack/style-hot-loader').loader('nativescript-dev-webpack/apply-css-loader.js').options({
url: false
}),
config.module.rule('app/scss').exclude.add('app/scss').use('nativescript-dev-webpack/style-hot-loader').loader('nativescript-dev-webpack/apply-css-loader.js').options({
url: false
}),*/
config.module.rule('js').use('babel-loader').loader('babel-loader')
/*config.module.rule('ts').use('ts-loader').loader('ts-loader').options({
appendTsSuffixTo: [/\.vue$/],
allowTsInNodeModules: true,
compilerOptions: {
declaration: false
}
}),*/
config.module.rule('vue').use('vue-loader').options({
compiler: NsVueTemplateCompiler,
})
// config.module.rule('html').use('html-loader').loader('html-loader') // TODO fix error SCSS {
})
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
return webpack.resolveConfig();
};