Importing and using ES6 modules through npm browserify

Hello, so I’m new to npms and I’m using the official documentation of importing three.js through an npm which is this:

var THREE = require('three');

var scene = new THREE.Scene();

when a scene is created everything is good except I would like to use Map controls from orbit controls

import { MapControls } from 'three/examples/jsm/controls/OrbitControls.js';

The only way i’m able to use this map functionality is through this method (when I’m not using npms).

I tried using ES6 imports but it gives me this error:

** Parsing error: ‘import’ and ‘export’ may appear only with 'sourceType: module**

I tried adding this to my package.json file but to no avail.

 "parserOptions": {
        "sourceType": "module"

Hmm, I’m not sure that the docs should suggest using require first (if at all). Can you try doing this instead?

import * as THREE from 'three';

There’s probably no need to use browserify and require any more. It was a non-standard solution to using modules in a time before the JavaScript language had a module system. Now it’s better to use JavaScript modules, which use the import and export keywords and are natively supported by most browsers.

Hi, thank you for your comment. The reason for using browserify is to reduce the need for multiple script tags in the html and also I am using it to require jquery for non 3d elements within the dom.

I am also trying to use tween.js and when I imported it through ES6

import { Easing, Tween, autoPlay } from '../node_modules/es6-tween';

it provides this Error:

Failed to load module script: The server responded with a non-JavaScript MIME type of “text/html”. Strict MIME type checking is enforced for module scripts per HTML spec.

I have also tried to import the specific directory
import { Easing, Tween, autoPlay } from '../node_modules/es6-tween/bundled/Tween.min.js';

But it provides me with this Error:

Uncaught SyntaxError: The requested module ‘…/node_modules/es6-tween/bundled/Tween.min.js’ does not provide an export named 'Tween’

I don’t know why because I checked the tween javascript file and it states these as exports:

exports.Tween = Tween;
exports.Easing = Easing;
exports.autoPlay = autoPlay;
Object.defineProperty(exports, '__esModule', { value: true });

so it should be exporting right? Especially since this is the es6 version of tween.

If you use ES6 modules you will only need a single script tag, although you can include non-module scripts like jquery using additional script tags if you like.

Failed to load module script:

What server are you using?

Taking a quick look at that library, it’s a bit weird they are calling it “ES6” because they are bundling as a UMD (universal module definition) which works for every kind of module except for ES6 modules.

The reason UMD is called universal is because it was created before ES6 modules.

The actual src code is written using ES6 modules though (probably the reason for the name), so you could try importing from es6-tween/src/ directory instead of es6-tween/bundled/. You’ll have to dig around to find where the exports are located.

I don’t think browserify can though, it’s a pretty old tool at this point that I wouldn’t recommend using at all if you can help it.

If you’re finding this stuff confusing BTW, you’re in good company. We’re at an awkward time in JS dev history at the moment as all this require, UMD, browserify stuff existed to bring modules to JavaScript before the language actually supported them. Now that we have real JS modules, we’re trying to move away from the old “fake” modules systems that were created, but we’re stuck with dealing with all the libraries like es6-tween that still use them.

To make your life easier, I recommend using only two techniques: script tags for old libraries like es6-modules and jquery, and ES6 modules with updated libraries like three. Alternatively, if you use something like Webpack or Rollup, they’ll be able to handle importing UMD as ES6 modules, or possibly mixing UMD and ES6 in your code.

See how it’s done in this threejs typescript boilerplate.

It contains a nodejs server. It doesn’t use any bundlers.
It uses completely ES6 import syntax both typescript side and the output client side javascript.

In the boilerplates client.ts script, change line 2 to
import { MapControls } from '/jsm/controls/OrbitControls'

and line 12 to
const controls = new MapControls(camera, renderer.domElement)