Multiple JS file support

I tried to divide my single JS file into multiple files and include all of them in the root App. However it seems that the JS files can’t recognize variables declared in the other files. May I know if this is a current limitation? Having a large trunk of JS is not that easy to maintain.

Thanks.

Hi!

Each JS file is a module, that you can require from other files.

For example:

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

And do

var SomeModule = require("SomeModule");

SomeModule will then be the module.exports object from SomeModule.js

Thanks Anders. I tried to do something as follows but no luck yet. Probably I am still unclear about the settings. Please guide me through.

MainView.ux

<App>
    <JavaScript File="data.js" ux:Global="Data" />
    <JavaScript File="main.js" />
</App>

data.js

module.exports = data_object;

var data_object = 
{
    "blahblah": [
        {},{},{}
    ]
};

main.js

var Observable = require('FuseJS/Observable');

var t_data = Observable(require('Data')); // returning undefined

I think main problem is that in data.js, you set module.exports to data_object, which isn’t defined until lines later; that’s probably what’s giving you undefined.

I believe you also need new when creating the Observable in main.js. I built up basically the same example locally and it works:

MainView.ux:

<App Theme="Basic">
  <JavaScript File="data.js" ux:Global="Data" />
  <JavaScript File="main.js" />
</App>

data.js:

var data_object = {
    "blahblah": [
        {}, {}, {}
    ]
};

module.exports = data_object;

main.js:

var Observable = require("FuseJS/Observable");
var Data = require("Data");

var t_data = new Observable(Data);

console.log(JSON.stringify(t_data.value));

Oh my… How can I make this careless mistake… I really should get some sleep.

Thanks, Jake!

Haha, happens :slight_smile: no problem!

Side note: just double-checked, you don’t in fact need to use new with Observable’s as I mentioned previously :slight_smile:

Hi Fusetools team.

Reproducing this exact example shows me the folowing error:

LOG: Error: JavaScript error in main.js line 2: Name: System.Exception
    Error message: Exception of type 'System.Exception' was thrown.
    File name: main.js
    Line number: 2
    Source line: var Data = require("Data");
    JS stack trace: [Uno code]
      at Fuse.Scripting.Context.FindRootTable (Uno.UX.NameTable names) <0x17ebce10 + 0x00057> in <filename unknown>:0 
      at Fuse.Scripting.Context.GetClassInstance (Uno.UX.NameTable scope) <0x17ebcdc0 + 0x00013> in <filename unknown>:0 
      at Fuse.Reactive.RootableScriptModule.EnsureClassInstanceRooted () <0x17ebcd30 + 0x00033> in <filename unknown>:0 
      at Fuse.Reactive.RootableScriptModule.Evaluate (Fuse.Scripting.Context c, Fuse.Scripting.ModuleResult result) <0x17ebcc20 + 0x00013> in <filename unknown>:0 
      at Fuse.Scripting.Module.Evaluate (Fuse.Scripting.Context c, System.String id) <0x17eb3030 + 0x0019d> in <filename unknown>:0 
      at Fuse.Scripting.ScriptModule+RequireContext.Require (System.String id) <0x17ec25c0 + 0x000f7> in <filename unknown>:0 
      at Fuse.Scripting.ScriptModule+RequireContext.Require (System.Object[] args) <0x17ec2410 + 0x0007b> in <filename unknown>:0 
      at Fuse.Scripting.V8.Marshaller+CallbackWrapper.Call (Fuse.Scripting.V8.Simple.UniqueValueVector args) <0x17ec0180 + 0x00059> in <filename unknown>:0 
    [JavaScript code]
    Error: Exception of type 'System.Exception' was thrown.
        at (Error Handler):1:49
        at null._tempMethod (main.js:2:12)
     in Fuse.Reactive.JavaScript</usr/local/share/uno/Packages/Fuse.Reactive/0.39.2/$.uno:1444>

data.js:

var data_object = {
    "blahblah": [
        {}, {}, {}
    ]
};

module.exports = data_object;

App.ux:

<App ux:Class="ExampleApp" ClearColor="#fff">
  <JavaScript File="data.js" ux:Global="Data" />
  <JavaScript File="main.js"/>
</App>

main.js

var Observable = require('FuseJS/Observable');
var Data = require("Data");
var t_data = new Observable(Data);
console.log(JSON.stringify(t_data.value));

test.unoproj:

{
  "RootNamespace":"",
  "Packages": [
  	"Fuse",
  	"FuseJS"
  ],
  "Includes": [
    "*"
  ]
}

Any clue?

Thanks!

If your file is named data.js with an undercase d, then i believe your require should reflect that:

var data = require("data");

I haven’t double checked this yet, so please let me know if this solves your problem :slight_smile:

It seems the source file name and the global module javascript must match exactly (without extensions).

I couldn’t figure out why module names and source file names are internally related. But it works now.

Thanks Kristian!

Just to warn to newcomers.

If the javascript module is in a subdirectory (Ex. “App/data.js”), you must place the path in the declaration, for example:

var Data = require('App/data');

You can also do it with the extension var Data = require("App/data.js"). It’s just optional.