How to handle the JS in custom app?

I know that Python and JavaScript are the primary languages for Frappe and ERPNext. While I’ve mainly worked on the Python side, I only use basic JavaScript for default event handlers, frappe.call, frm.call, and a few utilities. I really enjoy Python’s modularity, where I can create various modules for different purposes, import them, and use them anywhere within the working directory. However, JavaScript tends to be a bit overwhelming for me, and I feel like I’m missing something important.

I’ve reviewed several utility.js files in the Frappe, ERPNext, and HRMS apps. They mostly follow a similar pattern: creating a namespace with frappe.provide() and adding functions or objects to that namespace, then importing it into my_custom_app.bundle.js to use it elsewhere. I tried implementing it this way, but for some reason, my utility.js file doesn’t seem to be working.

Here’s my utility.js file:

frappe.provide('genreport.util');

genreport.util.utilsF1 = () => {
    console.log("Test 1")
}

genreport.util.utilsF2 = () => {
    console.log("Test 2")
}

In my_custom_app.bundle.js, I’m importing it like this:

import "./utils";

Then, I try to use these utility functions in my_custom_service.js:

$(document).ready(function() {
    genreport.util.utilsF1();
    genreport.util.utilsF2();
});

And here’s my hooks.py file:

app_include_js = [
    "/assets/genreport/js/my_custom_app.bundle.js",
    "/assets/genreport/js/my_custom_service.js",
]

After running the app with bench start, I encounter this error in the console:

jquery.js:4059 Uncaught ReferenceError: genreport is not defined
    at HTMLDocument.<anonymous> (genreport.js:15:9)
    at mightThrow (jquery.js:3766:29)
    at process2 (jquery.js:3834:12)

Conclusion

At this point, I’m unable to use functions or objects from other files as intended. If anyone can offer guidance on how to effectively import files in JavaScript within Frappe/ERPNext, I’d really appreciate it!

if i include the utils.js file in the app_include_js its working but my concern is its not added like that in other apps like frappe, erpnext, hrms. please suggest if you have any other approach this is the way I added

app_include_js = [
    "/assets/genreport/js/utils.js", # Make sure your utils file loading first
    "/assets/genreport/js/my_custom_app.bundle.js",
    "/assets/genreport/js/my_custom_service.js",
]

In the above case for the my_custom_app.bundle.js, I added the file path from the assets, but in the other frappe and erpnext apps, it’s not added from the assets. It just mentions the file name. I made some changes in the JS load.

hooks.py

app_include_js="my_custom_app.bundle.js"

my_custom_app.bundle.js

import "./utils";
import "./my_custom_service"

now its worked fine

Small Reference: Any Idea to run JS script on any/specific doctype? - #2 by NCP

1 Like