qtmoduleqml

Import of module in Javascript does not respect qmldir->prefer


In my QML application, I want to implement hot reloading. The main thing one has to do for that is to load all resources from the file system, not the Qt resource system.
One has to do two things:

This allows to change a source file, restart the application without rebuilding it, and the changes are reflected in the running application.

Now I have found a special case, where this does not work. QML modules can contain javascript resources and expose their functions. Inside these javascript files, one can import other QML modules.

In my minimal application that reproduces this problem, I have defined two modules A and B next to my Main.qml file. Both of these modules simply contain one javascript resource:

A.js:

.pragma library

.import B as B

function test() {
    console.log("Calling B from A")
    B.B.test()
}

B.js:

.pragma library

function test() {
    console.log("Hello from B")
}

Inside module A, I define a simple function test, that prints a message on the console and also calls the function test of module B, which also just prints to the console.

My Main.qml file looks like this:

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

import A
import B

ApplicationWindow {
    id: root

    width: 1920
    height: 1080
    visible: true

    Component.onCompleted: {
        console.log("Calling A from Main")
        A.test()
        console.log("Calling B from Main")
        B.test()
    }
}

When starting this application, the console output looks like this:

qml: Calling A from Main
qml: Calling B from A
qml: Hello from B
qml: Calling B from Main
qml: Hello from B

Now I modify the message being printed inside B.test() and restart the application without rebuilding it:

qml: Calling A from Main
qml: Calling B from A
qml: Hello from B
qml: Calling B from Main
qml: Hello from B MODIFIED

Notice, how the changes are only reflected, when module B is loaded from within the main QML module (or any other QML file, even from within other modules, as I have tested in my real application). But as soon as the module gets imported inside a javascript resource, the import seems to no longer respect the prefer ./path/to/module line of the qmldir file.

Does somebody know how one could work around this? I am using CMake to build my Qt application.

Additional resources:


Solution

  • I created a bugreport on the QT website.

    Some kind people there attended my problem and confirmed, that at least the difference in the behaviour of importing from a .js file vs. a .qml file is not intended.