The javascript at https://jsfiddle.net/nsands/kvhcuL72/ is the simplest demonstration I've come up with for this issue. It is based on OpenLayers example code, but I've defined the map projection using proj4js.
It works fine for my custom EPSG:28355 projection, but it does not work for my custom EPSG:4326 projection, which results in an empty map. The projection is correct according to https://epsg.io/4326.
Below are the two proj4.defs()
lines from the jsfiddle.
This first one works fine and OpenLayers reprojects (warps) the OSM map (EPSG:3857) to EPSG:28355 no problems:
// EPSG:28355
proj4.defs('BLAH', '+proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
(It does take a little time for the map to appear, as warping rasters is not a super-fast process.)
This second one does not work and results in an empty white map:
// EPSG:4326
proj4.defs('BLAH', '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs');
If I use the already built-in EPSG:4326, instead of my own custom defined one, it also works just fine and reprojects the map perfectly. In the jsfiddle, this can be tested by changing which of the projection:
lines is uncommented in the map's view definition.
Why does my custom definition of EPSG:4326 not work in my OpenLayers code, even though the built in EPSG:4326 and my custom EPSG:28355 both work fine?
I assume I'm using the libraries incorrectly, or perhaps assuming functionality that does not exist. But from the documentation I've seen, I had expected it to work.
(I'm using a custom definition of EPSG:4326 because in my real OpenLayers app, the projection is determined at run-time and the EPSG code may not be available, even then - only the proj4 string. Therefore I cannot hard-code the projection in the javascript, and I need to be able to work without an EPSG code. It needs to work for whatever projection is passed in, including the proj4 string for EPSG:4326.)
UPDATE - Documentation:
I had been under the impression that OpenLayers could simply use proj4js defined projections. Although the OL documentation is not entirely clear on this, I had got this impression from several 3rd party examples, from the snippets of OpenLayers documentation below, AND because it appears to work fine in my JSFiddle linked in the first line of this post above.
From the OpenLayers Example's comments in the code at https://openlayers.org/en/latest/examples/wms-image-custom-proj.html :
If you use Proj4js only to transform coordinates, you don't even need to create an ol.proj.Projection instance. ol.proj.get() will take care of it internally.
From the OpenLayers API documentation at https://openlayers.org/en/latest/apidoc/ol.proj.html :
[OpenLayers] will check if the Proj4js library and the necessary definition are loaded; if so, it will register the appropriate ol.proj.Projection object and add transform functions between the new projection and all the existing ones.
From the OpenLayers API documentation at https://openlayers.org/en/latest/apidoc/ol.proj.Projection.html :
You can use [ol.proj.Projections] in applications, but this is not required, as API params and options use ol.ProjectionLike which means the simple string code will suffice. ... If you use proj4js, aliases can be added using proj4.defs()