Closed schnapzz closed 3 years ago
This is what I did in my app to make this plugin work with Nativescript 7 without having to modify the source files
In the webpack config I added a few alias records:
// webpack.config.js
// Shim old core modules view and text base to make nativescript-drop-down work with ns7
alias['ui/data/observable-array'] = resolve(projectRoot, 'shims/view.js');
alias['ui/core/view'] = resolve(projectRoot, 'shims/view.js');
alias['ui/text-base'] = resolve(projectRoot, 'shims/view.js');
alias['ui/editable-text-base/editable-text-base'] = resolve(projectRoot, `node_modules/${coreModulesPackageName}`, 'ui/editable-text-base');
The last alias just redirects the editable-text-base
import one level up as Nativescript 7 switched to using index
files.
The others however point to a custom shim that I made to fix the remaining issues. The shim is as follows:
// shims/view.js
import { ObservableArray as _ObservableArray, Utils, View as _View } from '@nativescript/core';
// Export exepected properties
export {
backgroundColorProperty,
CoercibleProperty,
colorProperty,
CSSProperty,
CSSType,
fontInternalProperty,
fontSizeProperty,
Length,
letterSpacingProperty,
makeParser,
makeValidator,
paddingBottomProperty,
paddingLeftProperty,
paddingRightProperty,
paddingTopProperty,
Property,
textAlignmentProperty,
textDecorationProperty,
textTransformProperty,
} from '@nativescript/core';
export const layout = Utils.layout;
// Wrap ES7 classes from Nativescript to be extendable from ES2015 prototypes
// Proxy the original ObservableArray class to embed an `apply` function
export const ObservableArray = new Proxy(_ObservableArray, {
apply(target, thisArg, args) {
// Create a dummy constructor to bind the `thisArg` prototype to
function TempHelperConstructor() {
//
}
// Override the prototype with the actual class that we want
TempHelperConstructor.prototype = thisArg;
// Reflect.construct allows us to call the class constructor without the `new` keyword
// And enables us to change the `this` context
return Reflect.construct(target, args, TempHelperConstructor);
},
});
// Proxy the original View class
export const View = new Proxy(_View, {
apply(target, thisArg, args) {
function TempHelperConstructor() {
//
}
TempHelperConstructor.prototype = thisArg;
return Reflect.construct(target, args, TempHelperConstructor);
},
});
There are two main goals this shim is accomplishing. The first is to reexport expected properties that pre-Nativescript 7 was exporting on almost every component. The second issue was dealing with the compiled plugin output (es2015) which is a Prototype based "class" that was extending an es6+ Class. I needed to handle both side stepping the new
keyword requirement for construction, but also maintaining proper this
context for extending.
This got the plugin working correctly for me on a Nativescript 7 project without touching the plugin source code.
Surely an update to this plugin to switch to ES7 would be ideal, but this works in the meantime ;)
Edit: Updated snippets to add support for the ValueList
class
@Archez your workaround saved my butt! I am building a free non-commercial app and I can't afford to subscribe for just this plugin (LOL)
Sorry to spring this on you, but have you encountered this error when using ValueList
?
TypeError: Class constructor ObservableArray cannot be invoked without 'new'
Thanks a ton @Archez ! Haven't tried it out yet but appreciate the quick response. I'll see if I can get around testing it next week!
@kryoware
TypeError: Class constructor ObservableArray cannot be invoked without 'new'
It would be similar to what I did for the View
class:
import { ObservableArray as _ObservableArray } from '@nativescript/core';
// Proxy the original ObservableArray
export const ObservableArray = new Proxy(_ObservableArray, {
apply(target, thisArg, args) {
function TempHelperConstructor() {
//
}
TempHelperConstructor.prototype = thisArg;
return Reflect.construct(target, args, TempHelperConstructor);
},
});
And adding an alias record for it in webpack config
alias['ui/data/observable-array'] = resolve(projectRoot, 'shims/view.js');
So you can either throw it in the same shim, or separate it out if you want. I forgot I had created my own implementation of ValueList
in my project and didn't hit this issue. (I haven't tested this out but should work 👍 )
This is what I did in my app to make this plugin work with Nativescript 7 without having to modify the source files
In the webpack config I added a few alias records:
// webpack.config.js // Shim old core modules view and text base to make nativescript-drop-down work with ns7 alias['ui/data/observable-array'] = resolve(projectRoot, 'shims/view.js'); alias['ui/core/view'] = resolve(projectRoot, 'shims/view.js'); alias['ui/text-base'] = resolve(projectRoot, 'shims/view.js'); alias['ui/editable-text-base/editable-text-base'] = resolve(projectRoot, `node_modules/${coreModulesPackageName}`, 'ui/editable-text-base');
The last alias just redirects the
editable-text-base
import one level up as Nativescript 7 switched to usingindex
files. The others however point to a custom shim that I made to fix the remaining issues. The shim is as follows:// shims/view.js import { ObservableArray as _ObservableArray, Utils, View as _View } from '@nativescript/core'; // Export exepected properties export { backgroundColorProperty, CoercibleProperty, colorProperty, CSSProperty, CSSType, fontInternalProperty, fontSizeProperty, Length, letterSpacingProperty, makeParser, makeValidator, paddingBottomProperty, paddingLeftProperty, paddingRightProperty, paddingTopProperty, Property, textAlignmentProperty, textDecorationProperty, textTransformProperty, } from '@nativescript/core'; export const layout = Utils.layout; // Wrap ES7 classes from Nativescript to be extendable from ES2015 prototypes // Proxy the original ObservableArray class to embed an `apply` function export const ObservableArray = new Proxy(_ObservableArray, { apply(target, thisArg, args) { // Create a dummy constructor to bind the `thisArg` prototype to function TempHelperConstructor() { // } // Override the prototype with the actual class that we want TempHelperConstructor.prototype = thisArg; // Reflect.construct allows us to call the class constructor without the `new` keyword // And enables us to change the `this` context return Reflect.construct(target, args, TempHelperConstructor); }, }); // Proxy the original View class export const View = new Proxy(_View, { apply(target, thisArg, args) { function TempHelperConstructor() { // } TempHelperConstructor.prototype = thisArg; return Reflect.construct(target, args, TempHelperConstructor); }, });
There are two main goals this shim is accomplishing. The first is to reexport expected properties that pre-Nativescript 7 was exporting on almost every component. The second issue was dealing with the compiled plugin output (es2015) which is a Prototype based "class" that was extending an es6+ Class. I needed to handle both side stepping the
new
keyword requirement for construction, but also maintaining properthis
context for extending.This got the plugin working correctly for me on a Nativescript 7 project without touching the plugin source code.
Surely an update to this plugin to switch to ES7 would be ideal, but this works in the meantime ;)
Edit: Updated snippets to add support for the
ValueList
class
To others who's not that strong with webpack and shims, I struggled to make it work until I realised the changes had to be done AFTER the following if statement:
if (hasRootLevelScopedModules) {
coreModulesPackageName = "@nativescript/core";
alias["tns-core-modules"] = coreModulesPackageName;
}
Thanks again @Archez for the neat workaround!
@PeterStaev Hi, I'm trying to update the plugin to NS7 right now, but I'm having some problems. In the drop-down.ios.ts file, you are importing stuff like Length, backgroundColorProperty, etc. from drop-down-common, but these properties/members don't exist there. Did you remove something from the code on GitHub?
@ReazerDev , I have not removed anything. Whatever is in GH is the latest working version that is available on NPM. The missing properties are coming from the re-export of view: https://github.com/PeterStaev/NativeScript-Drop-Down/blob/8aed0a461ab62dafcabd9dff2c1c483784442d34/drop-down-common.ts#L24
Hi, @PeterStaev I'm kinda stuck^^ Would you be willing to help a little? The demo app is installing fine, but once the view is being rendered, I get this error:
My current status is in my branch
@ReazerDev , you will have to rewrite the way the angular code is compiled. The one that was used in pre-NS6 is NOT compatible with Angular Ivy (Angular 9+).
I would suggest first getting the non-NG demo working and then see how to fix the Angular component.
Ok nice, done :) Both the normal demo and the ng demo work on android now!
It'd be awesome if someone could test it on iOS. I don't own any apple devices lol
Any updates on this?
Any updates on this?
@OPADA-Eng Just a small problem on android, that I have to fix. Tho I won't be able to work on it, til Wednesday, got an exam coming up.
@ReazerDev Thanks for your efforts and good luck in your exam.
Any news @ReazerDev? I have to deploy my app so this plugin is breaking it, and I have to decide deployment with or without it.
@OPADA-Eng You can see the current status here: https://github.com/PeterStaev/NativeScript-Drop-Down/pull/257
Project info node: v14 N-cli: 7.0.11 N-core: 7.0.13 ios-runtime: 7.0.6 android-runtime: 7.0.1 Drop-down: 5.0.6 (latest)
Description of problem 1: Build fails during
ns build ios
orns build android
with the following error:This can be fixed easily by updating the requires in drop-down.ios.js and drop-down.android.js and i've done so for quite some time .If time permits i'll send a PR with this update.
Description of problem 2: With the updated namespacing, the app is buildable. The next issue comes when using the drop-down menu, which causes the following error:
Haven't figured how to solve this but recon that it isn't a major thing. If anybody got a suggestion as to how to solve this or know of another plugin with likewise functionality it'll be greatly appreciated, since it hinders us from releasing a new version of our app.