Skip to content
This repository has been archived by the owner on Aug 7, 2021. It is now read-only.

XML Compatibility issue between NS-Angular and NS-Core #1121

Open
1 task done
NathanaelA opened this issue Jan 29, 2020 · 3 comments
Open
1 task done

XML Compatibility issue between NS-Angular and NS-Core #1121

NathanaelA opened this issue Jan 29, 2020 · 3 comments
Labels
angular feature migration-to-bundle The issue is describing a breaking change in the Bundle workflow compared to the Legacy one.

Comments

@NathanaelA
Copy link

NathanaelA commented Jan 29, 2020

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 6.3x

  • Cross-platform modules:

  • Android Runtime:6.3x

  • iOS Runtime: 6.3x

  • Plugin(s): Creating one 😀

  • Please, attach your package.json and webpack.config.js: STOCK -- just generated the demo apps with latest CLI.

Callstack

 Error: Parsing XML at 3:5
JS:  > Module 'null' not found for element '@nstudio/nativescript-camera-plus:CameraPlus'.
JS:    > require's first parameter should be string Error: Parsing XML at 3:5
JS:  > Module 'null' not found for element '@nstudio/nativescript-camera-plus:CameraPlus'.
JS:    > require's first parameter should be string
JS:  > require's first parameter should be string
JS:     at require (<anonymous>:1:266)
JS:     at _loop_1 (file:///node_modules/@nativescript/core/globals/register-module-helpers.js:83:0)
JS:     at loadModule (file:///node_modules/@nativescript/core/globals/register-module-helpers.js:91:0)
JS:     at file:///node_modules/@nativescript/core/ui/builder/component-builder/component-builder.js:30:0
JS:     at Object.getComponentModule (file:///node_modules/@nativescript/core/ui/builder/component-builder/component-builder.js:116:0)
JS:     at loadCustomComponent (file:///node_modules/@nativescript/core/ui/builder/builder.js:138:0)
JS:     at ComponentParser.push.../node_modules/@nativescript/core/ui/builder/builder.js.ComponentParser.buildComponent (file:///data/data/org.nativescript.demong...
JS: Failed Error: Parsing XML at 3:5
JS:  > Module 'null' not found for element '@nstudio/nativescript-camera-plus:CameraPlus'.
JS:    > require's first parameter should be string Error: Parsing XML at 3:5
JS:  > Module 'null' not found for element '@nstudio/nativescript-camera-plus:CameraPlus'.
JS:    > require's first parameter should be string
JS:  > require's first parameter should be string
JS:     at require (<anonymous>:1:266)
JS:     at _loop_1 (file:///node_modules/@nativescript/core/globals/register-module-helpers.js:83:0)
JS:     at loadModule (file:///node_modules/@nativescript/core/globals/register-module-helpers.js:91:0)
JS:     at file:///node_modules/@nativescript/core/ui/builder/component-builder/component-builder.js:30:0
JS:     at Object.getComponentModule (file:///node_modules/@nativescript/core/ui/builder/component-builder/component-builder.js:116:0)
JS:     at loadCustomComponent (file:///node_modules/@nativescript/core/ui/builder/builder.js:138:0)
JS:     at ComponentParser.push.../node_modules/@nativescript/core/ui/builder/builder.js.ComponentParser.buildComponent (file:///data/data/org.nativescript...

Describe the bug
I have a plugin that has its own custom XML/JS that it uses when it loads a model (using showmodal) the plugin works great on NS-Core. Unfortunately on Angular the webpack config breaks loading and the parse of NS-Core xml files.

The issue is that XML is treated differently between Angular webpack config and the NS-Core; when I manually changed my angular webpack.config.js file to be:

                { test: /\.xml$/, use: "nativescript-dev-webpack/xml-namespace-loader" },
                { test: /\.html$/, use: "raw-loader" },

Instead of both XML and HTML being raw-loader; my plugin will then work properly on Angular.

To Reproduce

  1. Have a XML file that is written as a NS-Core XML file with a namespaced component -- In my case this is it:
<Page xmlns:Cam="@nstudio/nativescript-camera-plus" shownModally="shownModally" unloaded="unloaded">
    <GridLayout backgroundColor="#00000000" rows="*,auto,auto" columns="*">
    <Cam:CameraPlus id="camPlus"
                    loaded="camLoaded"
                   ... more props ...
                    debug="false">
    </Cam:CameraPlus>
        <Button row="1" id="recordButton" text="Record" tap="handleRecording" visibility="collapsed"/>
        <Button row="2" id="cancelButton" text="Cancel" tap="cancel" visibility="collapsed"/>
    </GridLayout>
</Page>
  1. Use builder.Builder.parse(require("./camera.xml"),... So the xml is pulled into the bundle/vendor
  2. See error above...

Expected behavior
The plugin to work on all platforms equally well. 😀

Sample project
Need to check with client if I can share....

Workarounds

  • manually do this first:
    global.registerModule("@nstudio/nativescript-camera-plus", () => require('@nstudio/nativescript-camera-plus'));
    Before I call the Builder.parse function -- apparently the difference between the two webpack building methods; is the registerModule / namespaces are NOT discovered/added under angular; but they are added under NS-Core.

  • The other work around is to switch xml-loaders; but I can't expect clients to do that, and not sure the side effects it will cause for Angular apps using XML screens rather than html screens.

@DimitarTachev
Copy link
Contributor

@NathanaelA,

As far as I understand, the plugin is trying to use the NativeScript Core Builder.parse API in order to load a NativeScript Core view (an XML file) in an Angular app and this leads to an XML parsing exception runtime.

I won't recommend you using the above-mentioned workarounds as they add some partial NativeScript Core support in the Angular apps of the end-users.

I believe that the proper solution would be making the UI plugin itself Angular compatible, instead of trying to add a NativeScript Core view in Angular apps.

I suggest you take a look at the Support Angular in UI Plugins and Integrating UI Components With Angular articles.

@NathanaelA
Copy link
Author

@DimitarTachev - Go grab a cup of coffee; not sure you are all the way awake... 😀 (This is meant to be a joke! 😀 )


The page you linked to: https://docs.nativescript.org/angular/plugins/angular-third-party literally tells me to do exactly what my workaround is. 😀 Which is why I tried that workaround, because I've done enough plugins to have ideas what might be a potential cause/solution. 😀

Angular components are almost always just wrapped NS-Core components; sometimes they have extra pieces, but very frequently; it is just a simple registerModule call.
global.registerModule("plugin-namespace", () => require('plugin-name')); so that it is registered in the app as a valid namespace extension.

There are no issues using NS-Core components in Angular, Vue, Svelte, or even creating and disposing of them dynamically.


Now honestly, I don't know if this is something worth fixing, but it is a regression as it was something that used to work in NS < 6. But it is a corner case, and probably only a corner case a plugin would run into as if you are doing a Angular app; you won't normally be using the NS-Core builder to do things. But plugins might; and this is where the question of compatibility needs to be decided.

@DimitarTachev
Copy link
Contributor

@NathanaelA , I didn't get that you are doing the first workaround in the plugin itself. 😄

In the legacy workflow (before NativeScript 6.0 and without --bundle), we were copying all of the app files allowing any dynamic executions.

Once we've migrated to the Webpack workflow, we had issues with the NativeScript Core applications because the dependencies between the different views/components were not easily analyzable - you are able to navigate, build a dynamic view or reference UI from plugins by using simple strings (without importing/requiring any modules).
In order to keep the Webpack workflow as close as possible to the legacy one for NativeScript Core apps, we've included all XML, CSS and JS files from the app folder and we've implemented the above-mentioned xml-namespace-loader which is analyzing the XML namespace strings and automatically registering their dependencies (in this case the plugin files).

The reasons why we've not implemented a similar approach for the Angular apps are:

  1. We are using the AngularCompilerPlugin plugin which is automatically analyzing these dependencies and even creating additional files for the lazy routes. This plugin also has some strict restrictions for the loaders that should be used for the Angular files.
  2. Some of the users were using .xml instead of .html for their Angular view.
  3. Its a corner case that could be handled in the plugins by a manual registration.

I will mark the issue as a feature request but bear in mind that it would be a risky change.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
angular feature migration-to-bundle The issue is describing a breaking change in the Bundle workflow compared to the Legacy one.
Projects
None yet
Development

No branches or pull requests

2 participants