Node.js Modules

Is there any method of using Node.js modules (particularly the source modules like http, etc) in Fuse? They would open up a whole world of possibilities.

Hey!

As long as they don’t use any Node.js-specific APIs, then yes.

You can include any existing module in UX like this:

<JavaScript File="somemodule.js" ux:Global="somemodule" />

And in JS:

var somemodule = require('somemodule');

Most Node modules use the hidden Node API modules packaged directly within the Node executable but these API modules are available in the source version of Node as regular old .js files. Would scripts which relied on Node.js-specific APIs work if I included all the source modules using ux:Global?

Also; is it necessary to declare every single module referenced in every single file in the UX, or can require point to a .js path like so:

var differentmodule = require('../lib/a-different-module.js');

within somemodule.js without needing

<JavaScript File="../lib/a-different-module.js" ux:Global="a-different-module" />

in the MainView.ux,

With the file tree looking something like:

ADifferentModule
    ==> lib
        ==> a-different-module.js
MyApp
    ==> MainView.ux
    ==> somemodule.js

We haven’t tested the Node APIs, but as long as it’s just plain JS with no magic behind the scenes, it would “just work”.

For now you have to declare everything in UX by hand. We are looking into supporting paths in the future (directly from JS).

Ah I see, are paths supported in UX yet? As in can I declare a module like

<JavaScript File="/lib/a-different-module.js" ux:Global="a-different-module" />

from my UX file or does it have to be in the same folder as the UX file?

Also, is it possible to declare all my modules in one UX file and then reference that in my MainView.ux? Like so:

Modules.ux:

<Panel xmlns:b="Fuse.BasicTheme" ux:Class="Modules">
  <JavaScript File='assets\modules\NodeSource\assert.js' ux:Global='assert' />
  <JavaScript File='assets\modules\NodeSource\buffer.js' ux:Global='buffer' />
  <JavaScript File='assets\modules\NodeSource\child_process.js' ux:Global='child_process' />
  <JavaScript File='assets\modules\NodeSource\cluster.js' ux:Global='cluster' />
  <JavaScript File='assets\modules\NodeSource\console.js' ux:Global='console' />
  <JavaScript File='assets\modules\NodeSource\constants.js' ux:Global='constants' />
  <JavaScript File='assets\modules\NodeSource\crypto.js' ux:Global='crypto' />
  <JavaScript File='assets\modules\NodeSource\dgram.js' ux:Global='dgram' />
  <JavaScript File='assets\modules\NodeSource\dns.js' ux:Global='dns' />
  <JavaScript File='assets\modules\NodeSource\domain.js' ux:Global='domain' />
  <JavaScript File='assets\modules\NodeSource\events.js' ux:Global='events' />
  <JavaScript File='assets\modules\NodeSource\freelist.js' ux:Global='freelist' />
  <JavaScript File='assets\modules\NodeSource\fs.js' ux:Global='fs' />
  <JavaScript File='assets\modules\NodeSource\http.js' ux:Global='http' />
</Panel>

Then in MainView.ux:

<App>
    <BlahBlahBlah Other App Content>
    <Modules />
</App>

Just so I don’t clutter up my MainView with references to modules.

Paths are supported on the File properties in UX, yes.

You can put your global modules in any UX file, they are globally available in JS.

Ah so I don’t need to actually call Modules.ux from the MainView.ux file?

I’ve tried some of the things we discussed but I seem to be getting this error:

error summary">Error Summary

`` `

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\Modules.ux(40,35): E1173: Expected identifier

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\Modules.ux(40,35): E1178: Expected ‘,’ or ‘;’

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\MainView.ux(36): E8001: Data type not found: Modules.ux

`

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\MainView.ux(36): E8001: Could not resolve type 'Modules.ux'

Here’s my MainView.ux:

<App Theme="Basic" ClearColor="#eeeeeeff">
    <DockPanel>
        <JavaScript File='MainView.js' />
        <StatusBarBackground DockPanel.Dock="Top" />
        <Button Alignment="BottomRight" IgnoreStyle="true" Clicked="{button}" Padding="20" ux:Name="FAB">
            <Text Value="+" TextColor="#6E751E" TextAlignment="Center" Alignment="VerticalCenter" FontSize="40" ux:Name="FABText">
                <Font File="assets/fonts/Lato-Regular.ttf" />
            </Text>
            <Circle Fill="#EDFF41" Height="70" Width="70" Opacity='1' ux:Name="FABTop"/>
            <Circle Fill="#E6F741" Height="70" Width="70" Opacity='0' ux:Name="FABPressed"/>
            <Circle Fill="#E6F741" Height="70" Width="70" Opacity="0.5" ux:Name="FABShadow">
                <DropShadow Angle="90" Color="#818181" Distance="10" Size="20" Spread="0.05" />
            </Circle>
            <Clicked>
                <Rotate Target="FABText" Degrees="360" Duration="0.25" Easing="SinusoidalInOut" EasingBack="Linear" DurationBack="0" DelayBack="0" />
            </Clicked>
            <WhilePressed>
                <Scale Factor="0.95" Duration="0.1" DurationBack="0.1" />
                <Change Target="FABPressed.Opacity" Value="1" />
                <Change Target="FABTop.Opacity" Value="0" Duration="0.1" />
            </WhilePressed>
        </Button>
        <!--
        <Rectangle Alignment="BottomRight" CornerRadius="50" ux:Name='getrect' Width="100" Height="100" Margin="10" Fill="White" >
            <Clicked>
                <Rotate Degrees='180' Duration='0.7' Easing="QuadraticInOut" />
                <Change Target='getrect.CornerRadius' Value='5' Duration="0.5" Easing='QuadraticInOut' />
                <Change Target='getrect.Height' Value='10000' Delay="1" Duration='3' DelayBack="-1"/>
                <Change Target='getrect.Width' Value='10000' Delay="1" Duration='3' DelayBack="-1"/>
                <Change Target='getrect.CornerRadius' Value='5' Delay='0.5' DelayBack='-1'/> 
            </Clicked>
        </Rectangle>
        -->
        <ScrollViewer ClipToBounds="true">
            <StackPanel>
                <Modules.ux />
                <Each Items='{itemList}'>
                    <Button IgnoreStyle="true">
                        <Grid ux:Name='updatesPanel' ColumnData="auto,1*,auto" Alignment="Top" Height="60" Opacity="1" BoxSizing="Limit">
                            <LimitBoxSizingData ux:Name="boxData" LimitHeight="100" LimitHeightUnit="Percent" />
                                <Panel>
                                    <StackPanel Alignment="Left">
                                        <Text ux:Name="itemText" Value="{summary}" Alignment="VerticalCenter" TextAlignment="Left" />
                                        <Text ux:Name="itemLocation" Value="{textlocation}" Alignment="VerticalCenter" TextAlignment="Left" Opacity='0' />
                                        <Text ux:Name="itemDescription" Value="{textdescription}" Alignment="VerticalCenter" TextAlignment="Left" Opacity='0' />
                                        <Text ux:Name="itemStart" Value="{textstart}" Alignment="VerticalCenter" TextAlignment="Left" Opacity='0' />
                                        <Text ux:Name="itemEnd" Value="{textend}" Alignment="VerticalCenter" TextAlignment="Left" Opacity='0' />
                                    </StackPanel>
                                </Panel>

                            <LayoutAnimation>
                                <Move RelativeTo="LayoutChange" X="1" Duration="0.6" Easing="BounceIn" />
                            </LayoutAnimation>
                            <AddingAnimation>
                                <Move RelativeTo="Size" X="1" Duration="0.4" Easing="CircularInOut" />
                            </AddingAnimation>
                            <RemovingAnimation>
                                <Move RelativeTo="Size" X="1" Duration="0.3" Easing="CircularInOut" />
                            </RemovingAnimation>

                            <Rectangle Height="1" ColumnSpan="3" Row="0" Alignment="Bottom" Fill="#ddd" />
                        </Grid>
                        <WhilePressed>
                                <Change Target="updatesPanel.Height" Value="120" Duration="0.1" Easing="SinusoidalInOut" />
                                <Change Target="itemLocation.Opacity" Value="1" Duration="0.05" />
                                <Change Target="itemDescription.Opacity" Value="1" Duration="0.05" />
                                <Change Target="itemStart.Opacity" Value="1" Duration="0.05" />
                                <Change Target="itemEnd.Opacity" Value="1" Duration="0.05" />
                        </WhilePressed>
                    </Button>
                </Each>
            </StackPanel>
        </ScrollViewer>
        <JavaScript File='parse-1.5.0.min.js' ux:Global='Parse' />
        <!-- <JavaScript File='client.js' ux:Global='GCal' /> -->
        <JavaScript File='testnode.js' />
    </DockPanel>
</App>

And the Modules.ux file:

<Panel xmlns:b="Fuse.BasicTheme" ux:Class="Modules">
    <JavaScript File='assets\modules\NodeSource\assert.js' ux:Global='assert' />
    <JavaScript File='assets\modules\NodeSource\buffer.js' ux:Global='buffer' />
    <JavaScript File='assets\modules\NodeSource\child_process.js' ux:Global='child_process' />
    <JavaScript File='assets\modules\NodeSource\cluster.js' ux:Global='cluster' />
    <JavaScript File='assets\modules\NodeSource\console.js' ux:Global='console' />
    <JavaScript File='assets\modules\NodeSource\constants.js' ux:Global='constants' />
    <JavaScript File='assets\modules\NodeSource\crypto.js' ux:Global='crypto' />
    <JavaScript File='assets\modules\NodeSource\dgram.js' ux:Global='dgram' />
    <JavaScript File='assets\modules\NodeSource\dns.js' ux:Global='dns' />
    <JavaScript File='assets\modules\NodeSource\domain.js' ux:Global='domain' />
    <JavaScript File='assets\modules\NodeSource\events.js' ux:Global='events' />
    <JavaScript File='assets\modules\NodeSource\freelist.js' ux:Global='freelist' />
    <JavaScript File='assets\modules\NodeSource\fs.js' ux:Global='fs' />
    <JavaScript File='assets\modules\NodeSource\http.js' ux:Global='http' />
    <JavaScript File='assets\modules\NodeSource\https.js' ux:Global='https' />
    <JavaScript File='assets\modules\NodeSource\module.js' ux:Global='module' />
    <JavaScript File='assets\modules\NodeSource\net.js' ux:Global='net' />
    <JavaScript File='assets\modules\NodeSource\os.js' ux:Global='os' />
    <JavaScript File='assets\modules\NodeSource\path.js' ux:Global='path' />
    <JavaScript File='assets\modules\NodeSource\punycode.js' ux:Global='punycode' />
    <JavaScript File='assets\modules\NodeSource\querystring.js' ux:Global='querystring' />
    <JavaScript File='assets\modules\NodeSource\readline.js' ux:Global='readline' />
    <JavaScript File='assets\modules\NodeSource\repl.js' ux:Global='repl' />
    <JavaScript File='assets\modules\NodeSource\smalloc.js' ux:Global='smalloc' />
    <JavaScript File='assets\modules\NodeSource\stream.js' ux:Global='stream' />
    <JavaScript File='assets\modules\NodeSource\string_decoder.js' ux:Global='string_decoder' />
    <JavaScript File='assets\modules\NodeSource\sys.js' ux:Global='sys' />
    <JavaScript File='assets\modules\NodeSource\timers.js' ux:Global='timers' />
    <JavaScript File='assets\modules\NodeSource\tls.js' ux:Global='tls' />
    <JavaScript File='assets\modules\NodeSource\tty.js' ux:Global='tty' />
    <JavaScript File='assets\modules\NodeSource\url.js' ux:Global='url' />
    <JavaScript File='assets\modules\NodeSource\util.js' ux:Global='util' />
    <JavaScript File='assets\modules\NodeSource\vm.js' ux:Global='vm' />
    <JavaScript File='assets\modules\NodeSource\zlib.js' ux:Global='zlib' />
    <JavaScript File='assets\modules\NodeSource_debugger.js' ux:Global='_debugger' />
    <JavaScript File='assets\modules\NodeSource_http_agent.js' ux:Global='_http_agent' />
    <JavaScript File='assets\modules\NodeSource_http_client.js' ux:Global='_http_client' />
    <JavaScript File='assets\modules\NodeSource_http_common.js' ux:Global='_http_common' />
    <JavaScript File='assets\modules\NodeSource_http_incoming.js' ux:Global='_http_incoming' />
    <JavaScript File='assets\modules\NodeSource_http_outgoing.js' ux:Global='_http_outgoing' />
    <JavaScript File='assets\modules\NodeSource_http_server.js' ux:Global='_http_server' />
    <JavaScript File='assets\modules\NodeSource_linklist.js' ux:Global='_linklist' />
    <JavaScript File='assets\modules\NodeSource_stream_duplex.js' ux:Global='_stream_duplex' />
    <JavaScript File='assets\modules\NodeSource_stream_passthrough.js' ux:Global='_stream_passthrough' />
    <JavaScript File='assets\modules\NodeSource_stream_readable.js' ux:Global='_stream_readable' />
    <JavaScript File='assets\modules\NodeSource_stream_transform.js' ux:Global='_stream_transform' />
    <JavaScript File='assets\modules\NodeSource_stream_writable.js' ux:Global='_stream_writable' />
    <JavaScript File='assets\modules\NodeSource_tls_common.js' ux:Global='_tls_common' />
    <JavaScript File='assets\modules\NodeSource_tls_legacy.js' ux:Global='_tls_legacy' />
    <JavaScript File='assets\modules\NodeSource_tls_wrap.js' ux:Global='_tls_wrap' /></Panel>

``` ``

Try updating to the latest version (released a few minutes ago). There are some bugs related to JS parsing fixed in that.

Sadly that didn’t fix it. The error changed though, it’s now at (42,35), not (40,35) whatever that means.

Error Summary
-------------

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\Modules.ux(42,35): E1173: Expected identifier

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\Modules.ux(42,35): E1178: Expected ',' or ';'

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\MainView.ux(36): E8001: Data type not found: Modules.ux

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\MainView.ux(36): E8001: Could not resolve type 'Modules.ux'

# Build complete.

I don’t understand why it’s expecting a ‘,’ or ‘;’ because as far as I can tell, they’re not used as valid syntax in UX files. If it was a .js file I’d be looking for the missing ‘;’ but yeah I don’t know what the problem is right now.

For the last two errors, you should simply remove your <Modules.ux /> tag from the file. You don’t need to reference that, and if you were to reference it, you don’t need to use the file extension.

If you still have errors after that, please upload your project as a zip, and we will debug :slight_smile:

Getting rid of that tag did indeed fix the last couple of errors, thanks! :slight_smile: Unfortunately the first two are still around - is there any way I can privately send you guys my project .zip - it contains my Parse keys so I’d rather not publish it publically.

Just remove your parse keys before zipping :slight_smile: We are working on a private upload feature for support, but unfortunately it is not ready yet.

Here’s the download link: https://www.dropbox.com/s/ggsdk64bbjs3ffq/TimetableUpdater.zip?dl=0

Thanks again! :slight_smile:

Here’s the download link: https://www.dropbox.com/s/ggsdk64bbjs3ffq/TimetableUpdater.zip?dl=0

Thanks again :slight_smile:

Thanks for uploading. Someone will debug this shortly today or tomorrow morning.

Hi!

Thanks for reporting this. Turns out to be a bug in the UX processor. assert is a keyword in Uno and hence you cannot use that as a name for a module.

We will get this fixed for the next release. In the meantime rename that module to something else and it should at least compile.

Hi Anders,

Thanks for all your help in the matter. Unfortunately it seems it was all for nought; it appears that one of Node’s main global objects - process - is actually called from its C++ code or something so it’s sadly not pure JS after all. I only discovered this after finally being able to load the Node modules I needed, that’s when they started throwing errors. Basically there’s practically no way I can see to get any Node modules running. The only other API for Google services is the JavaScript one which assumes that it is being executed from within a browser and so uses things like ‘window’ which throw errors in Fuse because it’s not a browser.

I don’t suppose there’s any other way I’m not thinking of to communicate with Google’s web services in Fuse?

Hi, sorry to hear that.

However, we are working full speed internally on a big release that will make all sort of native UI components (including WebView) standard UX components. This means that you can run any HTML/JS content inside a Fuse app if you want to :slight_smile: Check back in a few weeks :slight_smile:

Sounds awesome, can’t wait! That should indeed solve my problem. Thanks again for all the assistance :slight_smile: