Reputation: 1572
I want to build an Angular 5 app once, and then publish it to different addresses, for example to:
By default, Angular will assume that all files are hosted in / so when i access index.html, it will load scripts such as https://sub1.example.com/vendor.bundle.js which will 404 because it's deploy to /myapp1/vendor.bundle.js (to make it slightly more complex, I'm actually loading the files from a CDN from a separate domain, but I don't think this affects the question):
Angular 5 allows me to run:
ng build --deploy-url "https://example.com/myapp1"
This will modify the inline.bundle.js and set the following:
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "https://example.com/myapp1";
This in turn will make sure that scripts are loaded from the proper path.
However, this is a compile time switch, and I want to configure this either at deploy-time or at runtime.
I've read various suggestions, such as:
My current workaround is to update the variable __webpack_require__.p at deploy-time, but this is extremly error-prone since this variable at this point is minimized to something like "n.p" and relying on an internal implementation detail.
What would be the proper approach to do this?
Upvotes: 3
Views: 2684
Reputation: 76
Setting the deployUrl setting in .angular-cli.json, or passing in the --deploy-url to the build command does 2 things. It makes sure that the script includes in the index.html file are using that as the base, and it sets a variable that makes sure that webpack adds that as the "base path" for any lazy loaded modules. That much we agree on I guess, and figuring out where to load the scripts from in the html is pretty simple. However, setting the path that webpack should use is a bit more tricky... The value used by webpack is not named __webpack_public_path__ as mentioned in the linked suggestion and in the documentation.
You even mention the solution yourself when you say that setting the --deploy-url causes the following
__webpack_require__.p = "https://example.com/myapp1";
So, instead of setting the __webpack_public_path__ at runtime, as mentioned explained in the documentation, you have to set the __webpack_require__.p property.
The easiest way to do this is to just set it in the app.module.ts file. Doing something like this should work in your scenario
<script>
window.config = { basePath: 'https://sub1.example.com/myapp1' }
</script>`
// imports etc...
declare var __webpack_require__: any;
declare var config;
__webpack_require__.p = window.config.basePath;
@NgModule({})
...
This will make sure that the __webpack_require__.p property is set to the configured value on load.
In this case I just added the configured value as a config variable on the window object, but you can fetch it from wherever you want. And to keep it simple, I just assumed the value would always be there... You might want to have a fallback in case the config object isn't available, or the basePath property isn't set.
Upvotes: 6