Client integration
Getting started
The client component is the single client-side toolkit that can be used with all of our HOOPS Envision for Web server components, or as a pure client-side toolkit. It is provided in a minified Javascript UMD bundle with additionnal TypeScript definitions. The quickest way to start is to take a look at our examples :
- Build Your First App provides a quick introduction to using the client component in a Web application.
- Examples provides a set of complete example applications using client and server components.
Quick testing in HTML
Most of our examples are loading the component as a global variable in a script tag. When the component is loaded directly from an HTML file, it will load as a global variable named “cee” that contains every sub-modules. This is also the default behavior when the usage context can not be detected.
<script src="./CeeEnvisionWebComponents.js"></script>
<script>
const session = new cee.CloudSession();
...
</script>
Installation
If your application is about to use a specific server-side component (ug, cug, vs), follow first the “Getting started” installation section of the documentation of your server-side component :
- Server for Remote Models (UgServer) for Remote Model
- Server for Constant Remote Models (CugServer) for Constant Remote Model
- Getting Started for Visualization Streamer
For a pure client-side usage (geo, usg), proceed directly to step 2.
- Copy the content of the “client” folder of the HOOPS distribution to your client project. To learn more about the content of the distribution, please refer to the Distribution Content page.
- If you plan to use the Remote Model (ug.RemoteModel), you will have to install an additionnal dependency :
socket.io-client. To install it, runnpm install socket.io-client.
Integration in your build workflow
The client component is distributed as a UMD module. It can be included natively with AMD and CommonJS. A transformation step is necessary to integrate it with ECMAScript modules. If the module type cannot be detected, or is not compatible with the UMD format, it will load as a global variable. The distribution also includes TypeScript definitions.
Below, you will find some tips and examples to integrate the Envision Web client to your workflow :
JavaScript
1. With a bundler and/or a transpilation pipeline
To use import with a named local variable, and benefit from module encapsulation, you will need to use a transformation step. In most cases, adding a CommonJS transformation plugin to your favorite bundler will be sufficient to be able to use the UMD module with CommonJS, ESM and AMD targets interchangeably.
In most cases, you will need to use the usual default import syntax to load the module :
import cee from './CeeEnvisionWebComponents.js'; // ECMAScript module syntax
...
// or
const cee = require('./CeeEnvisionWebComponents.js'); // CommonJS syntax
...
// or
require(['./CeeEnvisionWebComponents.js'], function(cee) { // AMD syntax
...
});
Here are some tips to help you integrate the UMD bundle in your project with popular bundlers :
a. Webpack
Use the
type: "javascript/auto"option in your javascript rule in the webpack config file to make the bundle compatible with most JS module types, including UMD. This setting works as well with a built-in Webpack rule (e.g. without a “use” option) than with complexBabelandSWCtransformation pipelines.... module: { rules: [ { test: /\.m?js$/, exclude: /node_modules/, type: "javascript/auto", use: { ... } }, ], } ...Beware : Contrary to other methods described in this section, ESM modules must be imported with the
import * assyntax or by submodule with theimport { MyClass } fromsyntax.import * as cee from './CeeEnvisionWebComponents.js'; const session = new cee.CloudSession(); // or import { CloudSession } from './CeeEnvisionWebComponents.js'; const session = new CloudSession(); ...
- For CommonJS, use a regular default require statement as describe in the begginning of this section.
- For AMD, the example should work for most cases. However, you may need more configuration when loading multiples AMD and UMD modules that depends on each others.
b. Rollup
A minimal
rollup.config.jsfile should look like this :import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; const production = !process.env.ROLLUP_WATCH; export default { input: 'index.js', output: { sourcemap: true, format: 'iife', // Change to your prefered output format. E.g. 'esm' for ES modules. name: 'app', file: 'dist/index.js' }, plugins: [ resolve({ browser: true, }), commonjs(), ], };That setup works as well with ESM, CJS and AMD modules pipelines. Use the default syntax described at the beginning of this section.
c. Vite
Use the
vite-plugin-commonjsto load the UMD as CommonJS, and take advantage of the compatibility between CommonJS and ES modules. Here is an example ofvite.config.jsconfiguration :import { defineConfig } from 'vite'; import commonjs from 'vite-plugin-commonjs'; export default defineConfig({ plugins: [commonjs()], });Much like the rollup example, all the default import syntaxes described at the beginning of the section should work.
2. Native JavaScript
a. ESM
Importing the client module with an ESM-style import will cause it to load as a global variable, unless you use a native CommonJS platform. This is a limitation of the UMD format. To overcome this limitation, you will need to use a transformation stage as described in sections above. Importing the client module with an ESM-style import will cause it to load as a global variable, unless you use a native CommonJS plateform. This is a limitation of the UMD format. To overcome this limitation, you will need to use a transformation stage as described in sections above.
import cee from './CeeEnvisionWebComponents.js'; // Loading an UMD module in a ES module context creates an empty import object. const session = new cee.CloudSession(); // Causes an error while accessing any sub-module. ...instead do :
import './CeeEnvisionWebComponents.js'; // loads the UMD module as global "cee". const session = new cee.CloudSession(); ...
b. CommonJS / Node.js
If you use a Node-based environment, you can use the CommonJS
requiredirectly to load the bundle.const cee = require('./CeeEnvisionWebComponents.js'); const session = new cee.CloudSession(); ...If your code executes in a browser, you will need to use a transformation pipeline that supports CJS modules. See the 1. With a bundler and/or a transpilation pipeline section above for more details.
c. Electron
For the Electron platform specifically :
- On the client side, use the bundling strategy described in the 1. With a bundler and/or a transpilation pipeline section.
- On the server side, you can use the CommonJS require to load the bundle directly (see the “Native CommonJS” section above).
d. AMD with RequireJS
AMD is natively supported by the UMD format. If you use RequireJS as a module loader, you can load the Envision Web component as follows :
HTML
<script src="./require.js"></script> <script> require(['./index.js'], function(myApp){ myApp(); }); </script>JavaScript
require(["./CeeEnvisionWebComponents.js"], function(cee) { const session = new cee.CloudSession(); ... });If you use AMD in a bundled project, read the Bundling section above.
TypeScript
The TypeScript setup is very much similar to the JavaScript one. To use the client component as a TypeScript module, the easiest path is to use a UMD -> CommonJS -> ESM transformation pipeline such as the one described in the 1. With a bundler and/or a transpilation pipeline section above. Often, an additionnal typescript plugins will be needed.
In most cases, the transpilation can make use of the Typescript definitions to provide named imports :
import * as cee from './CeeEnvisionWebComponents.js';
const session = new cee.CloudSession();
// or
import { CloudSession } from './CeeEnvisionWebComponents.js';
const session = new CloudSession();
...
CommonJS and AMD syntaxes are also supported :
const cee = require('./CeeEnvisionWebComponents.js'); // CommonJS syntax
...
// or
require(['./CeeEnvisionWebComponents.js'], function(cee) { // AMD syntax
...
});
1. Bundler / transpiler specific configuration
a. Webpack
The
ts-loadershould work seamlessly witout the need for further configuration :
webpack.config.js... { test: /\.tsx?$/, exclude: /node_modules/, use: { loader: "ts-loader", options: { transpileOnly: true, }, }, }, ...You can then use both
import * asorimport { MyClass } fromsyntax.
b. Rollup
Here is an example of minimal
rollup.config.jsfile that should work out of the box :import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import typescript from '@rollup/plugin-typescript'; const production = !process.env.ROLLUP_WATCH; export default { input: 'index.ts', output: { sourcemap: true, format: 'iife', name: 'app', file: 'dist/index.js' }, plugins: [ resolve({ browser: true, }), typescript({ sourceMap: !production, inlineSources: !production, strict: true }), commonjs(), ], };
c. Vite
The
vite-plugin-commonjsplugin can be used as well to integrate our bundle with Typescript. However, the drawback of that method is that it does not allow the use of Typescript definitions and only allows to import the module as a default import :import cee from './CeeEnvisionWebComponents.js';// import as default ...There is probably a better, more complex way to do it, by using a lower-level rollup configuration as the one provided above.
d. TSC
Depending on your target module type, you will need to adapt your tsconfig.json file as follows :
For ESM or IIFE targets, you will need to load UMD modules as global variables. In the “compilerOptions” section of your tsconfig.json file, set the
allowUmdGlobalAccesstotrue. Then import the module with that syntax :import './CeeEnvisionWebComponents.js';.For AMD targets, a minimal tsconfig is sufficient and allow more :
tsconfig.json{ "compilerOptions": { "target": "es6", "module": "amd", "types" : [], "outDir": "./dist", "strict": true }, "files": [ "index.ts", ], } See our examples for more details.This setup has the advantage to allow the use of both
import * asandimport { MyClass } fromsyntaxes.
2. Optional TypeScript configuration
The following options are not necessary, but recommended when bundling Javascript. Add these in your tsconfig.json file to ensure the JavaScript is imported correctly, that is it not loaded as a global, and to prevent conflicts with type definitions :
tsconfig.json
{
"compilerOptions": {
...
"esModuleInterop": true,
"allowUmdGlobalAccess": false,
"isolatedModules": true,
"allowJs": true,
...
}
}
F.A.Q.
Is Envision Web available as a NPM package ?
No, there is no NPM package at the moment. It might change in the future.
Is Envision Web available as a native ESM module ?
No, you need to use a bundler to convert it, unless your are fine with using a global variable. See the examples provided in the 1. With a bundler and/or a transpilation pipeline section to read more about the course of action to take.
Can I use Envision Web with frameworks like React, Angular or Vue ?
Yes absolutely. See the “Example Applications” page for more details.
One of the example on this page is not working, what should I do ?
The context of your project can affect the way building tools behave in many ways. For example, most build tools will check their own configuration files, but also the content of package.json. Typescript tools can also check tsconfig.json and their own configuration files. Try to keep your config files as simple as possible. If necessary, try to build a simple project from scratch to isolate the problem.
If you still have issues, please contact our support.