Enigma22134
Enigma22134

Reputation: 530

How to properly import from gl-matrix.js?

I am coming from a c++ background, so javascript isn't a familiar language. However, I think I've figured out the basics of ES6 module importing/exporting. I'm having a bit of trouble figuring out the exporting syntax in the popular library gl-matrix https://github.com/toji/gl-matrix/blob/master/dist/gl-matrix.js .

I can include gl-matrix.js in my html file and it code works fine within my main.js script. However, I'm trying to use a linter (eslint) within vscode to help guide me in using proper javascript; eslint marks types like vec3 and mat4 as red because they're undefined. I've noticed my other modules are also marked red until I import them.

I've tried things like: import {vec3} from 'gl-matrix.js'; and get the error Uncaught SyntaxError: The requested module 'gl-matrix.js' does not provide an export named 'vec3'

I've also tried import * as vl from 'gl-matrix.js'; and using vl.vec3, but no to luck either. It doesn't appear to me that gl-matrix.js is using the es6 module exporting, but I'm unsure. It is definitely using some export system.

Clicking the github link will take you to the entire gl-matrix.js for viewing, but here is some snippets of the type of exporting it is doing:

(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
        define([], factory);
    else {
        var a = factory();
        for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
    }
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, {
/******/                configurable: false,
/******/                enumerable: true,
/******/                get: getter
/******/            });
/******/        }
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = 4);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setMatrixArrayType = setMatrixArrayType;
exports.toRadian = toRadian;
exports.equals = equals;

It then proceeds to define functions to use. As far as I can tell, WebPack is a way to compose many library js files into a single output file (gl-matrix.js in this case). Perhaps I'm wrong. This being the output file, it seems I should be about to import from it directly.

So really I have multiple questions. Is this some special syntax for ES6 modules? If so, how does one import it?

If it is not, how does one import properly? Is it likely eslint will be able to resolve the symbols and stop flagging them as undefined?

Any help on any of those questions is greatly appreciated.

Upvotes: 4

Views: 7601

Answers (2)

Marius
Marius

Reputation: 1

I did the following:

  • Downloaded the npm version by using npm command in terminal.
  • Copied the entire folder into my projects lib folder.
  • Used import * as glMatrix from "../lib/gl-matrix/esm/index.js";
  • Used the methods as this: glMatrix.mat4.create(); instead of mat4.create();

Thanks gman :)

Upvotes: 0

user128511
user128511

Reputation:

That code you linked to is not in a format to use with es6 modules, it's a UMD format file that predates browsers supporting the import keyword. Browsers only started supporting import natively in early 2019.

If you download the npm version (the built version vs the github version) then there is a file esm/index.js that looks like this

import * as glMatrix from "./common.js";
import * as mat2 from "./mat2.js";
import * as mat2d from "./mat2d.js";
import * as mat3 from "./mat3.js";
import * as mat4 from "./mat4.js";
import * as quat from "./quat.js";
import * as quat2 from "./quat2.js";
import * as vec2 from "./vec2.js";
import * as vec3 from "./vec3.js";
import * as vec4 from "./vec4.js";
export { glMatrix, mat2, mat2d, mat3, mat4, quat, quat2, vec2, vec3, vec4 };

To use the es6 version you can do something like

  • download the source to gl-matrix and manually include them.

    import * as vec3 from 'path/to/vec3.js';
    
  • download the source to gl-matrix, build, copy into your project and then

    import vec3 from 'path/to/build/esm/index.js';
    
  • use npm and an npm aware build step like webpack or rollup

    In that case the libraries are stored in a folder called node_modules in the root of your project and the various tools know how to look inside that folder and you include them by not putting path and using the name you used when adding the library

    import vec3 from 'gl-matrix'
    

    See https://webpack.js.org/guides/getting-started/

    in that example they use a library called lodash and a variable that is a single underscore _ so change lodash to gl-matrix and _ to a variable of your choice like glMatrix

    note: that page assumes you've installed node.js

Upvotes: 6

Related Questions