Oracle JET — OJET for Hybrid Application Development

Aditya Padhi
5 min readMay 5, 2022

In this tutorial, we will be learning the basics of OJET and we will also set up our development environment for Hybrid application development.

App “Development Stage” Lifecycle:

Note: Serve is only used for viewing your application in a local development environment with a local dev server (usually a NodeJS-based server) hence it is never seen in the production.

App “Production” Lifecycle:

After building an application for the production, the built files (HTML, CSS, and JS files — already minified while release build) are placed and served using production-grade servers like Apache / Nginx / Lightspeed /Oracle HTTP Server (Apache Based) / Oracle Weblogic Server.

1. How to create an OJET Hybrid Application?

ojet create MyHR --hybrid --appname="MyHR" --template=navbar --platforms=android,ios

2. Structure and function of files and folders in created OJET Application:

3. What is the entry point of the application in the src development directory?

Entry Point is the index.html file.

Important parts of the index.html file (highlighted):

I. Link tags containing favicon and app.css

II. Injector:theme which is used by OJET CLI (during serve/build)to inject the Redwood/Alta theme according to the defaultTheme key in oraclejetconfig.json

<!DOCTYPE html>
<html lang="en-us">
<head>
<title>Oracle JET Starter Template - Hybrid Nav Bar</title>
<meta charset="UTF-8">
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
<link rel="icon" href="css/images/favicon.ico" type="image/x-icon" />
<!-- injector:theme -->
<!-- endinjector -->
<!-- This is where you would add any app specific styling -->
<link rel="stylesheet" href="css/app.css" type="text/css"/>
</head>
<body>
<div id="globalBody">
... omitted content
</div>
<script type="text/javascript" src="js/libs/require/require.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>

III. The script tag containing the RequireJS library which is a file/module loader.

IV. Another script tag — main.js which is the main entry point for Javascript.

4. What is RequireJS and why is OJET using it in its application?

RequireJS is a JavaScript file and module loader that simplifies managing library references and is designed to improve the speed and quality of your code.

RequireJS implements the Asynchronous Module Definition (AMD) API which provides a mechanism for “asynchronously” loading a module and its dependencies.

Oracle JET’s modular organization enables application developers to load a subset of needed features without having to execute require() calls for each referenced object. Each Oracle JET module represents one functional area of the toolkit, and it typically defines more than one JavaScript object.

5. Can we not load all dependencies using script tags directly in index.html?

We can load all dependencies directly in the index.html but the page load time will be a lot higher moreover loading dependencies in a certain format is a tedious process hence we depend on module loaders like RequireJS which make asynchronous calls to fetch and load scripts into the browser.

6. What does this main.js contain?

Important Parts of this file (highlighted):

I. RequireJS configuration has been added with baseUrl pointing to the js folder. It means RequireJS will start searching files mentioned in paths the key in the js folder.

II. Anything betweeninjector:mainReleasePaths and endinjector will be deleted and new paths will be added by OJET CLI during ojet build/serve from the src/js/path_mapping.json file.

It means if we have to add a library to RequireJS dependencies we will have to change src/js/path_mapping.json file.

"use strict";
(function () {
window["oj_whenReady"] = true;
requirejs.config({
baseUrl: "js",
paths:
// injector:mainReleasePaths
{
ojs: "libs/oj/v12.0.1/debug",
... other dependencies omitted
},
// endinjector
});
})();

require([
"ojs/ojbootstrap",
"knockout",
"appController",
"ojs/ojlogger",
"ojs/ojknockout",
"ojs/ojmodule",
"ojs/ojnavigationlist",
], function (Bootstrap, ko, app, Logger) {
Bootstrap.whenDocumentReady().then(function () {
function init() {
ko.applyBindings(app, document.getElementById("globalBody"));
}
if (document.body.classList.contains("oj-hybrid")) {
document.addEventListener("deviceready", init);
} else {
init();
}

});
});

III. If the build is for a hybrid environment OJET adds a oj-hybrid class to the body of the HTML and we wait for Cordova to fire the deviceready event for the initialization of our application. In either case, init is the entry point of our application JS.

IV. appController.jsa file in the same directory as main.js is loaded into the application using require and a new instance of the AppController viewModel which is returned by the appController is bound to the application HTML Element with IDglobalBody in our case.

7. What does this appController.js contain?

It contains the root ViewModel of the application which initializes the CoreRouter and ModuleRouterAdapterwhich helps the application in finding the maintaining the router state and (view, viewModel) mapping.

8. How to add web browser capability to hybrid application?

ojet add web

OJET Documentation

9. How to add TailwindCSS to OJET?

npm install -D tailwindcssnpx tailwindcss init

tailwind.config.js — In the root directory.

module.exports = {   
content: ["./src/**/*.{html,js}"],
theme: { extend: {}, },
plugins: [],
}

Create a main.css in the src folder:

@tailwind base;
@tailwind component;
@tailwind utilities;

In scripts/hooks — Change these hooks (before_build.js, before_serve.js)

module.exports = function (configObj) {
return new Promise((resolve, reject) => {

require("child_process").exec("npx tailwindcss -c ./tailwind.config.js -i ./src/main.css -o ./src/css/app.css", function (error, stdout, stderr) {
if (error !== null) {
console.log("exec error: " + error);
reject("exec error: " + error);
} else {
console.log("****Tailwind Build Complete***");
resolve();
}
});
resolve(configObj);
});

10. Pre-requisites for building an application for android platform?

Perform the following tasks: Create folders if they don't exist.

Extract here: C:\Android\SDK\cmdline-tools\tools\<zip-contents-here>

  • Set JAVA_HOME to the root of the Java directory.
  • Add bin folder in JAVA_HOME to PATH.
  • C:\Gradle => bin folder to PATH
  • Set path of cmdlinetools/tools/bin => PATH
sdkmanager --list
  • sdkmanager “platform-tools”
  • sdkmanager “<buildtools+version>”
  • sdkmanager “<platforms+android32>”
  • Add C:\cmdlinetools\platform-tools=> PATH

11. How do Hooks work in Ojet?

To be updated. Original Documentation

12. How to add “Prettier” to project for code formatting?

To be updated.

13. How to add “ESLINT” to audit fix problems during development?

To be updated.

14. How to add “Redux” for state management?

To be updated.

15. How to build application for Web, Android, IOS?

To be updated.

--

--