hyperknot
hyperknot

Reputation: 13996

How to extend production version of OpenLayers

I am using the production (ol.js) and debug (ol-debug.js) version of OpenLayers 4. The source of these files is the -dist.zip from the releases page (neither npm package was compatible with our browserify workflow).

I am adding a custom tile source, based on ol.source.Zoomify.

The structure of the code is the following (pretty much a clone of Zoomify from ol source code):

var ol = require('openlayers')

var self = (module.exports = {
  Gigapan: function(optOptions) {
    // ...

    var tileGrid = new ol.tilegrid.TileGrid({
      extent: extent,
      origin: ol.extent.getTopLeft(extent),
      resolutions: zoomInfo.resolutions,
    })

    // ...

    ol.source.TileImage.call(this, {
      tileClass: myTile,
      tileGrid: tileGrid,
      tileUrlFunction: gigapanUrlFunction,
    })
  },
})

ol.inherits(self.Gigapan, ol.source.TileImage)

var myTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction) {
  ol.ImageTile.call(this, tileCoord, state, src, crossOrigin, tileLoadFunction)
  this.zoomifyImage_ = null
}

ol.inherits(myTile, ol.ImageTile)

myTile.prototype.getImage = function() {
  // ...
}

This works perfectly with the -debug version, however raises the following exception when using the production version.

ol.js:16 Uncaught TypeError: Cannot read property 'prototype' of undefined
    at Object.v [as inherits] (ol.js:16)
    at Object.43../../../assets/non-npm/openlayers/ol.js (viewerTileFormats.js:168)

which points to the second ol.inherits at ol.inherits(myTile, ol.ImageTile).

What is the problem with this code and how can I extend OL4 in such a way that it's compatible with the production build?

Upvotes: 2

Views: 581

Answers (1)

Alexandre Dubé
Alexandre Dubé

Reputation: 2829

Only the properties that are marked with @api become available in the production build. To be more precise:

The OpenLayers API consists of

  • names and signatures of constructors
  • names and signatures of instance methods and properties
  • names and signatures of functions
  • names of constants

http://openlayers.org/en/v4.6.5/apidoc/

So, if you're trying to extend or use a property that's not marked as api, it can't be used in the production version.

There are ways to accomplish what you want, however.

(1) Build OpenLayers alongside your code

You can use Closure Compiler to build your code alongside OpenLayers. This is explained in this tutorial. That way, you can access any property that's not private and extend it as you please. Also, you gain the benefit of having your code minimized and "checked" (for errors) as well, which is pretty cool.

Edit Works up to the version 4.6.5 of OpenLayers.

(2) Fork OpenLayers

If the property you want to use / extend is private or can't be reached, you could still fork OpenLayers, apply your own fix to make what you want available (marking them as @api, for example) and produce your own customized production version.

Regardless of what you choose to do, don't hesitate to look at the source code of OpenLayers itself. If a property is not marked as @api, consider it "not available" for the default JS packaged with the official versions of OpenLayers.

Upvotes: 2

Related Questions