Solved 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;
-
Thank you! I have been able to implement the features I want, but it is not too beautiful.Is there a better way?
main.cppint 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.