Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QJsEngine cannot use import syntax



  • I follow the documentation, using import, but I am getting an error.

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QString fileName = ":/test.jsm";
        QFile scriptFile(fileName);
        if (!scriptFile.open(QIODevice::ReadOnly)){
            // handle error
            qDebug()<<"open file fail!";
        }
        QTextStream stream(&scriptFile);
        QString contents = stream.readAll();
        scriptFile.close();
        QJSEngine myEngine;
        myEngine.installExtensions(QJSEngine::AllExtensions);
        qDebug()<<contents;
        QJSValue result = myEngine.evaluate(contents, fileName);
        if (result.isError())
            qDebug()
                    << "Uncaught exception at line:"
                    << result.property("lineNumber").toInt()
                    << endl << result.toString();
        qDebug()<<"end";
        return a.exec();
    }
    
    

    test.jsm

    import { sum } from "./math.mjs";
    export function addTwice(left, right)
    {
        return sum(left, right) * 2;
    }
    print(sum(1,2));
    

    error

    Uncaught exception at line: 1
    "SyntaxError: Unexpected token `import'"
    


  • Hi UremSetp

    When you write a module, you should use myEngine.importModule. So it can parse "import" and "export" keywords to use.

    QCoreApplication a(argc, argv);
    
        QString fileName = ":/test.jsm";
        QFile scriptFile(fileName);
        if (!scriptFile.open(QIODevice::ReadOnly)){
            // handle error
            qDebug()<<"open file fail!";
            return 0;
        }
        QTextStream stream(&scriptFile);
        QString contents = stream.readAll();
        scriptFile.close();
        QJSEngine myEngine;
        myEngine.installExtensions(QJSEngine::AllExtensions);
        qDebug()<<contents;
        QJSValue module = myEngine.importModule(":/test.jsm");
        QJSValue sumFunction = module.property("addTwice");
        QJSValueList list;
        list.append(3);
        list.append(4);
        QJSValue result = sumFunction.call(list);
        qDebug()<<result.toInt()<<endl;
    
    


  • @CKurdu

    Thank you! I have been able to implement the features I want, but it is not too beautiful.Is there a better way?
    main.cpp

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QString fileName = "./test.jst";
        QFile scriptFile(fileName);
        if (!scriptFile.open(QIODevice::ReadOnly)){
            qDebug()<<"open file fail!";
            return 0;
        }
        QTextStream stream(&scriptFile);
        QString contents = stream.readAll();
        scriptFile.close();
        QJSEngine myEngine;
        myEngine.installExtensions(QJSEngine::AllExtensions);
        QJSValue module = myEngine.importModule("./test.jsm");//The first js file needs to be imported like this and cannot be imported in the script.
        myEngine.globalObject().setProperty(QLatin1String("_import"),module);
        QJSValue result = myEngine.evaluate(contents, fileName);
        if (result.isError())
            qDebug()
                    << "Uncaught exception at line:"
                    << result.property("lineNumber").toInt()
                    << endl << result.toString();
        qDebug()<<"end";
        return a.exec();
    }
    

    first js :test.jst

    print(_import.addTwice(1,2));
    

    first module:test.jsm

    import { sum } from "./math.mjs";
    export function addTwice(left, right)
    {
        return sum(left, right) * 2;
    }
    

    other module:

    export function sum(left, right)
    {
        return left + right
    }
    


  • @UremSept said in QJsEngine cannot use import syntax:

    Thank you! I have been able to implement the features I want, but it is not too beautiful.Is there a better way?

    You are welcome. What is your final aim? I think you want to make a library consists of modules and a final main script that uses all of the libraries. But QJsEngine is made for QML apps and for this reason it maybe not a good solution as node.js (You can use es6-7 well-supported environment).

    To beautify the work, you can create a method dynamically list files in a directory and install all modules that your start script requires.



  • @CKurdu I just want to customize some APIs in C++ and then use them easily in scripts. Thank you for your suggestion, these are enough to use.



  • @UremSept said in QJsEngine cannot use import syntax:

    I just want to customize some APIs in C++ and then use them easily in scripts. Thank you for your suggestion, these are enough to use.

    Then If you want to use this script files without "import" restriction you can do it like below.
    First Create a main.qml in working directory file where it isn't in a resource file.

    import "./test.mjs" as TestImport //You can import start script module here
    import QtQuick 2.0
    QtObject{
        id:root
        Component.onCompleted: {
            var result = TestImport.addTwice(2,4); 
            console.log(result);
        }
    }
    

    Your test.mjs file in working directory.

    import { sum } from "./math.mjs";
    export function addTwice(left, right)
    {
        return sum(left, right) * 2;
    } 
    

    Your math.mjs file in wokring directory

    export function sum(left, right)
    {
        return left + right
    } 
    
    

    And your main.cpp file

    #include <QCoreApplication>
    #include <QQmlApplicationEngine>
    #include <QFile>
    #include <QTextStream>
    #include <QJSEngine>
    #include <QDebug>
    #include <QQmlEngine>
    #include <QObject>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QQmlApplicationEngine myEngine("main.qml");
        return a.exec();
    }
    

    This is actually console application and when you use QQmlApplicationEngine you can faciliate many qt imports also.



  • @CKurdu Thank you very much, I don’t know enough, this solves my problem.


Log in to reply