:orphan:

###
ESM
###

|HCNOW|'s new import system
===========================

As of |HCTHEN| version 2024.2.0, |HCNOW| has migrated to an ESM (ECMAScript Module) based system in an effort to modernize the code base. With this change, we hope to simplify and improve the user experience in a few different ways. The added support for ESM can offer you improved code organization, encapsulation, dependency managements, performance, and compatibility with modern Javascript development practices. For these reasons, it is strongly recommended to use ESM, if possible.

These improvements will be found in the package in the form of a few scripts for different environments.

Please note that the older IIFE system can still be used. UMD is also newly supported, however, ESM is recommended as it is the modern standard.


The IIFE
########

Historically, we have always provided the Web Viewer code as an IIFE (Immediately Invoked Function Expression) and we will continue to do so. However, if you are starting a new project with |HCNOW|, ESM is recommended.

You should be able to replace the IIFE files in your project with those in *<COMMUNICATOR_INSTALL_DIR>/web_viewer/*:

.. code-block:: none

	- engine.wasm
	+ engine.esm.wasm

	- hoops_web_viewer.js
	+ hoops-web-viewer.iife.js


The change should be seamless. Your HTML should look like this simple sample:

.. code-block:: html

	<!DOCTYPE html>
	<html lang="en">
	  <head>
		<!-- ... -->
		<script type="text/javascript" src="./hoops-web-viewer.iife.js"></script>
	  </head>
	  <body>
		<!-- ... -->
		<div id="viewerContainer" tabindex="0"></div>
		<!-- ... -->
		<script type="text/javascript">
		  const container = document.getElementById('viewerContainer');
		  const hwv = new Communicator.WebViewer({
			container,
			endpointUri: 'models/microengine.scs',
			enginePath: '.', // The engine folder path is mandatory
		  });

		  /* ... */
		</script>
	  </body>
	</html>

You can see an example of using IIFE in *<COMMUNICATOR_INSTALL_DIR>/web_viewer/examples/iife.html* and *<COMMUNICATOR_INSTALL_DIR>/web_viewer/examples/iife.js*.


The ESM
#######

For ESM users, the only thing to keep in mind is that there is no need for prefixing HOOPS classes with ``Communicator``.

You should be able to replace these files in your project with those in *<COMMUNICATOR_INSTALL_DIR>/web_viewer/*:

.. code-block:: none

	- engine.wasm
	+ engine.esm.wasm

	- hoops_web_viewer.js
	+ hoops-web-viewer.mjs


By using only those Javascript files needed by your application, you can now do things like exclude larger pieces of code, if possible. The change should be very minimal. Your HTML should look like this simple sample:

.. code-block:: html

	<!DOCTYPE html>
	<html lang="en">
	  <head>
		<!-- ... -->
	  </head>
	  <body>
		<!-- ... -->
		<div id="viewerContainer" tabindex="0"></div>
		<!-- ... -->
		<script type="module">
		  import { WebViewer } from './hoops-web-viewer.mjs';
		  // Or you can mimic the historic style by aliasing the import
		  // import * as Communicator from './hoops-web-viewer.mjs';

		  const container = document.getElementById('viewerContainer');
		  const hwv = new WebViewer({
			container,
			endpointUri: 'models/microengine.scs',
			enginePath: '.', // The engine folder path is mandatory
		  });

		  /* ... */
		</script>
	  </body>
	</html>

You can see an example of using the ESM in *<COMMUNICATOR_INSTALL_DIR>/web_viewer/examples/esm.html* and *<COMMUNICATOR_INSTALL_DIR>/web_viewer/examples/esm.js*.


The UMD
#######

Additionally, some users may use systems based on RequireJS and relate on AMD/UMD files. We provide these technologies for those customers who prefer UMD, but we recommend ESM because it is the modern standard.

You should be able to replace these files in your project with those in *<COMMUNICATOR_INSTALL_DIR>/web_viewer/*:

.. code-block:: none

	- engine.wasm
	+ engine.esm.wasm

	- hoops_web_viewer.js
	+ hoops-web-viewer.umd.js

The code should be very similar to what you're used to:

.. code-block:: html

	<!DOCTYPE html>
	<html lang="en">
	  <head>
		<!-- ... -->
		<script crossorigin src="./require.min.js"></script>
	  </head>
	  <body>
		<!-- ... -->
		<div id="viewerContainer" tabindex="0"></div>
		<!-- ... -->
		<script type="module">
		  requirejs(['hoops-web-viewer.umd.js'], (Communicator) => {
			const hwv = new Communicator.WebViewer({
			  container,
			  endpointUri: 'models/microengine.scs',
			  enginePath: '.',
			}); // The engine folder path is mandatory

			/* ... */
		  });
		</script>
	  </body>
	</html>

You can see an example of using the UMD in *<COMMUNICATOR_INSTALL_DIR>/web_viewer/examples/umd.html* and *<COMMUNICATOR_INSTALL_DIR>/web_viewer/examples/umd.js*.


Experiment
##########

If you want to experiment with the ESM version you can replace the *quick_start/server_config.js* with *web_viewer/server_config_esm.js*.

Alternatively, you can also edit the *start_server* script in *quick_start*.

For Windows users, apply these changes in *quick_start/start_server.bat*:

.. code-block:: none

	- @call "%node_install_dir%\node.exe" --expose-gc ./lib/Startup.js --config-file ../../quick_start/server_config.js
	+ @call "%node_install_dir%\node.exe" --expose-gc ./lib/Startup.js --config-file ../../quick_start/server_config_esm.js

For Linux and Mac, apply these changes in *quick_start/start_server.sh*:

.. code-block:: none

	- ${node_install_dir}/bin/node --expose-gc ./lib/Startup.js --config-file ../../quick_start/server_config.js
	+ ${node_install_dir}/bin/node --expose-gc ./lib/Startup.js --config-file ../../quick_start/server_config_esm.js

Now you can run the *start_server* script and try the examples and the demo application.


Migrating
##########

If you want to know more about the changes of the ESM version you can read our page about migration :doc:`here </overview/migrating-to-esm>`.
