Introducing qlbuilder

qlbuilder

In general qlbuilder is a tool that communicates with Qlik apps (using the Engine API) and set the script. The script is located on the local machine and can be "stitched" from multiple files.

Why?

Everyone have their own preferred IDE/text editor and we can write own Qlik Sense load scripts there and use include/must_include inside the app to "bring" the script inside the app.

But it will be nice if we can write the scrips locally and upload them directly to the app as it is.

The basic idea is that we will write each Qlik Sense script tab in a separate .qvs file and qlbuilder will combine them (when needed) in a single file and set it's content to the dedicated Qlik Sense app (on dedicated QS environment).

qlbuilder can perform few more actions, apart from combining and setting the script: check for syntax errors, reload app, "watching" for script changes and check for syntax errors etc.

With this approach I can write my script in Visual Studio Code (in combination with Qlik for Visual Studio Code
extension) and use all VS Code shortcuts, themes etc.

Installation

qlbuilder is a Node JS module and can be installed as a global package

npm install -g qlbuilder

Folder structure

The folder structure used from qlbuilder looks like this:

project-name
│   config.yml
│───dist
│      LoadScript.qvs
└───src
    │   0--Main.qvs
    │   1--Config.qvs
    │   2--Mapping.qvs
    │   ...

src is the main folder. In this folder are located all qvs files. Each file will result in a separate script tab, when uploaded. The .qvs files are combined in alphabetical order (for now. please have a look at the Road map section at the end of this post)

Config files

There are two configuration files that are used from qlbuilder:

config.yml

This file is mandatory and it's created during the project/folder creation. This file is located in the root folder and defines the Qlik Sense environments and apps ID that are relevant to this script.

The file is in yaml format and looks like this:

- name: dev
  host: 192.168.0.100 # IP/FQDN of QS engine (central node) 
  secure: false # default value is true 
  appId: 12345678-1234-1234-1234-12345678901
  authentication:
    type: winform

The above config defines:

  • QS environment called dev
  • the environment's host is 192.168.0.100
  • the environment is access through http
  • the appId (that this script belongs to) is 12345678-1234-1234-1234-12345678901
  • the authentication for this environment is Windows/Forms - winform

(for more information on authentication types and other possible settings please have a look at qlbuilder GitHub repo)

The config contains the "public" environment information and can be commit to git repo.

.qlbuilder.yml

The non-public info (authentication information) is held in another configuration file .qlbuilder.yml (there is option to use environment variables as well)

This file is not created through the install/create process and should be located in current user home folder. For example: C:\Users\My-User-Name\.qlbuilder.yml. Using the above example, with winform authentication and environment named dev, the config will looks like:

dev:
  QLIK_USER: DOMAIN\username
  QLIK_PASSWORD: my-secret-password

This information will be used by qlbuilder during the authentication process to generate the sessionId

Commands

qlbuilder is executed from command line and accept few parameters:

  • create [project name] - create the initial project folder structure, sample script and config file. If folder with the same name already exists, and the developer agree to re-create, then this command will re-create only the qlbuilder specific files and folders and will not modify any other folders or files

  • build - combines all qvs files from src folder into a single load script. The result script is created in dist folder (ideally this file should not be edited)

  • checkscript [env name] - check the script for syntax errors. The check is made against temp (session) Qlik app

  • getscript [env name] - gets the script from the app id (specified in config.yml) and splits it into multiple qvs files (in src folder). This operation deletes all files in src folder as first step!

  • reload [env name] - reloads the QS app and output the reload progress. (the reload is performed on the QS Engine itself)

  • setscript [env name] -

    • builds the script from the files in src folder
    • checks the script for syntax errors (if there are errors the process is stopped)
    • opens the QS app and replaces the script with the build one
    • saves the app
  • watch [env name] - now this is a funny one :) ... when started in watch mode qlbuilder will check for syntax error on each file save (any qvs file in src folder). During watch mode few sub-commands that can be used:

    • s or set - sets the script to the app and saves it
    • r or rl - reloads the app (if successful the app is saved)
    • c or cls - clears the console
    • x - exit qlbuilder
    • ? - outputs these commands again

Version Control

Having the script locally allows us to put the project folder under version control and keep history of the script changes (anyone thinking about git hooks as well? 😉)

Road map

More or less qlbuilder includes all the features I had in mind initially. But there are few things that can be added:

  • include / must_include - (optional config) detect if these statements are present in the script. If found - get the content of the included scripts and replace the statement with the actual script. This can "save" apps from failing because of external script being edited after the app is published
  • different way to organize script files? - at the moment the script files are combined based on alphabetical order. It might be a bit annoying when adding new file in the middle of the script - all files that follow need to be renamed

For more information please have a read at the readme at the qlbuilder GitHub repo

Fell free to open issues there if you experiencing any problems or have requests/suggestions

Any suggestions are very welcome!

Hope you liked it!
Stefan