You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
7.0 KiB
258 lines
7.0 KiB
2 years ago
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<base href="../../../" />
|
||
|
<script src="page.js"></script>
|
||
|
<link type="text/css" rel="stylesheet" href="page.css" />
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>[name]</h1>
|
||
|
|
||
|
<p class="desc">
|
||
|
This article shows how to get three.js into a [link:https://nodejs.org/en/ node.js] environment so that you
|
||
|
can execute automated tests. Tests can be run on the command line, or by automated
|
||
|
CI tools like [link:https://travis-ci.org/ Travis].
|
||
|
</p>
|
||
|
|
||
|
<h2>The short version</h2>
|
||
|
|
||
|
<p>
|
||
|
If you're comfortable with node and npm,
|
||
|
<code>
|
||
|
$ npm install three --save-dev
|
||
|
</code>
|
||
|
and add
|
||
|
<code>
|
||
|
const THREE = require('three');
|
||
|
</code>
|
||
|
to your test.
|
||
|
</p>
|
||
|
|
||
|
<h2>Create a testable project from scratch</h2>
|
||
|
<p>
|
||
|
If you're not familiar with these tools, here's a quick guide (for linux, the installation process
|
||
|
will be slightly different using windows, but the NPM commands are identical).
|
||
|
</p>
|
||
|
|
||
|
<h3>Basic setup</h3>
|
||
|
<div>
|
||
|
<ol>
|
||
|
<li>
|
||
|
Install [link:https://www.npmjs.org/ npm] and nodejs. The shortest path typically looks something like
|
||
|
<code>
|
||
|
$ sudo apt-get install -y npm nodejs-legacy
|
||
|
# fix any problems with SSL in the default registry URL
|
||
|
$ npm config set registry http://registry.npmjs.org/
|
||
|
</code>
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Make a new project directory
|
||
|
<code>
|
||
|
$ mkdir test-example; cd test-example
|
||
|
</code>
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Ask npm to create a new project file for you:
|
||
|
<code>
|
||
|
$ npm init
|
||
|
</code>
|
||
|
and accept all defaults by hitting Enter on all the prompts.
|
||
|
This will create package.json.
|
||
|
</li><br />
|
||
|
|
||
|
<li>
|
||
|
Try and start the test feature with
|
||
|
<code>
|
||
|
$ npm test
|
||
|
</code>
|
||
|
This will fail, which is expected.
|
||
|
If you look in the package.json, the definition of the test script is
|
||
|
<code>
|
||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||
|
</code>
|
||
|
</li>
|
||
|
|
||
|
</ol>
|
||
|
</div>
|
||
|
|
||
|
<h2>Add mocha</h2>
|
||
|
<div>
|
||
|
We're going to use [link:https://mochajs.org/ mocha].
|
||
|
|
||
|
<ol>
|
||
|
<li>
|
||
|
Install mocha with
|
||
|
<code>
|
||
|
$ npm install mocha --save-dev
|
||
|
</code>
|
||
|
Notice that node_modules/ is created and your dependencies appear in there.
|
||
|
Also notice that your package.json has been updated: the property devDependencies
|
||
|
is added and updated by the use of --save-dev.
|
||
|
</li><br />
|
||
|
|
||
|
<li>
|
||
|
Edit package.json to use mocha for testing. When test is invoked, we just want to run
|
||
|
mocha and specify a verbose reporter. By default this will run anything in test/
|
||
|
(not having directory test/ can run into npm ERR!, create it by mkdir test)
|
||
|
<code>
|
||
|
"test": "mocha --reporter list"
|
||
|
</code>
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Rerun the test with
|
||
|
<code>
|
||
|
$ npm test
|
||
|
</code>
|
||
|
|
||
|
This should now succeed, reporting 0 passing (1ms)
|
||
|
or similar.
|
||
|
</li>
|
||
|
|
||
|
</ol>
|
||
|
</div>
|
||
|
|
||
|
<h2>Add three.js</h2>
|
||
|
<div>
|
||
|
<ol>
|
||
|
<li>
|
||
|
Let's pull in our three.js dependency with
|
||
|
<code>
|
||
|
$ npm install three --save-dev
|
||
|
</code>
|
||
|
<ul>
|
||
|
<li>
|
||
|
If you need a different three version, use
|
||
|
<code>
|
||
|
$ npm show three versions
|
||
|
</code>
|
||
|
to see
|
||
|
what's available. To tell npm the right one, use
|
||
|
<code>
|
||
|
$ npm install three@0.84.0 --save
|
||
|
</code>
|
||
|
(0.84.0 in this example). --save makes this a dependency of this project, rather than
|
||
|
dev dependency. See the docs [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json here] for more info.
|
||
|
</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Mocha will look for tests in test/, so let's
|
||
|
<code>
|
||
|
$ mkdir test
|
||
|
</code>
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Finally we actually need a JS test to run. Let's add a simple test that will verify that
|
||
|
the three.js object is available and working. Create test/verify-three.js containing:
|
||
|
<code>
|
||
|
const THREE = require('three');
|
||
|
const assert = require('assert');
|
||
|
|
||
|
describe('The THREE object', function() {
|
||
|
it('should have a defined BasicShadowMap constant', function() {
|
||
|
assert.notEqual('undefined', THREE.BasicShadowMap);
|
||
|
}),
|
||
|
|
||
|
it('should be able to construct a Vector3 with default of x=0', function() {
|
||
|
const vec3 = new THREE.Vector3();
|
||
|
assert.equal(0, vec3.x);
|
||
|
})
|
||
|
})
|
||
|
</code>
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Finally let's test again with $ npm test. This should run the tests above and succeed,
|
||
|
showing something like:
|
||
|
<code>
|
||
|
The THREE object should have a defined BasicShadowMap constant: 0ms
|
||
|
The THREE object should be able to construct a Vector3 with default of x=0: 0ms
|
||
|
2 passing (8ms)
|
||
|
</code>
|
||
|
</li>
|
||
|
</ol>
|
||
|
</div>
|
||
|
|
||
|
<h2>Add your own code</h2>
|
||
|
<div>
|
||
|
You need to do three things:
|
||
|
|
||
|
<ol>
|
||
|
<li>
|
||
|
Write a test for the expected behaviour of your code, and place it under test/.
|
||
|
[link:https://github.com/air/encounter/blob/master/test/Physics-test.js Here] is an example from a real project.
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Export your functional code in such a way that nodejs can see it, for use in conjunction with require.
|
||
|
See it [link:https://github.com/air/encounter/blob/master/js/Physics.js here].
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Require your code into the test file, in the same way we did a require('three') in the example above.
|
||
|
</li>
|
||
|
</ol>
|
||
|
|
||
|
<p>
|
||
|
Items 2 and 3 will vary depending on how you manage your code. In the example of Physics.js
|
||
|
given above, the export part is right at the end. We assign an object to module.exports:
|
||
|
</p>
|
||
|
<code>
|
||
|
//=============================================================================
|
||
|
// make available in nodejs
|
||
|
//=============================================================================
|
||
|
if (typeof exports !== 'undefined')
|
||
|
{
|
||
|
module.exports = Physics;
|
||
|
}
|
||
|
</code>
|
||
|
</div>
|
||
|
|
||
|
<h2>Dealing with dependencies</h2>
|
||
|
<div>
|
||
|
<p>
|
||
|
If you're already using something clever like require.js or browserify, skip this part.
|
||
|
</p>
|
||
|
<p>
|
||
|
Typically a three.js project is going to run in the browser. Module loading is hence done by
|
||
|
the browser executing a bunch of script tags. Your individual files don't have to worry
|
||
|
about dependencies. In a nodejs context however, there is no index.html binding everything
|
||
|
together, so you have to be explicit.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you're exporting a module that depends on other files, you're going to have to tell node to load them.
|
||
|
Here is one approach:
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li>
|
||
|
At the start of your module, check to see if you're in a nodejs environment.
|
||
|
</li>
|
||
|
<li>
|
||
|
If so, explicitly declare your dependencies.
|
||
|
</li>
|
||
|
<li>
|
||
|
If not, you're probably in a browser so you don't need to do anything else.
|
||
|
</li>
|
||
|
</ol>
|
||
|
Example code from Physics.js:
|
||
|
<code>
|
||
|
//=============================================================================
|
||
|
// setup for server-side testing
|
||
|
//=============================================================================
|
||
|
if (typeof require === 'function') // test for nodejs environment
|
||
|
{
|
||
|
const THREE = require('three');
|
||
|
const MY3 = require('./MY3.js');
|
||
|
}
|
||
|
</code>
|
||
|
</div>
|
||
|
|
||
|
</body>
|
||
|
</html>
|