FCF 2.0 development in progress...
> > >
[News] [Packages API] [Downloads] [Donate to the project] [Contacts]

Modules

The FCF framework uses its own model for declaring and loading JavaScript modules, which allows you to organize dependencies and dynamically load them, both on the server side and on the client side. Any JS file can act as a JavaScript module, but if the script must have dependencies and be able to be loaded, both on the server side and on the browser side, then the module must be declared with the function fcf.module() . To declare an FCF module, it is enough to create a file and declare the module code in it.

The fcf.module({name, dependencies, lazy, module}) function takes an object with four fields:

  • string name - Module name. Must contain the full path to the module in FCF format.

  • [string] dependencies = [] - An array of module dependencies that will be loaded and passed to the module function as arguments.

  • [string] lazy = [] - An array of module dependencies that will be loaded after the module function is executed. Dependency data can be used in case of cyclic dependencies and data is accessed via global variables.

  • function module - A function that should return module data. Arguments from the array of module dependencies act as parameters.

File declaration example:

modules/dependence.js file:

fcf.module({ name: "modules/dependence.js", dependencies: [], lazy: [], module: () => { class Dependence { dosome(){ console.log("Hello world"); } }; return Dependence; } });

modules/main.js file:

fcf.module({ name: "modules/main.js", dependencies: ["modules/dependence.js"], lazy: [], module: (Dependence) => { let dependence = new Dependence(); return { dosome: () => { dependence.dosome(); } }; } });

A Javascript file can contain multiple modules, making it easy to load multiple files saved in one file.

Modules can be loaded either by standard means, using require() on the NODEJS server side, and on the browser side by including a js file in the stript tag, or using the fcf.require() function, which takes paths to modules as parameters and returns fcf.Actions, which will store an array with the data of the requested modules.

The last parameter of the fcf.require() function can be an object with additional parameters, among which is the async option. If the option value is true (the default value), then the browser-side download is performed asynchronously, if the option is false, then synchronous download is performed. On the NODEJS server side, loading is always done synchronously.

Example loading modules/main.js module

let [mainModule] = fcf.require("modules/main.js", {async: false}).result();

In the above example, the module is loaded synchronously into the mainModule variable, since the async flag is false. To get the result, we call the fcf.Actions.result method, so as not to use the await operator

Loading simple JavaScript files.

The framework's modularity mechanism allows you to load simple JS files, if the script file on the server side returns the result of execution through the module.exports variable, then the file can be included without additional steps. If a JavaScript file writes the result of its execution to a global variable, then in order to use such a file, it is necessary to tell the framework from which variable to take the result of the file execution.

To do this, you need to set the result parameter for the JavaScript file in the framework configuration.

helloWorld.js file

let globalEnvironment = fcf.isServer() ? global : window; if (!globalEnvironment.variables) { globalEnvironment.variables = {}; } globalEnvironment.variables.helloWorld = () => { console.log("Hello world"); };

main.js file

fcf.getConfiguration().append({ sources: { "": { files: { "helloWorld.js": { result: "variables.helloWorld" }, } } } }); async function doCallHelloWorld() { let [helloWorld] = await fcf.require("helloWorld.js"); helloWorld(); }

In order to set the parameters for downloading a file, you first need to declare the source configuration option, which contains options for describing the source files of the package. The key is the name of the package, and the value is the description parameters. The application itself, i.e. the root path of the application, is specified as a package with the name of the empty string ""

The sources["PACKAGE_NAME"].files option is an object that contains information about the rules for connecting files, the key is the names of the files, and the option value describes the rules for downloading a particular file. The following options are available in this object:

  • string filePath - A tokenized string containing the path to the file on the browser side. Using tokenization, it is easy to organize the switching of the downloaded file from the debug version to the release version using the user context settings. The following variables are available in the tokenizer:

    • string path - Full path to the file

    • string directory - File directory

    • string shortName - Short filename without extension

    • string name - File name

    • string extension - File extension

  • string result - A string containing the path to a global variable containing the result of the JS module. This option is used to load modules declared without using the fcf.module function.

  • string loadState - If the parameter is defined, then the first time the JS module is loaded in the tokenized string, the condition is first determined, and if the result of the calculated string returns true, then the module is considered already loaded. This method allows you to load JS modules not declared by the fcf.module function using the script tag and the fcf.require method together (that is, to avoid double loading the module).

    Example:

    fcf.getConfiguration().append({ sources: { "jquery": { webMain: "jquery.js", webFiles: { "jquery.js": { result: "jQuery", loadState: "@{{!!window.jQuery}}@", filePath: "@{{directory}}@/@{{shortName}}@@{{!fcf.getContext().debug && name.indexOf(\".min.\") == -1 ? \".min\" : \"\"}}@.@{{extension}}@", } } }, } });

In addition to the files option, there are also the serverFiles and webFiles options, which are similar to the files option, but serverFiles define the configuration of files on the server, and webFiles define the configuration on the browser side.