When asset-pipeline generates asset relative URLs it assumes it is relative to the server and not to the currently opened URL.
Assumptions
I'm using asset-pipeline though grails. Adjust accordingly if you use other projects.
I don't want to use and configure grails.assets.url. Each application is standalone and does not use a CDN.
Observations
Grails 2.x context path defaults to /$applicationName
Grails 3.x context path defaults to /
Problem
Using grails 3.x, suppose you are accessing your applications through a gateway (e.g. traefik) and are configuring the gateway to use context paths to distinguish applications (e.g. http://example.com/app1/, http://example.com/app2/; in traefik PathPrefixStrip: /app1) and not DNS approach (e.g. http://app1.example.com, http://app2.example.com). Then:
in app1
deployed (e.g. via docker) as http://ip:port/
but accessible from the outside world as http://example.com/app1/
using <asset:javascript src="app.js">
generated URL is /app.js
But from the outside, there is no such asset http://example.com/app.js. It should actually be http://example.com/app1/app.js. So the problem is that currently asset-pipeline makes assumptions as to how the application will be deployed and made accessible to the outside world.
Current workarounds
use grails.assets.url and define the absolute URL where resources are located for each application and for each deployment (dev, staging, testing, production, etc.)
in grails 3.x, define server.contextPath = '/app1' in grails-app/conf/application.groovy (or application.yml equivalent). In traefik: PathPrefix: /app1. This equates the two context paths: context path of app deployed in a docker container == context path of where the application is available to the outside world. In this case, asset-pipeline generates /app1/app.js.
Solution?
I was wondering if this would be a good direction to take asset-pipeline... If instead of generating /app.js URL, it generated app.js, then it would be relative to the currently opened URL. Basically <script src="app.js"> in the browser that is currently visiting http://example.com/app1/ translates to http://example.com/app1/app.js.
When asset-pipeline generates asset relative URLs it assumes it is relative to the server and not to the currently opened URL.
Assumptions
grails.assets.url
. Each application is standalone and does not use a CDN.Observations
/$applicationName
/
Problem
Using grails 3.x, suppose you are accessing your applications through a gateway (e.g. traefik) and are configuring the gateway to use context paths to distinguish applications (e.g.
http://example.com/app1/
,http://example.com/app2/
; in traefikPathPrefixStrip: /app1
) and not DNS approach (e.g.http://app1.example.com
,http://app2.example.com
). Then:app1
http://ip:port/
http://example.com/app1/
<asset:javascript src="app.js">
/app.js
But from the outside, there is no such asset
http://example.com/app.js
. It should actually behttp://example.com/app1/app.js
. So the problem is that currently asset-pipeline makes assumptions as to how the application will be deployed and made accessible to the outside world.Current workarounds
grails.assets.url
and define the absolute URL where resources are located for each application and for each deployment (dev, staging, testing, production, etc.)server.contextPath = '/app1'
ingrails-app/conf/application.groovy
(orapplication.yml
equivalent). In traefik:PathPrefix: /app1
. This equates the two context paths: context path of app deployed in a docker container == context path of where the application is available to the outside world. In this case, asset-pipeline generates/app1/app.js
.Solution?
I was wondering if this would be a good direction to take asset-pipeline... If instead of generating
/app.js
URL, it generatedapp.js
, then it would be relative to the currently opened URL. Basically<script src="app.js">
in the browser that is currently visitinghttp://example.com/app1/
translates tohttp://example.com/app1/app.js
.Code
I was looking at the code. I think it's these are the relevant lines, right? https://github.com/bertramdev/asset-pipeline/blob/rel-3.0.10/asset-pipeline-grails/src/main/groovy/asset/pipeline/grails/AssetProcessorService.groovy#L133-L136.