2 Understand the Web App Workflow
Developing virtual DOM apps with Oracle JET is designed to be simple and efficient using the development environment of your choice and a starter template to ease the development process.
Oracle JET supports creating web apps from a command-line interface:
-
Before you can create your first Oracle JET web app using the CLI, you must install the prerequisite packages if you haven’t already done so. For details, see Install Oracle JET Tooling.
-
Then, use the Oracle JET command-line interface package (
ojet-cli
) to scaffold a web app using a basic starter template that creates a pre-configured app that you can modify as needed. -
After you have scaffolded the app, use the
ojet-cli
to build the app, serve it in a local web browser, and create a package ready for deployment.
You must not use more than one version of Oracle JET to add components to the same HTML document of your web app. Oracle JET does not support running multiple versions of Oracle JET components in the same web page.
Scaffold a Web App
Scaffolding is the process you use in the Oracle JET command-line interface (CLI) to create an app that is pre-configured with a content area, a header and a footer layout. After scaffolding, you can modify the app as needed.
The following image shows an app generated by the starter template. It includes responsive styling that adjusts the display when the screen size changes.

Before you can create your first Oracle JET web app using the CLI, you must also install the prerequisite packages if you haven’t already done so. For details, see Install Oracle JET Tooling.
About the Virtual DOM App Layout
Oracle JET Tooling creates an app for you with the necessary source files and directory structure.
The new application will have a directory structure similar to the one shown in the following image.

The application folders contain the application and configuration files that you will modify as needed for your own application.
Directory or File | Description |
---|---|
|
Contains the Node.js modules used by the tooling. |
|
Contains template hook scripts that you can modify to define new build and serve steps for your application. See Customize the Web App Tooling Workflow |
|
Site root for your application. Contains the application
files that you can modify as needed for your own application and
should be committed to source control. The starter template
includes an |
|
Defines rules for application folders to ignore when
using a GIT repository to check in application source. Users who do
not use a GIT repository can use |
|
Contains the default source and staging file paths that you can modify if you need to change your application's file structure. |
|
Defines npm dependencies and project metadata. |
Whether you are developing a virtual DOM app or a VComponent-based web
component, you'll write your code in the files under the src
directory.
The Oracle JET Tooling creates a corresponding web
and
dist
directory when you build and/or serve the app, or publish a
JET Pack with web components.
||| Contents of virtual DOM app directory prior to build or serve
| oraclejetconfig.json
| package-lock.json
| package.json
| path_mapping.json
| tsconfig.json
+---scripts
| +---config
| \---hooks
\---src
| index.html
| index.ts
| main.js
+---components
| | app.tsx
| | footer.tsx
| | header.tsx
| \---content
| index.tsx
\---styles
| app.css
+---fonts
\---images
...
oracle_logo.svg
Oracle JET virtual DOM architecture uses modules to organize VComponents and the Oracle JET Tooling manages the modules in a project.
Custom element-based VComponents must reside in a directory with a name that
matches the name of the component. That is, the oj-hello-world
custom
component must reside in a directory named oj-hello-world
. By default,
the name of the directory where you store all components in your virtual DOM app is
components
, but you can change it to a different value by editing
the value of components
in the oraclejetconfig.json
file in your virtual DOM app's root directory.
{
"paths": {
"source": {
...,
"components": "changeToYourPreferredValue",
...
},
...
Each custom element-based VComponent requires an accompanying
loader.ts
module file, as illustrated by the following example for
a custom element-based VComponent named oj-hello-world
. Oracle JET
Tooling includes this file as Oracle Visual Builder, the Oracle Component Exchange, and
the Oracle JET Tooling itself require it.
...
+---src
| index.html
...
+---components
| | app.tsx
| | footer.tsx
| | header.tsx
| |
| +---content
| | index.tsx
| |
| \---oj-hello-world
| | loader.ts
| | oj-hello-world-styles.css
| | oj-hello-world.tsx
| | README.md
| |
| +---resources
| | \---nls
| | oj-hello-world-strings.ts
| |
...
The Oracle JET Tooling can manage components individually but we recommend that you manage components in a pack (also known as a JET Pack) if you intend to create more than one component.
About the Binding Provider for Virtual DOM Apps
Oracle JET's default binding provider is Knockout. The binding provider that you use affects how Oracle JET custom elements render.
If the default binding provider
(data-oj-binding-provider="knockout"
) is used, all Oracle JET
custom elements, such as oj-list-view
, wait on the apply bindings
traversal to complete before rendering. When Oracle JET custom elements are used in a
Preact environment (virtual DOM app), you must use the preact binding provider
(data-oj-binding-provider="preact"
).
VComponent-based web components implicitly set the binding provider to
preact
on behalf of their child components. As a result, Oracle JET
custom elements inside of a VComponent use the preact
binding provider.
However, for virtual DOM apps, you, the app developer, must configure the binding
provider manually (data-oj-binding-provider="preact"
) somewhere in the
DOM above where you add Oracle JET custom elements. The following code snippet shows
three examples of how you can set the binding provider to preact
.
// Update the entry in the appRootDir/src/index.html file of your virtual DOM app
<body class="oj-web-applayout-body" data-oj-binding-provider="preact">
// Set the data-oj-binding-provider="preact" on a parent element to a collection
// of JET custom elements
<body>
<div id="preact-content-goes-here" data-oj-binding-provider="preact">
<oj-c-button . . .>
<oj-list-view . . .>
</div>
// Set the data-oj-binding-provider="preact" on an individual JET custom element
<oj-list-view data-oj-binding-provider="preact"...>
Note:
Theindex.html
file that the Oracle JET Tooling generates when you
create a virtual DOM app is a regular HTML document with no active binding provider. For
this reason, its use of <body ... data-oj-binding-provider="none">
is appropriate. Note too that the <app-root>
element that the Oracle
JET Tooling also generates in the index.html
file is a VComponent-based
web component and it, like other VComponent-based web components, sets the binding
provider to preact
on behalf of any child components that it
references.
For more information about the binding provider, see the Binding Providers section in the Oracle® JavaScript Extension Toolkit (JET) API Reference for Oracle JET.
Add Progressive Web App Support to Web Apps
Add Progressive Web App (PWA) support to your JET web app if you want to give users a native-like mobile app experience on the device where they access your JET web app.
Using the ojet add pwa
command, you add both a service worker
script and a web manifest to your JET web app. You can customize these artifacts to
determine how your JET web app behaves when accessed as a PWA.
Using the ojet add pwa
command, you add both a service worker script, an
assets
folder with a series of image files for app launcher icons and
splash screens, plus a web manifest file to your JET web app. You can customize these
artifacts to determine how your JET web app behaves when accessed as a PWA.
When you run the command, Oracle JET tooling makes the following changes to your JET web app:
- Adds the following two files to the app’s
src
folder:-
assets
folderThe
assets
folder contains an additional two sub-folders,icons
andsplashscreens
, that contain image files of various dimensions to use as app launcher icons and splash screens on the devices where you install the JET web app. manifest.json
This file tells the browser about the PWA support in your JET web app, and how it should behave when installed on a user's desktop or mobile device. Use this file to specify the app name to appear on a user’s device, plus device-specific icons. For information about the properties that you can specify in this file, see Add a web app manifest.
-
swinit.js
This is the initialization file for the service worker script (
sw.js
). -
sw.js
This is the service worker script that the browser runs in the background. Use this file to specify any additional resources from your JET app that you want to cache on a user’s device if the PWA service worker is installed. By default, JET specifies the following resources to cache:
const resourcesToCache = [ 'index.js', 'index.html', 'bundle.js', 'manifest.json', 'components/', 'libs/', 'styles/', 'assets/' ];
-
- Registers the splash screen
files, the manifest file, and the service worker script in the JET web app's
./src/index.html
file:<html lang="en-us"> <head> . . . <meta name="apple-mobile-web-app-title" content="Oracle JET" /> <meta name="theme-color" content="#000000"> <!-- Splash screens --> <link rel="apple-touch-startup-image" href="assets/splashscreens/splash-640x1136.jpg" . . ."> . . . <link rel="manifest" href="manifest.json"> </head> . . . <script src="swinit.js"></script> </body>
With these changes, a user on a mobile device, such as an Android phone, can initially access your JET web app through its URL using the Chrome browser, add it to the Home screen of the device, and subsequently launch it like any other app on the phone. Note that browser and platform support for PWA is not uniform. To ensure an optimal experience, test your PWA-enabled JET web app on your users' target platforms (Android, iOS, and so on) and the browsers (Chrome, Safari, and so on).
PWA-enabled JET web apps and service workers require HTTPS. The production environment where you deploy your PWA-enabled JET web app will serve the app over HTTPS. If, during development, you want to serve your JET web app to a HTTPS-enabled server, see Serve a Web App to a HTTPS Server Using a Self-signed Certificate.
Build a Web App
Use the Oracle JET command-line interface (CLI) to build a development version of your web app before serving it to a browser. This step is optional.
Change to the app’s root directory and use the ojet build
command
to build your app.
ojet build [--cssvars=enabled|disabled
--theme=themename
--themes=theme1,theme2,...]
Tip:
You can enterojet help
at a terminal prompt to get help for specific Oracle JET CLI options.
Done.
The command will also create a web folder in your app’s root to contain the built content.
Note:
You can also use theojet
build
command with the --release
option to build a
release-ready version of your app. For information, see Package and Deploy Apps.
Serve a Web App
Use ojet serve
to run your web app in a local web server
for testing and debugging. By default, the Oracle JET live reload option is enabled which lets
you make changes to your app code that are immediately reflected in the browser.
To get additional help for the supported ojet serve
options, enter
ojet serve --help
at a terminal prompt.
About ojet serve Command Options and Express Middleware Functions
Use ojet serve
to run your web app in a local web server for
testing and debugging.
The following table describes the available ojet serve
options and provides examples for their use.
Oracle JET tooling uses Express, a Node.js web app framework, to set up
and host the web app when you run ojet serve
. If the ready-to-use
ojet serve
options do not meet your requirements, you can add
Express configuration options or write Express middleware functions in Oracle JET’s
before_serve.js
hook point. For an example that demonstrates how to
add Express configuration options, see Serve a Web App to a HTTPS Server Using a Self-signed Certificate.
The before_serve
hook point provides options to determine
whether to replace the existing middleware or instead prepend and append a middleware
function to the existing middleware. Typically, you’ll prepend a middleware function
(preMiddleware
) that you write if you want live reload to continue
to work after you serve your web app. Live reload is the first middleware that Oracle
JET tooling uses. You must use the next
function as an argument to any
middleware function that you write if you want subsequent middleware functions, such as
live reload, to be invoked by the Express instance. In summary, use one of the following
arguments to determine when your Express middleware function executes:
preMiddleware
: Execute before the default Oracle JET tooling middleware. The default Oracle JET tooling middleware consists ofconnect-livereload
,serve-static
, andserve-index
, and executes in that order.postMiddleware
: Execute after the default Oracle JET tooling middleware.middleware
: Replaces the default Oracle JET tooling middleware. Use if you need strict control of the order in which middleware runs. Note that you will need to redefine all the default middleware that was previously added by Oracle JET tooling.
Option | Description |
---|---|
|
Server port number. If not specified, defaults to 8000. |
|
Live reload port number. If not specified, defaults to 35729. |
|
Enable the watch files feature. Watch files is enabled
by default ( Use Disabling watch files also disables the live reload feature. Configure the interval at which the watch files feature
polls the Oracle JET project for updates by configuring a value for
the |
|
Enable the live reload feature. Live reload is enabled
by default ( Use Disabling live reload can be helpful if you’re working in an IDE and want to use that IDE’s mechanism for loading updated apps. The interval at which the live reload feature polls the
Oracle JET project depends on the |
|
Build the app before you serve it. By default, an app is
built before you serve it ( Use |
|
Theme to use for the app. The theme defaults to
|
|
Themes to use for the app, separated by commas. If you don’t specify the |
|
Serves the app, as if to a browser, but does not launch a browser. Use this option in cloud-based development environments so that you can attach your browser to the app served by the development machine. |
|
Specify the server URL to serve from. For example,
|
Serve a Web App to a HTTPS Server Using a Self-signed Certificate
You can customize the JET CLI tooling to serve your web app to a HTTPS
server instead of the default HTTP server that the Oracle JET ojet serve
command uses.
Do this if, for example, you want to approximate your development environment more closely to a production environment where your web app will eventually be deployed. Requests to your web app when it is deployed to a production environment will be served from an SSL-enabled HTTP server (HTTPS).
To implement this behavior, you’ll need to install a certificate in your web
app directory. You’ll also need to configure the before_serve.js
hook
to do the following:
-
Create an instance of Express to host the served web app.
- Set up HTTPS on the Express instance that you’ve created. You specify the HTTPS protocol, identify the location of the self-signed certificate that you placed in the app directory, and specify a password.
- Pass the modified Express instance and the SSL-enabled server to the
JET tooling so that
ojet serve
uses your middleware configuration rather than the ready-to-use middleware configuration provided by the Oracle JET tooling. - To ensure that live reloads works when your web app is served to the HTTPS server, you’ll also create an instance of the live reload server and configure it to use SSL.
If you can’t use a certificate issued by a certificate authority, you can create your own
certificate (a self-signed certificate). Tools such as OpenSSL, Keychain Access on Mac,
and the Java Development Kit’s keytool
utility can be used to perform
this task for you. For example, using the Git Bash shell that comes with Git for
Windows, you can run the following command to create a self-signed certificate with the
OpenSSL tool:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
-nodes
Once you've obtained the self-signed certificate that you want to use, install it in your app's directory. For example, place the two files generated by the previous command in your app’s root directory:
...
.gitignore
cert.pem
key.pem
node_modules
...
Once you have installed the self-signed certificates in your app, you
configure the script for the before_serve
hook point. To do this, open
the AppRootDir/scripts/hooks/before_serve.js
with your editor and
configure it as described by the comments in the following example configuration.
'use strict';
module.exports = function (configObj) {
return new Promise((resolve, reject) => {
console.log("Running before_serve hook.");
// Create an instance of Express, the Node.js web app framework that Oracle
// JET tooling uses to host the web apps that you serve using ojet serve
const express = require("express");
// Set up HTTPS
const fs = require("fs");
const https = require("https");
// Specify the self-signed certificates. In our example, these files exist
// in the root directory of our project.
const key = fs.readFileSync("./key.pem");
const cert = fs.readFileSync("./cert.pem");
// If the self-signed certificate that you created or use requires a
// password, specify it here:
const passphrase = "1234";
const app = express();
// Pass the modified Express instance and the SSL-enabled server to the Oracle JET tooling
configObj['express'] = app;
configObj['urlPrefix'] = 'https';
configObj['server'] = https.createServer({
key: key,
cert: cert,
passphrase: passphrase
}, app);
// Enable the Oracle JET live reload option using its default port number so that
// any changes you make to app code are immediately reflected in the browser after you
// serve it
const tinylr = require("tiny-lr");
const lrPort = "35729";
// Configure the live reload server to also use SSL
configObj["liveReloadServer"] = tinylr({ lrPort, key, cert, passphrase });
resolve(configObj);
});
};
Once you have completed these configuration steps, run the series of commands
(ojet build
and ojet serve
, for example) that you
typically run to build and serve your web app. As the certificate that you are using is
a self-signed certificate rather than a certificate issued by a certificate authority,
the browser that you use to access the web app displays a warning the first time that
you access the web app. Acknowledge the warning and click the options that allow you to
access your web app. On Google Chrome, for example, you click Advanced and
Proceed to localhost (unsafe) if your web app is being served to
https://localhost:8000/
.
Once your web app opens in the browser, you'll see that the HTTPS protocol is used and an indicator that the connection is not secure, because you are not using a certificate from a certificate authority. You can also view the certificate information to confirm that it is the self-signed certificate that you created. In Google Chrome, click Not secure and Certificate to view the certificate information.

Description of the illustration httpsserver.png
The before_serve
hook point is one of a series of script
hook points that you can use to customize the tooling workflow for Oracle JET apps. See
Customize the Web App Tooling Workflow.
Customize the Web App Tooling Workflow
Hook points that Oracle JET tooling defines let you customize the behavior of the JET build and serve processes when you want to define new steps to execute during the tooling workflow using script code that you write.
When you create an app, Oracle JET tooling generates script templates in the
/scripts/hooks
app subfolder. To customize the
Oracle JET tooling workflow, you can edit the generated templates with the
script code that you want the tooling to execute for specific hook points
during the build and serve processes. If you do not create a custom hook
point script, Oracle JET tooling ignores the script templates and follows
the default workflow for the build and serve processes.
To customize the workflow for the build or serve processes, you edit the generated script template file named for a specific hook point. For example, to trigger a script at the start of the tooling's build process, you would edit the before_build.js
script named for the hook point triggered before the build begins. That hook point is named before_build
.
Therefore, customization of the build and serve processes that you enforce on Oracle JET tooling workflow requires that you know the following details before you can write a customization script.
-
The Oracle JET build or serve mode that you want to customize:
-
Debug — The default mode when you build or serve your app, which produces the source code in the built app.
-
Release — The mode when you build the app with the
--release
option, which produces minified and bundled code in a release-ready app.
-
-
The appropriate hook point to trigger the customization.
-
The location of the default hook script template to customize.
About the Script Hook Points for Web Apps
The Oracle JET hooks system defines various script trigger points, also called hook points, that allow you to customize the create, build, serve, package, and restore workflow across the various command-line interface processes. Customization relies on script files and the script code that you want to trigger for a particular hook point.
The following table identifies the hook points and the workflow customizations they support in the Oracle JET tooling create, build, serve, and restore processes. Unless noted, hook points for the build and serve processes support both debug and release mode.
Hook Point | Supported Tooling Process | Description |
---|---|---|
|
create |
This hook point triggers the script with the default name
|
|
restore |
This hook point triggers the script with the default name
|
|
build |
This hook point triggers the script with the default name
|
|
build (release mode only) |
This hook point triggers the script with the default name
|
|
build / serve |
This hook point triggers the script with the default name
|
|
build / serve |
This hook point triggers the script with the default name
|
|
build / serve |
This hook point triggers the script with the default name
|
|
build / serve |
This hook point triggers the script with the default name
|
|
build / serve |
This hook point triggers the script with the default name
|
|
build / serve (release mode only) |
This hook point triggers the script with the default name
|
|
build / serve |
This hook point triggers the script with the default name |
|
build |
This hook point triggers the script with the default name
|
|
build |
This hook point triggers the script with the default name |
|
build (debug mode only) |
This hook point triggers the script with the default name |
|
serve |
This hook point triggers the script with the default name
|
|
serve |
This hook point triggers the script with the default name
|
|
serve |
This hook point triggers the script with the default name
|
|
serve |
This hook point triggers the script with the default name
|
after_component_package |
package | This hook point triggers the script with the default name
after_component_package.js immediately after the
tooling concludes the component package process.
|
before_component_package |
package | This hook point triggers the script with the default name
before_component_package.js immediately before the
tooling initiates the component package process.
|
About the Process Flow of Script Hook Points
The Oracle JET hooks system defines various script trigger points, also called hook points, that allow you to customize the create, build, serve, and restore workflow across the various command-line interface processes.
The following diagram shows the script hook point flow for the create process.

The following diagram shows the script hook point flow for the build process.

The following diagram shows the script hook point flow for the serve and restore processes.

Change the Hooks Subfolder Location
When you create an app, Oracle JET tooling generates script templates in the
/scripts/hooks
app subfolder. Your development effort may require you
to relocate hook scripts to a common location, for example to support team
development.
By default, the hooks system locates the scripts in the hooks
subfolder using a generated JSON file (hooks.json
) that specifies the
script paths. When the tooling reaches the hook point, it executes the corresponding
script which it locates using the hooks.json
file. If you relocate hook
script(s) to a common location, you must edit the hooks.json
file to
specify the new location for the hook scripts that you relocated, as illustrated by the
following example.
{
"description": "OJET-CLI hooks configuration file",
"hooks": {
"after_app_create": "scripts/hooks/after_app_create.js",
...
"after_serve": "http://example.com/cdn/common/scripts/hooks/after_serve.js "
}
}
Create a Hook Script for Web Apps
You can create a hook point script to define a new command-line interface process step for your web app. To create a hook script, you edit the hook script template associated with a specific hook point in the tooling build and serve workflow.
The Oracle JET hooks system defines various script trigger points, also called hook points, that allow you to customize the build and serve workflow across the various build and serve modes. Customization relies on script files and the script code that you want to trigger for a particular hook point. Note that the generated script templates that you modify with your script code are named for their corresponding hook point.
To customize the workflow for the build or serve processes, you edit the generated script template file named for a specific hook point. For example, to trigger a script at the start of the tooling's build process, you would edit the before_build.js
script named for the hook point triggered before the build begins. That hook point is named before_build
.
A basic example illustrates a simple customization using the
before_optimize
hook, which allows you to control the RequireJS properties
shown in bold to modify the app's bundling configuration.
requirejs.config(
{
baseUrl: "web/js",
name: "main-temp",
paths: {
// injector:mainReleasePaths
"knockout":"libs/knockout/knockout-3.x.x.debug",
"jquery":"libs/jquery/jquery-3.x.x",
"jqueryui-amd":"libs/jquery/jqueryui-amd-1.x.x",
...
}
// endinjector
out: "web/main.js"
}
...
A script for this hook point might add one line to the
before_optimize
script template, as shown below. When you build the app
with this customization script file in the default location, the tooling triggers the script
before calling requirejs.out()
and changes the out
property
setting to a custom directory path. The result is that the app-generated
main.js
is created in the named directory instead of the default
web/js/main.js
location.
module.exports = function (configObj) {
return new Promise((resolve, reject) => {
console.log("Running before_optimize hook.");
configObj.requirejs.out = 'myweb/js/main.js';
resolve(configObj);
});
};
You can retrieve more information about the definition of
configObj
that is passed into many script hook points as a parameter by
making the following modification in one of the build-related hook points and then running
ojet build
. For example, the before_build.js
hook point
can be modified as follows:
module.exports = function (configObj) {
return new Promise((resolve, reject) => {
console.log("Running before_build hook.", configObj);
resolve(configObj);
});
};
The console from where you run the ojet build
command then
displays the available options that you can customize in configObj
.
Cleaning staging path.
Running before_build hook {
buildType: 'dev',
opts: {
stagingPath: 'web',
injectPaths: {
startTag: '// injector:mainReleasePaths',
. . .
Elsewhere, read examples that illustrate how to use the
configObj
to customize a hook point to, for example, add Express
configuration options or write Express middleware functions in the
before_serve.js
hook point if the ready-to-use ojet serve
options do not meet your requirements. See Serve a Web App to a HTTPS Server Using a Self-signed Certificate.
Tip:
If you want to change app path mappings, it is recommended to always edit the
path_mappings.json
file. An exception might be when you want app runtime
path mappings to be different from the mappings used by the bundling process, then you might
use a before_optimize
hook script to change the
requirejs.config
paths
property.
The following example illustrates a more complex build customization using the after_build
hook. This hook script adds a customize task after the build finishes.
'use strict’;
const fs = require('fs');
const archiver = require('archiver');
module.exports = function (configObj) {
return new Promise((resolve, reject) => {
console.log("Running after_build hook.");
//Set up the archive
const output = fs.createWriteStream('my-archive.war');
const archive = archiver('zip');
//Callbacks for the archiver
output.on('close', () => {
console.log('Files were successfully archived.');
resolve();
});
archive.on('warning', (error) => {
console.warn(error);
});
archive.on('error', (error) => {
reject(error);
});
//Archive the web folder and close the file
archive.pipe(output);
archive.directory('web', false);
archive.finalize();
});
};
In this example, assume the script templates reside in the default folder generated
when you created the app. The goal is to package the app into a ZIP file. Because packaging
occurs after the app build process completes, this script is triggered for the
after_build
hook point. For this hook point, the modified script template
after_build.js
will contain the script code to ZIP the app, and because the
.js
file resides in the default location, no hooks system configuration
changes are required.
Tip:
Oracle JET tooling reports when hook points are executed in the message log for the build and serve process. You can examine the log in the console to understand the tooling workflow and determine exactly when the tooling triggers a hook point script.
Pass Arguments to a Hook Script for Web Apps
You can pass extra values to a hook script from the command-line interface
when you build or serve the web app. The hook script that you create can use these values to
perform some workflow action, such as creating an archive file from the contents of the
web
folder.
--user-options
flag to the command-line interface
for Oracle JET to define user input for the hook system when you build or serve the web app.
The --user-options
flag can be appended to the build or serve commands and
takes as arguments one or more space-separated, string
values:ojet build --user-options="some string1" "some string2" "some stringx"
archive-file
set to the archive file name by using the
--user-options
flag on the Oracle JET command
line.ojet build web --user-options="archive-file=deploy.zip"
If
the flag is appended and the appropriate input is passed, the hook script code may write a ZIP
file to the /deploy
directory in the root of the project. The following
example illustrates this build customization using the after_build
hook. The
script code parses the user input for the value of the user defined
archive-file
flag with a promise to archive the app after the build
finishes by calling the NodeJS function fs.createWriteStream()
. This hook
script is an example of taking user input from the command-line interface and processing it to
achieve a build workflow customization.
'use strict';
const fs = require('fs');
const archiver = require('archiver');
const path = require('path');
module.exports = function (configObj) {
return new Promise((resolve, reject) => {
console.log("Running after_build hook.");
//Check to see if the user set the flag
//In this case we're only expecting one possible user defined
//argument so the parsing can be simple
const options = configObj.userOptions;
if (options){
const userArgs = options.split('=');
if (userArgs.length > 1 && userArgs[0] === 'archive-file'){
const deployRoot = 'deploy';
const outputArchive = path.join(deployRoot,userArgs[1]);
//Ensure the output folder exists
if (!fs.existsSync(deployRoot)) {
fs.mkdirSync(deployRoot);
}
//Set up the archive
const output = fs.createWriteStream(outputArchive);
const archive = archiver('zip');
//callbacks for the archiver
output.on('close', () => {
console.log(`Archive file ${outputArchive} successfully created.`);
resolve();
});
archive.on('error', (error) => {
console.error(`Error creating archive ${outputArchive}`);
reject(error);
});
//Archive the web folder and close the file
archive.pipe(output);
archive.directory('web', false);
archive.finalize();
}
else {
//Unexpected input - fail with information message
reject(`Unexpected flags in user-options: ${options}`);
}
}
else {
//nothing to do
resolve();
}
});
};
Use Webpack in Oracle JET App Development
You can use Webpack to manage your Oracle JET app, as well as the build and serve tasks.
If you decide to use Webpack, Oracle JET passes responsibility to Webpack to build and serve the source files of your Oracle JET project. Before you decide to use Webpack, note that it is not possible to use Webpack with Oracle JET apps that need to build, package or publish web components, to test apps using Oracle JET's Component WebElements UI automation library (TestAdapters), or to use the newer Core Pack components through their component class names. That is, the following syntax won't work:
import { SelectMultiple } from "oj-c/select-multiple";
export function Content() {
return (
<SelectMultiple labelHint="Select Multiple" itemText="foo"/>
);
};
Though you can use Core Pack components using their custom element names, as in the following example:
import "oj-c/select-multiple";
export function Content() {
return (
<oj-c-select-multiple labelHint="Select Multiple" />
);
};
If you decide to use Webpack in your Oracle JET app, you can specify it as a command-line argument when you scaffold the project, as demonstrated by the following example command:
ojet create <app-name> --template=basic --vdom --webpack
To build and serve the app with Webpack, simply run ojet
build
and ojet serve
respectively. You cannot use the
ojet serve --release
command. To run a release build from your
local development environment, use the ojet build --release
command,
and then use a static server of your choice (for example, http-server) from the /web
folder.
To add Webpack to an existing Oracle JET app, run the following command from the root directory of your Oracle JET project:
ojet add webpack
The files and directories in an Oracle JET project that uses Webpack differ to a project
an app generated without specifying the --webpack
argument. The
following table describes the differences that result from use of the --webpack
argument.
Option | Description |
---|---|
|
The types directory contains a
/types/components/index.d.ts file with a stub to
add custom element tag names to the list of known JSX intrinsic
elements. This is important if you plan to use custom elements within
JSX that do not have preact.JSX.IntrinsicElements type
definitions. Note that /types should only include type
definitions which do not emit a JavaScript file after compilation. If
you wish to rename the folder, make sure to also update the reference to
it in the tsconfig.json file under the
typeRoots option.
|
|
This file manages Oracle JET's default webpack configuration. For more detail about this file and how to configure it, see Configure Oracle JET's Default Webpack Configuration. |
|
In constrast to the |
As mentioned at the start of this topic, it is not possible to use Webpack in Oracle JET projects that build, package or publish web components, or projects that need use JET theming. In other words, this means that you cannot use the following commands from the Oracle JET CLI:
ojet build (component|pack)
ojet package (component|pack)
ojet publish (component|pack)
One other thing to note is that when you serve your Oracle JET app in development mode
(the default), the Oracle JET app loads styles from memory and styles appear in the
<styles>
tag in the HTML of your browser. In contrast, when you
serve an Oracle JET app that you have built in release mode (ojet build
--release
), styles come from the CSS file link that is included in the HTML
file. In the following image, with an Oracle JET app instance that runs in development
mode and release mode instance, you can see the different entries using the browser’s
developer tools.

Configure Oracle JET's Default Webpack Configuration
You can configure the default Webpack configuration generated by the Oracle
JET CLI through the webpack
function in the ojet.config.js
file.
The webpack
function receives an object with the Oracle JET
build context (context
) and Webpack configuration
(config
). Note the buildType
property which
indicates whether Webpack executes in development or release mode. As for
config
, the default Webpack configuration generated by Oracle JET,
you can customize it to fit your needs.
To view the default options in the ojet.config.js
file, add a console
log statement to the ojet.config.js
file, as demonstrated by the
following examples:
. . .
webpack: ({ context, config }) => {
if (context.buildType === "release") {
// update config with release / production options
} else {
// Print out the default webpack configuration options
// as a JSON string
console.log(JSON.stringify(config));
// Or let your terminal console determine how to
// present the configuration
console.log(config);
}
. . .
Then build your Oracle JET project using the following command to render the default configuration in the terminal console:
ojet build
Tip:
Create a JSON-formatted file in Visual Studio Code to view the default configuration in a more readable form to that returned by the terminal.The default Webpack configuration for an Oracle JET app built in development mode includes the following top-level nodes:
{
"entry": { },
"output": { },
"module": {},
"resolve": {},
"resolveLoader": { },
"plugins": [],
"mode": "development",
"devServer": { }
}
Once you have identified the configuration setting in Oracle JET's default
Webpack configuration that you want to change, you add the alternative value in the
ojet.config.js
file. The following example illustrates how to
change the port number when you serve your Oracle JET app in development mode using
Webpack.
module.exports = {
webpack: ({ context, config }) => {
if (context.buildType === 'release') {
// update config with release / production options
} else {
// update config with development options. In the following example, we specify
// a different server port number to the default of 8000
config.devServer.port = 3000;
// Print out the default webpack configuration options as a JSON string
console.log(JSON.stringify(config));
// Or let your terminal console determine how to present the configuration
console.log(config);
}
return config;
}
};