Three.js: es6 import three.js

Created on 10 Dec 2016  路  15Comments  路  Source: mrdoob/three.js

Hi! Throw off the template you import three.js in webpack.

Most helpful comment

You're excluding node_modules in babel-loader (so three.modules.js never goes through Babel), and only Webpack 2 supports ES Modules natively, so you need to change either one of those conditions.


Here's a working example for Webpack 2.

application.js:

import {Scene, PerspectiveCamera, WebGLRenderer, BoxGeometry, MeshBasicMaterial, Mesh} from 'three';

const scene = new Scene();
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new BoxGeometry(1, 1, 1);
const material = new MeshBasicMaterial({color: 0x00ff00});
const cube = new Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

function render(){
    requestAnimationFrame(render);
    cube.rotation.x += 0.1;
    cube.rotation.y += 0.1;
    renderer.render(scene, camera);
}

render();

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');


module.exports = {
    target: 'web',
    devtool: 'source-map',
    entry: './src/application.js',
    output: {
        path: path.resolve(__dirname, 'www'),
        filename: 'bundle.js',
        publicPath: ''
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Example',
            filename: 'index.html'
        })
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                include: [
                    path.resolve(__dirname, 'src')
                ],
                loader: 'babel-loader',
                query: {
                    compact: true,
                    presets: [
                        ['es2015', {modules: false}]
                    ]
                }
            }
        ]
    }
};

All 15 comments

import {PerspectiveCamera, ...} from 'three/build/three.modules';

How resolve this error: Unexpected token export ?
webpack config:

...
module: {
  loaders: [
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      loader: 'babel-loader?presets[]=es2015'
    }
  ]
}
...

src file:

import {PerspectiveCamera} from 'three/build/three.modules';

You're excluding node_modules in babel-loader (so three.modules.js never goes through Babel), and only Webpack 2 supports ES Modules natively, so you need to change either one of those conditions.


Here's a working example for Webpack 2.

application.js:

import {Scene, PerspectiveCamera, WebGLRenderer, BoxGeometry, MeshBasicMaterial, Mesh} from 'three';

const scene = new Scene();
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new BoxGeometry(1, 1, 1);
const material = new MeshBasicMaterial({color: 0x00ff00});
const cube = new Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

function render(){
    requestAnimationFrame(render);
    cube.rotation.x += 0.1;
    cube.rotation.y += 0.1;
    renderer.render(scene, camera);
}

render();

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');


module.exports = {
    target: 'web',
    devtool: 'source-map',
    entry: './src/application.js',
    output: {
        path: path.resolve(__dirname, 'www'),
        filename: 'bundle.js',
        publicPath: ''
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Example',
            filename: 'index.html'
        })
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                include: [
                    path.resolve(__dirname, 'src')
                ],
                loader: 'babel-loader',
                query: {
                    compact: true,
                    presets: [
                        ['es2015', {modules: false}]
                    ]
                }
            }
        ]
    }
};

@cecilemuller thanks

how about THREE.Math.degToRad()?

thank you very much @cecilemuller for your example app. Maybe it should be linked somewhere in the documentation?

@v1talM

import { Math } from 'three/build/three.modules'

Math.degToRad();

Keep in mind, there'll be collisions with browser's Math object, so make sure you prefix them with window. window.Math.sqrt(...)

Btw, for quick and dirty drop in module testing, you can do this too:

import * as THREE from 'three/build/three.modules';

new THREE.Mesh....

import {Math as ThreeMath} from 'three/build/three.modules' should also work to avoid name clashes.

Great information, thanks!

I am converting my project to use native es6 modules with no webpack, system.js, babel etc .. just the module's themselves.

This is now possible with all modern browsers except chrome. I'm using Safari Technical Preview for now and it works with my project's modules correctly (yay!).

Is there a way to access the individual module files via the Three CDN?
I.e. I can use

.. but I don't seem to be able to

import Scene from 'https://threejs.org/src/scenes/Scene.js'

How do I import, without webpack etc, the module files themselves? I guess I could just include the node_modules/three/src tree in my own build?

Is there a way to access the individual module files via the Three CDN?

https://threejs.org is not a CDN. Please, do not use it as a CDN...

Rawgit may be the right solution:

https://cdn.rawgit.com/mrdoob/three.js/master/src/scenes/Scene.js

However, I wouldn't recommend doing this either as I may change the files in src around.

Oops: sorry about three.js as CDN, saw it on StackOverflow.
http://stackoverflow.com/questions/23434732/what-is-the-url-for-three-js-to-include-it-online
.

I'll use a local copy or https://cdnjs.com/libraries/three.js/ and leave a
comment there.

However .. would it be reasonable/appropriate to include the src/ module
files in build/? I believe that would allow native module use remotely
(cdnjs, say).

I believe that would allow native module use remotely (cdnjs, say).

I just don't want people to hate me because I moved src folders around.

I just don't want people to hate me because I moved src folders around.

Well, I certainly expect file/directory changes between releases along with moving functionality between files. And I typically setup npm to only use micro changes. But boy do I feel you pain!

So how should we structure our projects? Very little public conversation. This is my favorite insanity:
https://blog.hospodarets.com/native-ecmascript-modules-nomodule

My plan is: I am going to deploy two things: 1) modules/src along with an exporter file like src/Three.js, and 2) a single bundle using rollup built using the exporter file. Like you're doing now, but also deploying the source.

Hope it works. It fits in with the bizarre nomodule proposal: use a module entry

Related issues

zsitro picture zsitro  路  3Comments

danieljack picture danieljack  路  3Comments

seep picture seep  路  3Comments

boyravikumar picture boyravikumar  路  3Comments

jack-jun picture jack-jun  路  3Comments