Importing JavaScript Resources in QML

Description of how to import and use JavaScript resources in QML documents

JavaScript resources may be imported by QML documents and other JavaScript resources. JavaScript resources may be imported via either relative or absolute URLs. In the case of a relative URL, the location is resolved relative to the location of the QML document or JavaScript Resource that contains the import. If the script file is not accessible, an error will occur. If the JavaScript needs to be fetched from a network resource, the component’s status is set to “Loading” until the script has been downloaded.

JavaScript resources may also import QML modules and other JavaScript resources. The syntax of an import statement within a JavaScript resource differs slightly from an import statement within a QML document, which is documented thoroughly below.

Importing a JavaScript Resource from a QML Document

A QML document may import a JavaScript resource with the following syntax:

import "ResourceURL" as Qualifier

For example:

import "jsfile.js" as Logic

Imported JavaScript resources are always qualified using the “as” keyword. The qualifier for JavaScript resources must start with an uppercase letter, and must be unique, so there is always a one-to-one mapping between qualifiers and JavaScript files. (This also means qualifiers cannot be named the same as built-in JavaScript objects such as Date and Math).

The functions defined in an imported JavaScript file are available to objects defined in the importing QML document, via the "Qualifier.functionName(params)" syntax. Functions in JavaScript resources may take parameters whose types can be any QML value types or object types, as well as normal JavaScript types. The normal data type conversion rules will apply to parameters and return values when calling such functions from QML.

Imports Within JavaScript Resources

In QtQuick 2.0, support has been added to allow JavaScript resources to import other JavaScript resources and also QML type namespaces using a variation of the standard QML import syntax (where all of the previously described rules and qualifications apply).

Due to the ability of a JavaScript resource to import another script or QML module in this fashion in QtQuick 2.0, some extra semantics are defined:

  • a script with imports will not inherit imports from the QML document which imported it (so accessing Component.errorString will fail, for example)

  • a script without imports will inherit imports from the QML document which imported it (so accessing Component.errorString will succeed, for example)

  • a shared script (i.e., defined as .pragma library) does not inherit imports from any QML document even if it imports no other scripts or modules

The first semantic is conceptually correct, given that a particular script might be imported by any number of QML files. The second semantic is retained for the purposes of backwards-compatibility. The third semantic remains unchanged from the current semantics for shared scripts, but is clarified here in respect to the newly possible case (where the script imports other scripts or modules).

Importing a JavaScript Resource from Another JavaScript Resource

A JavaScript resource may import another in the following fashion:

import * as MathFunctions from "factorial.mjs";

Or:

.import "filename.js" as Qualifier

The former is standard ECMAScript syntax for importing ECMAScript modules, and only works from within ECMAScript modules as denoted by the mjs file extension. The latter is an extension to JavaScript provided by the QML engine and will work also with non-modules. As an extension superseded by the ECMAScript standard, its usage is discouraged.

When a JavaScript file is imported this way, it is imported with a qualifier. The functions in that file are then accessible from the importing script via the qualifier (that is, as Qualifier.functionName(params)).

Sometimes it is desirable to have the functions made available in the importing context without needing to qualify them. In this case ECMAScript modules and the JavaScript import statement should be used without the as qualifier.

For example, the QML code below left calls showCalculations() in script.mjs, which in turn can call factorial() in factorial.mjs, as it has included factorial.mjs using import.

import QtQuick
import "script.mjs" as MyScript

Item {
    width: 100; height: 100

    MouseArea {
        anchors.fill: parent
        onClicked: {
            MyScript.showCalculations(10)
            console.log("Call factorial() from QML:",
                MyScript.factorial(10))
        }
    }
}
// script.mjs
import { factorial } from "factorial.mjs"
export { factorial }

export function showCalculations(value) {
    console.log(
        "Call factorial() from script.js:",
        factorial(value));
}
// factorial.mjs
export function factorial(a) {
    a = parseInt(a);
    if (a <= 0)
        return 1;
    else
        return a * factorial(a - 1);
}

The include() function includes one JavaScript file from another without using ECMAScript modules and without qualifying the import. It makes all functions and variables from the other file available in the current file’s namespace, but ignores all pragmas and imports defined in that file. This is not a good idea as a function call should never modify the caller’s context.

include() is deprecated and should be avoided. It will be removed in a future version of Qt.

Importing a QML Module from a JavaScript Resource

A JavaScript resource may import a QML module in the following fashion:

.import TypeNamespace MajorVersion.MinorVersion as Qualifier

Below you can see an example that also shows how to use the QML types from a module imported in javascript:

.import Qt.test 1.0 as JsQtTest

var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3

In particular, this may be useful in order to access functionality provided via a singleton type; see QML_SINGLETON for more information.

Your JavaScript resource by default can access all imports of the component that imports the resource. It does not have access to the componpents’s imports if it is declared as a stateless library (using .pragma library) or contains an explicit .import statment.

Note

The .import syntax doesn’t work for scripts used in WorkerScript