How to import a .js module in Frappe?

Hi @satyajit_ghana. Try removing your export statements. Export is not needed in frappe.require() and if I remember correctly, it does interfere with the import if the keyword is found in your script.

As an example, if you had a script, stored in your app’s public/js directory, with a function that prints a greeting message, and you wanted to call it in your document each time you refresh the page:

example.js

function greet_user() {
    frappe.msgprint("Hello " + frappe.session.user_fullname)
}

Then in your client script:

frappe.require([
    '/assets/example_app/js/example.js',
]);

frappe.ui.form.on('Example Doc', {
    refresh(frm) {
        greet_user()
    }
}

Does this help?

1 Like

Hi @archais , thanks for the reply

My concern is better explained in this: Can't import external JS Library in Frappe App

So what i basically want to do is import a node_module (xeokit) in a js file, but i’m not able to.

I don’t want to modify the node module package (xeokit) because every time i deploy i have to do that, and every time there’s a npm i i have to do that.

Ah, I see your problem now. Unfortunately, I’ve never worked with NPM modules, nevermind using them in Frappe. However, I did find a tutorial for using them in Frappe, have you seen this: Tutorial: Adding node modules to Frappe?

yes i did

node_modules = {
	'xeokit': {
		'js': [
			'/assets/myapp/node_modules/@xeokit/xeokit-sdk/dist/xeokit-sdk.es.js'
		]
	}
}

# include js, css files in header of desk.html
app_include_js = [
	*node_modules.get('xeokit').get('js'),
	# "/assets/js/xeokit.min.js",
	"/assets/js/myapp.min.js"
]

this is my build.json

{
	"js/myapp.min.js": [
		"public/js/xeokit.js"
	]
}

and this is my public/js/xeokit.js

import { Viewer, XKTLoaderPlugin, NavCubePlugin, TreeViewPlugin, FastNavPlugin } from "@xeokit/xeokit-sdk/dist/xeokit-sdk.min.es.js";

frappe.provide("frappe.xeokit")

frappe.xeokit.Viewer = Viewer
frappe.xeokit.XKTLoaderPlugin = XKTLoaderPlugin
frappe.xeokit.NavCubePlugin = NavCubePlugin
frappe.xeokit.TreeViewPlugin = TreeViewPlugin
frappe.xeokit.FastNavPlugin = FastNavPlugin

This gives me

$ node rollup/build.js --app myapp
Development mode
✔ Built js/moment-bundle.min.js
✔ Built js/libs.min.js

Building myapp assets...

SyntaxError: Unexpected token (16:416) in /workspace/development/mileone-bench/apps/myapp/node_modules/@xeokit/xeokit-sdk/dist/xeokit-sdk.min.es.js

What is the token at that address?

you can view the file yourself at: https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk@2.0.0-beta.17/dist/xeokit-sdk.es.min.js

I was finally able to import it

It turns out xeokit had this

XKTLoaderPlugin.js

 getProperties: async (propertiesId) => {
         return await this._dataSource.getProperties(src, propertiesId);
}

and frappe DOES NOT support the arrow syntax

i simply had to make it

 getProperties: async function(propertiesId) {
         return await this._dataSource.getProperties(src, propertiesId);
}

and that made it work

BUT

I’ve read that frappe support ES6, so why isn’t ES6 syntax working ?

1 Like

That’s quite strange as I use the arrow format in my own code without any issues. Well done for getting it to work! Out of interest, is your frappe up to date?

ERPNext: v13.9.2 (version-13)
Frappe Framework: v13.9.0 (version-13)

So it’s not a version problem because that’s what I’m on. Maybe the arrow syntax only doesn’t work in node modules for some reason? :thinking:

update: i was wrong, just changing the arrow function syntax didn’t work

it turns out i had to retranspile xeokit with buble, and everything worked !

for anyone who comes here, here’s the commit which fixed it: change: add buble; feat: now supports frappe · satyajitghana/xeokit-sdk@3ed8859 · GitHub

but something curious to note is that frappe does use buble on its own in rollup, i wonder why that didn’t work

1 Like

Well done! It’s at least less strange that it’s not using buble on it when compared to it not using the arrow syntax.

1 Like

this problem cannot resolved, you have other ways ?

Hi Eric. What do you mean the problem cannot be resolved? What is your particular issue?

i try use this way deal with this problem, but alert exception, You have a good solved way?



@archais, Do you have a good idea?

What is the absolute path of your demo.js file? It should be something like

../apps/your_app/your_app/public/js/demo.js

Ah, I think that I may have found your issue

Your file path in the frappe.require() is supposed to include the app name so instead of:

frappe.require("/assets/js/demo.js")

It should be:

frappe.require("/assets/**your_app**/js/demo.js")

path not found reason: js address problem

but this problem resolved after i found A new problem, js method not function, can you help me?

i think framework load not recognized this method, do you good idea?

How have you defined the function in your demo.js?

Yes, i already defined

image