Browserify: SyntaxError: The keyword 'let' is reserved
<p>Today I was happily typing bits of code into my js app, and frequently building using browserify.
Then <em>all of a sudden</em>, browserify started throwing a weird error. It did no longer like my <code>let</code> declarations (which I have quite a lot of).</p>

<p>Suspecting that it somehow no longer accepted ES6 code, I googled on how to specify the Javascript language version, without luck. No one seemed to have the same error with browserify. I also tried deleting my <code>node_modules</code> folder and doing a clean <code>npm install</code>. No dice.</p>

<p>This is the error I get:</p>

<pre><code>events.js:141
      throw er; // Unhandled 'error' event
      ^

SyntaxError: The keyword 'let' is reserved (119:1) while parsing C:\Users\Jon\Auchitect\frontend\js\cons\designs\plate\BoundedPlane.js while parsing file: C:\Users\Jon\Auchitect\frontend\js\cons\designs\plate\BoundedPlane.js
    at DestroyableTransform.end [as _flush] (C:\Users\Jon\Auchitect\frontend\node_modules\insert-module-globals\index.js:96:21)
    at DestroyableTransform.&lt;anonymous&gt; (C:\Users\Jon\Auchitect\frontend\node_modules\insert-module-globals\node_modules\readable-stream\lib\_stream_transform.js:115:49)
    at DestroyableTransform.g (events.js:260:16)
    at emitNone (events.js:67:13)
    at DestroyableTransform.emit (events.js:166:7)
    at prefinish (C:\Users\Jon\Auchitect\frontend\node_modules\insert-module-globals\node_modules\readable-stream\lib\_stream_writable.js:465:12)
    at finishMaybe (C:\Users\Jon\Auchitect\frontend\node_modules\insert-module-globals\node_modules\readable-stream\lib\_stream_writable.js:473:7)
    at endWritable (C:\Users\Jon\Auchitect\frontend\node_modules\insert-module-globals\node_modules\readable-stream\lib\_stream_writable.js:485:3)
    at DestroyableTransform.Writable.end (C:\Users\Jon\Auchitect\frontend\node_modules\insert-module-globals\node_modules\readable-stream\lib\_stream_writable.js:455:41)
    at DestroyableTransform.onend (C:\Users\Jon\Auchitect\frontend\node_modules\module-deps\node_modules\through2\node_modules\readable-stream\lib\_stream_readable.js:495:10)
npm ERR! Test failed.  See above for more details.
</code></pre>

<p>This is my setup:</p>

<p><strong>package.json:</strong></p>

<pre><code>{
  "name": "frontend",
  "private": true,
  "version": "0.1.0",
  "main": "./js/main.js",
  "directories": {
    "doc": "doc"
  },
  "scripts": {
    "test": "node build_test.js",
    "start": "node build_main.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://loldrup@bitbucket.org/loldrup/auchitect.git"
  },
  "author": "Jon Loldrup",
  "license": "UNLICENSED",
  "homepage": "https://bitbucket.org/loldrup/auchitect#readme",
  "dependencies": {
    "gl-matrix-common": "*",
    "gl-matrix-mat3": "*",
    "ndarray": "*",
    "ndarray-householder-qr": "*",
    "ndarray-matrix-vector-product": "*",
    "ndarray-ops": "*",
    "three": "*",
    "three-orbit-controls": "*"
  },
  "devDependencies": {
    "browserify": "*",
    "qunitjs": "*"
  },
  "browser": {}
}
</code></pre>

<p>I use the <code>build_test.js</code> script when developing. It looks like this:</p>

<pre><code>var browserify = require('browserify');
var fs = require('fs');

var options = {
    basedir: './js/',
    debug: true,
    noParse: ['three', 'qunitjs']
};

var outputFileStream = fs.createWriteStream('./js/test_bundle.js');

var b = browserify('./test.js', options);
b.bundle().pipe(outputFileStream);  // process.stdout
</code></pre>

<p>This is my <code>BoundedPlane.js</code> file:</p>

<pre><code>"use strict";


var THREE = require('three');
var BoundedPlane_prototype = require('./BoundedPlane_prototype');
var utils_mat = require('../../../utils/mat');
var utils_matrix = require('../../../utils/matrix');
require('../../../utils/three/Lin3');
require('../../../utils/three/misc');

// the local (relative) plate index, given an absolute azimuth and polar index entry:
// +--------+--------+--------+
// | plate0 | plate1 | plate2 |
// +--------+--------+--------+
// | plate3 | plate4 | plate5 |
// +--------+--------+--------+
// | plate6 | plate7 | plate8 |
// +--------+--------+--------+


// assumes that the normal vector given as argument is normalized
THREE.BoundedPlane = function ( constant, normal, center, instanceDebug ) {

    THREE.Plane.call(this, normal, constant);

    this.center = center;

    this.normalPoint_vector = this.normal.clone().multiplyScalar(constant);  // this point might at any time be out of sync with this.normal and this.constant. Access only through the this.normalPoint() function.

    this.bindingBPs = [];

    this.boundingPoints = [];

    this.instanceDebug = instanceDebug || false;
};

THREE.BoundedPlane.prototype = BoundedPlane_prototype;
THREE.BoundedPlane.prototype.constructor = THREE.BoundedPlane;
Object.freeze( THREE.BoundedPlane );



THREE.BoundedPlane_from_pivot = function ( pivotLength, lowLeft, upLeft, lowRight, instanceDebug, visualDebug ) {

    if ( instanceDebug ) {
        if ( typeof lowLeft.debug  !== "undefined" ) { console.log( "lowLeft.debug: ",   lowLeft.debug  ); }
        if ( typeof upLeft.debug   !== "undefined" ) { console.log( "upLeft.debug: ",    upLeft.debug   ); }
        if ( typeof lowRight.debug !== "undefined" ) { console.log( "lowRight.debug: ",  lowRight.debug ); }
    }

    var pivotAxis   = new THREE.Lin3( upLeft, lowLeft.clone() ).project_end_to_Vector3( lowRight.sub(upLeft) );
    var pivotLever  = new THREE.Lin3( lowLeft, upLeft.clone() ).reject_end_to_Lin3( pivotAxis );

    var pivotCenter = pivotAxis.end;
    var leverSpan   = pivotLever.length();

    if ( instanceDebug &amp;&amp; typeof lowLeft.debug  !== "undefined" ) { console.log( "pivotCenter: ", pivotCenter ); }

    // put an orthogonal circle with radius 'pivotLength' in lowLeft and find its
    // tangent point by a line intersecting the point 'pivotCenter':
    var center = new THREE.Vector2( 0, 0 );
    var point  = new THREE.Vector2( leverSpan, 0 );
    var radius = pivotLength;

    // get one out of two solutions in a local coordinate system of the plane spanned by the circle:
    var tangentPoint_local_2D = utils_mat.circle_tangent_point( center, radius, point )[1];
    // state the solution in a local 3D basis:
    var tangentPoint_local_3D = new THREE.Vector3( tangentPoint_local_2D.x, 0, tangentPoint_local_2D.y );

    // find the (local) basis vectors that were implicitly used when finding the tangentPoint:
    var b_x = pivotLever.delta().normalize();
    var b_z = pivotAxis.delta().clone().cross( b_x ).normalize();
    var b_y = b_z.clone().cross( b_x ).normalize();

    // convert the solution to the global 3D space:
    var tangentPoint = utils_matrix.changeBasis( tangentPoint_local_3D, b_x, b_y, b_z, true );
    var tangentLine = tangentPoint.sub( pivotLever.delta() );

    var normal = tangentLine.cross( pivotAxis.delta() ).normalize();

    var constant = pivotCenter.clone().projectOnVector( normal ).length();
    if ( utils_mat.vectors_negatively_oriented( pivotCenter, normal ) ) {  // if true, one has to walk the opposite way of the normal, in order to get to the plane
        constant = -1 * constant; }

    THREE.BoundedPlane.call( this, constant, normal, pivotCenter, instanceDebug );

    if ( false &amp;&amp; typeof visualDebug !== 'undefined' &amp;&amp; visualDebug.debug ) {
        // ONLY FOR TESTING!!
        // transform tangentPoint2:
        var tangentPoint2 = utils_matrix.changeBasis( tangentPoint2_local_3D, b_x, b_z, b_y, true);
        // add lowLeft to tangentPoint to make tangentPoint absolute:
        var abs_tangentPoint2 = tangentPoint2.clone().add(lowLeft);
        var tangentLine2 = abs_tangentPoint2.clone().sub(pivotCenter);  // put in THREE.Line and add a ".cross" method to THREE.Line ?
        var pivotAxisVector = upLeft.clone().sub(lowRight);
        var new_normal_inverse = pivotAxisVector.cross(tangentLine2.clone()).normalize();
        console.log( "tangentPoint2: ", tangentPoint2 );
        console.log( "abs_tangentPoint2: ", abs_tangentPoint2 );
        console.log( "normal: ", normal );
        console.log( "new_normal_inverse: ", new_normal_inverse );
        var abs_tangentPoint2_mesh = new THREE.PointHelper(abs_tangentPoint2, 4);
        visualDebug.aScene.add(abs_tangentPoint2_mesh);  //, fixPoint0_res1_mesh
        // also add an axis helper:
        var axisHelper_mesh = new THREE.AxisHelper(50);
        visualDebug.aScene.add(axisHelper_mesh);

        // x = red
        // y = green
        // z = blue
    }
};

THREE.BoundedPlane_from_pivot.prototype = BoundedPlane_prototype;



THREE.BoundedPlane_from_parallel_projection = function ( aBoundedPlane, offset, flip, instanceDebug, visualDebug ) {  // all fixPoint1's (presumably..)

    let normal = aBoundedPlane.normal.clone();
// ***THIS IS LINE 119 ***
    // assumes that the normal vector of 'aBoundedPlane' is already normalized:
    let center = aBoundedPlane.center.clone().add(normal.multiplyScalar(offset));  // which "de-normalizes" normal...

    // so please restore 'normal' after messing with it:
    normal.x = aBoundedPlane.normal.x;
    normal.y = aBoundedPlane.normal.y;
    normal.z = aBoundedPlane.normal.z;

    let constant = aBoundedPlane.constant + offset;

    if ( utils_mat.vectors_negatively_oriented( center, normal ) )  // if true, one has to walk the opposite way of the normal, in order to get to the plane
        { constant = -1 * constant; }

    if ( flip )  { normal.multiplyScalar(-1); constant = -1 * constant; }

    THREE.BoundedPlane.call( this, constant, normal, center, instanceDebug );

};

THREE.BoundedPlane_from_parallel_projection.prototype = BoundedPlane_prototype;



THREE.BoundedPlane_pivoted90_from_twoBPs = function ( mainBP, otherBP, intended_BP_width, instanceDebug, vd ) {
    var constant, normal, center, scalar;

    //if ( typeof vd !== 'undefined' &amp;&amp; vd.debug ) { console.log( "BoundedPlane_pivoted90_from_twoBPs: got visualdebug" ); }

    let intersection = utils_mat.plane_plane_intersection( mainBP, otherBP, false, vd );

    if ( otherBP.point_on_face_side(mainBP.center) ) {
        normal = mainBP.normal.clone().cross( intersection.orientation ).normalize(); }

    else { normal = intersection.orientation.clone().cross( mainBP.normal ).normalize(); }

    center = intersection.point.clone().projectOnVector( normal );  // fixme: remove clone?

    constant = center.length();  // has to happen prior to reflecting the center

    // Ensure that center stays within the intended width of the new BP:
    center.projectOnPlane( mainBP.normal );
    scalar = 1 - ( ( intended_BP_width / 2 ) / mainBP.normalPoint().length() );
    center.add( mainBP.normalPoint().multiplyScalar( scalar ) );
    var rolledBP = new THREE.BoundedPlane_rolled90_from_twoBPs( mainBP, otherBP, instanceDebug, vd );
    center.sub( rolledBP.normalPoint() );

    if ( mainBP.point_strictly_on_face_side( center ) ) {
        center = mainBP.reflect_vector( center ); }

    if ( utils_mat.vectors_negatively_oriented( center, normal ) ) {  // if true, one has to walk the opposite way of the normal, in order to get to the plane
        constant = -1 * constant; }

    THREE.BoundedPlane.call( this, constant, normal, center, instanceDebug );

    if ( typeof vd !== 'undefined' &amp;&amp; vd.debug ) {

        var mainBP_plane   = new vd.THREE.PlaneHelper(  mainBP.normal,  mainBP.center,  10, 2);
        var mainBP_center  = new vd.THREE.VectorHelper( mainBP.center.clone() ).setColor( 0x00ffff );
        var otherBP_plane  = new vd.THREE.PlaneHelper(  otherBP.normal, otherBP.center, 10, 2, 0xff0000, 0xff0000 );
        var otherBP_center = new vd.THREE.VectorHelper( otherBP.center.clone() ).setColor( 0x00ffff );
        var newBP_plane    = new vd.THREE.PlaneHelper(  normal.clone(), center.clone(), vd.size, vd.size/5, vd.color );
        var newBP_normal   = new vd.THREE.VectorHelper( normal.clone() ).setColor( 0xffff00 );
        var newBP_center   = new vd.THREE.VectorHelper( center.clone() ).setColor( 0xff7777 );

        vd.aScene.add( newBP_plane, mainBP_plane, otherBP_plane, /*newBP_normal, newBP_center, mainBP_center, otherBP_center */ );

        // also check out the 'rolled' plane:
        var rolledBP_plane  = new vd.THREE.PlaneHelper(  rolledBP.normal,  rolledBP.center,  10, 2, 0x0055aa);
        var rolledBP_center = new vd.THREE.VectorHelper( rolledBP.center.clone() ).setColor( 0xff00ff );  // lilla
        var rolledBP_normal = new vd.THREE.VectorHelper( rolledBP.normal.clone() ).setColor( 0xff00ff );  // lilla
        var rolledBP_normalPoint = new vd.THREE.VectorHelper( rolledBP.normalPoint.clone() ).setColor( 0xff0077 );
        console.log( "rolledBP: ", rolledBP );
        vd.aScene.add( rolledBP_plane, /*rolledBP_center, rolledBP_normal,*/ rolledBP_normalPoint );

        // also add an axis helper:
        // var axisHelper_mesh = new THREE.AxisHelper(50);
        // vd.aScene.add(axisHelper_mesh);

        // x = red
        // y = green
        // z = blue
    }
};

THREE.BoundedPlane_pivoted90_from_twoBPs.prototype = BoundedPlane_prototype;



THREE.BoundedPlane_pivoted90_from_BP_and_2_Vectors = function ( aBP, v0, v1, intended_BP_width, instanceDebug, visualDebug ) {
    let delta, constant, normalish, normal, center, length, scalar;

    delta = v1.sub(v0);

    normalish = delta.cross(aBP.normal);  // this vector might be pointing the wrong way, depending on the order og args v0 and v1. It also lacks normalization.
    normalish = v0.projectOnVector( normalish );  // this vector removes the ordering uncertainty, but still lacks the normalization.

    constant = normalish.length();

    normal = v1.copy(normalish).normalize();

    center = normalish;

    // Ensure that center stays within the intended width of the new BP:
    center.projectOnPlane( aBP.normal );
    scalar = 1 - ( ( intended_BP_width / 2 ) / aBP.normalPoint().length() );
    center.add( aBP.normalPoint().multiplyScalar( scalar ) );

    // The new plane should bend "backwards" in relation to aBP. Thus planes will, per default, tend to form
    // a closed form. If other behaviour is desired (concave corners?), add a flag that activates this behaviour
    if ( aBP.point_strictly_on_face_side( center ) ) {
        center = aBP.reflect_vector( center ); }

    THREE.BoundedPlane.call( this, constant, normal, center, instanceDebug );

    // we want the normal to point away from the center of 'aBP':
    if ( this.point_on_face_side( aBP.center ) ) {
        this.normal = this.normal.multiplyScalar( -1 );
        this.constant = -1 * this.constant }

};

THREE.BoundedPlane_pivoted90_from_BP_and_2_Vectors.prototype = BoundedPlane_prototype;



THREE.BoundedPlane_rolled90_from_twoBPs = function ( mainBP, otherBP, instanceDebug, vd ) {
    let constant, normal, center;

    center = mainBP.center.clone().add( otherBP.center ).divideScalar( 2 );

    constant = center.length();

    let delta = otherBP.center.clone().sub( mainBP.center );
    let normals_crossed = mainBP.normal.clone().cross( otherBP.normal );  // this vector might be pointing the wrong way, depending on the order of the vectors being crossed
    normal = normals_crossed.clone().normalize();  // fixme: remove clone

    if ( utils_mat.vectors_negatively_oriented( center, normal ) ) {
        normal.multiplyScalar( -1 ) }

    THREE.BoundedPlane.call( this, constant, normal, center, instanceDebug );

    if ( typeof vd !== 'undefined' &amp;&amp; vd.debug ) {
        console.log( "hi" );
        let normals_crossed_vh = new vd.THREE.VectorHelper( normals_crossed ).setColor( 0xaa00aa );  // lilla
        vd.aScene.add( normals_crossed_vh );
    }
};

THREE.BoundedPlane_rolled90_from_twoBPs.prototype = BoundedPlane_prototype;
</code></pre>