Deploying Vue.JS Single Page App to multiple environments-- how?



  • I'm finally fixing our Vue.JS front-end app deploy story, and I have a simple question that so far I haven't found an answer for.

    In most programming environments, PHP, C#, Java, you can code your application to read its configuration from a file on the system it gets deployed to. For example, in .NET you can put your config in the web.config XML to be consumed by the app. This is a best practice because it ensures the copy you QA on your development server is the same copy (the same exact bits as an old manager of mine used to say) that gets deployed to production.

    But in a JavaScript SPA, there's no way to have it configure itself without changing its own source code (aka I can't replace the URL to the API its supposed to talk to without changing the code of the app itself).

    The simple question is this: how do front-end developers do this? So far my only thought is to do a find-and-replace for the API URL and make a build step that actually changes the JS file, but this is giving me the heebie-jeebies up my spine, and I'm sure there has to be a better way, right?

    Weng suggested having the JS file read a JSON configuration (which could be at a relative path but not part of the deploy, so that each server has its own JSON), but then you're delaying the app execution until two files have been fetched from the web server, and also you're doubling the odds that a user will see a blank site due to a failed HTTP connection. (Which happens even on good networks 0.25-0.5% of the time, by our measurements.) So, again, there has to be a better way, right?

    I need to know the better way. Front-end devs, come to my aid!

    If it helps, the app is written in Vue.JS and deployed using Visual Studio Team Services.



  • That's a good question. I usually put the URL in a <link id="some-special-id" /> in the same document, then have the JS code read it from there at startup. The URL itself gets either baked in through a build step, or rendered by the server from a config file.



  • @DCoder With Vue.JS that just moves the problem one step-- it does generate an index.html of course where that could be added, but then distributing it would require changing index.html which similarly gives me the heebie-jeebies.

    I guess the question is: is there a way to deploy a JavaScript SPA app to a new server without changing any of the source code of the app?


  • :belt_onion:

    The way I've always done it is to have the environment the SPA is bootstrapped into provide all the configuration. Basically, instead of the entry point looking like this;

    (function() {
      // Get the DOM node, talk to the server, render some HTML, add some listeners, etc.
    })();
    

    it looks like this:

    (function() {
      var CONFIG = window.MY_APP_CONFIG;
      // Get the DOM node, talk to the server, render some HTML, add some listeners, etc.
      // using CONFIG where I have environment-varying configuration.
    })();
    

    Now this assumes that your server-code can be driven by configuration, otherwise (as you note) you've just moved the problem from JS to HTML (or C#, or PHP, or whatever). But most likely something in your stack can consume configuration already, so pushing the read-config-spit-out-data stage to the server lets you bootstrap the SPA without an extra server round-trip and without changing the source code of either the JS or the server.



  • @svieira Hm all we got is a huge-ass MVC app and I'd rather not put it in charge of this if I can avoid it. (For many reasons, but one important one being so I can put this Vue.JS front end on its own server.)

    How is it possible this situation still sucks so much? Nobody involved in JS front-end development has attempted to fix this yet?


  • :belt_onion:

    @blakeyrat - the basic problem is that you want to read your configuration from somewhere synchronously or at least "not at Network I/O" speeds. That means that it either has to be embedded in the downloaded code (e. g. not byte-for-byte compatible across environments) or else it's got to be served up by something else.

    Now, that said, you might be able to use a Service Worker at a fixed relative URL to provide the configuration instead and have every load except the very first one be fast ... 🤔

    // Waves hands furiously
    (function() {
      // Find script tag loading us
      // Replace last `/` with `/my-config-providing-service-worker.js`
      // Register service worker
      // Listen for postMessage event with remaining configuration
      window.addEventListener('message', e => {
        var CONFIG = e.data;
        // Get the DOM node, talk to the server, render some HTML, add some listeners, etc.
        // using CONFIG where I have environment-varying configuration.
      });
    })();
    

  • :belt_onion:

    Or even just a cached config.js file ... but the service worker lets you change the contents of the configuration and at least get the new configuration on the next reload of the page (as opposed to Cache-Control: immutable which sticks you with the same configuration forever.)



  • @svieira What about an old fashioned tech like Server Side Includes/SHTML?

    I frankly don't know what a service worker is.


  • :belt_onion:

    @blakeyrat - that would absolutely work too, and if that's an acceptable solution in your case, I'd go for it (I had excluded anything like that because then the app isn't byte-for-byte compatible as it ships with its configuration rather than alongside it. It just doesn't actually become the app until run-time :-D )


  • :belt_onion:

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    I frankly don't know what a service worker is.

    It's a way of having a persistent JS process hang around for a website even if the website cannot be reached (because the network is unavailable). It's the new lower-level version of AppCache (which is deprecated), which is in itself an attempt to make it easier to build a website / web app with long-term cached assets without shooting yourself in the foot when you need to change ./sub-page.js.

    See also: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers



  • Last time I've had to do something like this, I wrote a teeny tiny asp.net mvc site to host my application in, and I built an HtmlHelper which would read the necessary settings from web.config and dump them as a JSON object. Depending on your workflow this could also work for you.

    Alternatively, maybe you could do some magic during deployment to change index.html to Default.aspx and to then inject some code to read settings and build a JSON object. You don't need code behind in an .aspx file after all :)



  • @blakeyrat What you want to do is generally not done.

    Any deployment I've ever seen basically hardcodes all the settings at compile time and then just deploys the bundle that way, without any configuration files. Since this bundle will generally get CDN-ed and cached, it is not advisable to have any changeable files packaged with it anyway.

    If you want a separate build for the staging, then you make a build for staging. I guess there is slight chance that production configuration might be wrong and staging might not catch that, but you'll get the same problem if you edit your config file by hand too.

    If you really insist on using the exact same bundle in staging and production, I guess you can put it in a docker and then map reverse-proxy endpoints to production/staging API? Dunno, this is just not done for frontend SPA-s in my experience.


  • :belt_onion:

    @cartman82 My reading of the thread indicates @blakeyrat understands it's generally not done but disagrees with the way it's generally done. And that's fine because that's the only way you find something better. Personally I think @blakeyrat has the right idea given the rise in containerization, in which an image is supposed to be immutable.

    My last project used the "Go get a JSON file (from Spring Cloud Config)" method. Spring Cloud Config allowed us to have config files in a number of formats (we used YAML), have layers (e.g. we had "common config" then env config), and serve in a number of formats. It would refresh regularly from Git then apps would refresh from it. It was really good for configuration management, but I suspect it was a higher-weight solution than most would prefer.



  • @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    What you want to do is generally not done.

    Yeah but why not?

    So you have a QA server and a production server. You put the code on QA, do all kinds of testing, yay it seems to work, now it's time to put the code on production-- but you're putting up different code on production. ... well shit! You've just invalidated your entire QA effort, didn't you?

    The other problem is of course I'm working within the confines of VSTS which assumes a build, once built, is immutable and it has no concept of "doing a new build for a deploy". You build once, ever, and deploy multiple times. (And frankly, good for VSTS-- it has the right idea and is doing the right thing-- it's not VSTS's fault that the JS community still has no fix for this simple problem!)

    So far all of these solutions frankly kind of suck. I'm leaning towards doing the simple "search and replace on deploy" method (fortunately VSTS is flexible enough to let you run arbitrary PowerShell during deploy), but goddamn... seriously? It's 2018, it feels like I'm using sticks and rocks to build a space shuttle.

    The second best solution is to have the JS load a JSON config file on first-run, but that makes an already-fragile app even more fragile.

    @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    If you really insist on using the exact same bundle in staging and production, I guess you can put it in a docker and then map reverse-proxy endpoints to production/staging API? Dunno, this is just not done for frontend SPA-s in my experience.

    That adds a shitload of complexity compared to pretty much every other idea in this thread.

    @heterodox said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @cartman82 My reading of the thread indicates @blakeyrat understands it's generally not done but disagrees with the way it's generally done. And that's fine because that's the only way you find something better. Personally I think @blakeyrat has the right idea given the rise in containerization, in which an image is supposed to be immutable.

    It's more like, "this is how it's done in literally every single other language, even really shitty ones like PHP and oh by the way it's a really good and smart way of doing things, how do I do it in JavaScript?"



  • @svieira said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Now, that said, you might be able to use a Service Worker at a fixed relative URL to provide the configuration instead and have every load except the very first one be fast ...

    BTW I know I'm backing up 9 hours in this conversation but the real concern isn't "fast" (although that is a concern), the real concern is "reliability". HTTP requests have a decently high failure rate, and in this case when it fails the app does jack shit-- it just shows a blank window with no real way to recover. (That I'm aware of at least, I'm brand new to Vue.JS.)

    I think most front end developers have never bothered to measure the failure rate of HTTP requests, and have no idea that they hover around half a percentage or so. At least based on my consumption of front-end apps, which all seem to inevitably break if one single file doesn't end up downloaded correctly.

    So if my app relies on 3 HTTP requests (index.html, site.js, config.json) instead of 2, it's a third more likely to fail on load. And it's already way more likely to fail on load, just because of the vagaries of the HTTP protocol, than I'd like it to be.


  • :belt_onion:

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    It's more like, "this is how it's done in literally every single other language, even really shitty ones like PHP

    There are a decent number of PHP applications that load config.inc.php or whatever on startup. Pretty much the same thing ("changing source"). Lazy developers exist in every language.


  • area_pol

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    So if my app relies on 3 HTTP requests (index.html, site.js, config.json) instead of 2, it's a third more likely to fail on load. And it's already way more likely to fail on load, just because of the vagaries of the HTTP protocol, than I'd like it to be.

    If that is a concern in your case, you can put inline js into index.html which retries the other requests until success.



  • @heterodox said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    There are a decent number of PHP applications that load config.inc.php or whatever on startup. Pretty much the same thing ("changing source"). Lazy developers exist in every language.

    That's fine; you just exclude config.inc.php from your deploy. In fact, that's exactly what I want here: the configuration to be kept in a static location on the server (Web.config, a JSON file, hell-- anywhere!), outside of the deployed code.



  • @Adynathos said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    If that is a concern in your case, you can put inline js into index.html which retries the other requests until success.

    Yeah like all those desktop apps that have to put in all that retry logic in case their .dll files don't load.

    ... front end development is really a cesspool, isn't it? Sigh. Oh well.



  • @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Yeah but why not?

    So you have a QA server and a production server. You put the code on QA, do all kinds of testing, yay it seems to work, now it's time to put the code on production-- but you're putting up different code on production. ... well shit! You've just invalidated your entire QA effort, didn't you?

    The other problem is of course I'm working within the confines of VSTS which assumes a build, once built, is immutable and it has no concept of "doing a new build for a deploy". You build once, ever, and deploy multiple times. (And frankly, good for VSTS-- it has the right idea and is doing the right thing-- it's not VSTS's fault that the JS community still has no fix for this simple problem!)

    This all sounds like a very theoretical problem. I can't think of a way changing the API url and some keys can have negative effect on the code itself.

    So far all of these solutions frankly kind of suck. I'm leaning towards doing the simple "search and replace on deploy" method (fortunately VSTS is flexible enough to let you run arbitrary PowerShell during deploy), but goddamn... seriously? It's 2018, it feels like I'm using sticks and rocks to build a space shuttle.

    The second best solution is to have the JS load a JSON config file on first-run, but that makes an already-fragile app even more fragile.

    Search and replace will work for API url, but it's fragile for maintenance. What if you start increasing the number of options you need to regexp and some of those are less distinctive than URL-s?

    Loading a js <script> file that sets something like window.CONFIG is better, but then you have even less confidence your staging will work the same as production.

    The most "correct" solution would be that both your staging and production target the same reverse-proxy, which then splinters traffic based on origin or similar. But once again, you then have a situation where staging can influence production, and vice versa.

    Just compile two freaking bundles.



  • @heterodox said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @cartman82 My reading of the thread indicates @blakeyrat understands it's generally not done but disagrees with the way it's generally done. And that's fine because that's the only way you find something better. Personally I think @blakeyrat has the right idea given the rise in containerization, in which an image is supposed to be immutable.

    For your frontend code, you want it to be super easy to deploy and copy to different places. Having some kind of configuration overlay seems like more trouble than it's worth.



  • @heterodox said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    It's more like, "this is how it's done in literally every single other language, even really shitty ones like PHP

    There are a decent number of PHP applications that load config.inc.php or whatever on startup. Pretty much the same thing ("changing source"). Lazy developers exist in every language.

    Also the little detail that deploying backend code isn't the same as deploying frontend SPA.



  • @blakeyrat Oh, your index.html is autogenerated, that's ass. I usually do this like @AlexMedia said, by building the HTML at deploy time or even at runtime instead of build time. But I have no idea what specific HTML would be needed for your bundle to load and run, it probably involves magic shit like cachebusting URLs and whatnot. Frontend does suck.



  • @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    This all sounds like a very theoretical problem. I can't think of a way changing the API url and some keys can have negative effect on the code itself.

    I'm a software engineer. I want my shit to be correct. Not "correct if..." or "correct assuming that you..." just plain correct.

    If I test X, if I check-out on X, I want to make sure that the production server has X. Not "X but after a find and replace", but X.

    @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Also the little detail that deploying backend code isn't the same as deploying frontend SPA.

    I don't care that it's different, I care that it's worse.

    This is a problem that every back-end web development environment has solved. Even the shitty ones like PHP.



  • @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Search and replace will work for API url, but it's fragile for maintenance. What if you start increasing the number of options you need to regexp and some of those are less distinctive than URL-s?

    Why not just insert some code defining a few globals at the beginning of the file?


  • kills Dumbledore

    @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Search and replace will work for API url, but it's fragile for maintenance. What if you start increasing the number of options you need to regexp and some of those are less distinctive than URL-s?

    Ideally, you'd have the search and replace go from something standard that you control, like ~~APIEndpoint~~ or something, and replaced in every environment



  • @Jaloopa said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Ideally, you'd have the search and replace go from something standard that you control, like APIEndpoint or something, and replaced in every environment

    Yeah but then LOCAL testing is a nightmare of annoyance.


  • kills Dumbledore

    @blakeyrat It's bullshit all the way down



  • @Jaloopa said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @blakeyrat It's bullshit all the way down

    Sure seems like it.

    Today I'm going to drive into work and make a rule on the Dev deploy that says "find https://localhost:xxx/api and replace with dev.product.com/api" and I'll feel bad about it but.


  • ♿ (Parody)

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    So you have a QA server and a production server. You put the code on QA, do all kinds of testing, yay it seems to work, now it's time to put the code on production-- but you're putting up different code on production. ... well shit! You've just invalidated your entire QA effort, didn't you?

    I don't see any significant difference here between deploying with separate config files and including the config file in the source based on where you're deploying.



  • @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @cartman82 said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    This all sounds like a very theoretical problem. I can't think of a way changing the API url and some keys can have negative effect on the code itself.

    I'm a software engineer. I want my shit to be correct. Not "correct if..." or "correct assuming that you..." just plain correct.

    There is no strict boundary between code and configuration. When you change configuration from staging to production, it can still surface a bug that was not observed in staging. So you don't ever eliminate change altogether, you always only minimise it.

    If I test X, if I check-out on X, I want to make sure that the production server has X. Not "X but after a find and replace", but X.

    I do agree that find&replace is a risky tool for the job though.

    I can see basically three options:

    1. Include the settings as a separate .js file at fixed relative address via <link> in the index.html. The script will simply set window.CONFIG or something like that. If you can make the framework inject a line there, it is probably the easiest. Disadvantage is that you are relying on the browser to load it.
    2. Load the config from a .json file at fixed relative address. Disadvantage is that it takes a bit of programming, but you can implement retries.
    3. Concatenate the settings with the bundle. Javascript files are just sequences of statements, so you can bundle them by simply concatenating. That eliminates the extra request, it isn't search&replace and you can do it with the deploy script or server-side includes.


  • @Bulb said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Concatenate the settings with the bundle. Javascript files are just sequences of statements, so you can bundle them by simply concatenating. That eliminates the extra request, it isn't search&replace and you can do it with the deploy script or server-side includes.

    Interesting, but the string has to be in the JS Module that does the AJAX request, so I'm not sure how this could work.

    I guess you could concatenate a file that just says window.apiRequestURL = "blah", then have the module read from the window namespace? Meh.



  • @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    string has to be in the JS Module that does the AJAX request

    Why? If it was a config file, it wouldn't be there – it would be in the config file.

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    I guess you could concatenate a file that just says window.apiRequestURL = "blah", then have the module read from the window namespace?

    That's what I mean, yes.



  • @Bulb said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Why? If it was a config file, it wouldn't be there – it would be in the config file.

    Vue.js apps are compiled into a single minified JS file. Everything's in a JS module. AFAICT they have no concept whatsoever of "reading from a config file" so anything that does that would just have to be written in raw JavaScript outside the framework.



  • @blakeyrat yes. The closest to an external config file in a vue.js application is an object attached to window. I was comparing to other environments that do have config files, just like you did before.



  • @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @Bulb said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Why? If it was a config file, it wouldn't be there – it would be in the config file.

    Vue.js apps are compiled into a single minified JS file. Everything's in a JS module. AFAICT they have no concept whatsoever of "reading from a config file" so anything that does that would just have to be written in raw JavaScript outside the framework.

    Vue.js works like this as does Angular. Both these systems I feel were put together by people that actually had zero concept of real world processes. I actually regret the one project we did in Angular and this is one of the reasons why.
    Configuration should not be compiled in, configuration by definition should be able to be changed without a recompile and considered part of the environment not part of the code.



  • @KattMan said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Configuration should not be compiled in, configuration by definition should be able to be changed without a recompile and considered part of the environment not part of the code.

    I'm glad there are still people in front-end development who get it.


  • Fake News

    In my case we cheat by bundling each deployment of the frontend with its own backend on an Azure web app. This way the "production" build of the frontend just uses a local path ../api/ relative to the location of the frontend and the browser will make it work. It also has the advantage of sidestepping CORS rules because it's all on the same domain.

    Developers who are working locally use a "debug" build where you can insert an absolute URL in some ignored-by-git config file which then points to the right location. It's only for them that the API needs CORS rules where we need to whitelist localhost:someport.


  • Notification Spam Recipient

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    So if my app relies on 3 HTTP requests (index.html, site.js, config.json) instead of 2, it's a third more likely to fail on load. And it's already way more likely to fail on load, just because of the vagaries of the HTTP protocol, than I'd like it to be.

    Yeah, I ran into this real quick when I added global rate limiting to the Master Server app. Turns out, if you need 16 requests to load your app, and you give 10 with the rest responding 429 (with a Retry-After header), things break hard. And no web browsers will actually retry the request automatically.

    Partially solved by adding cache headers, but still..



  • @Tsaukpaetra Well one nice thing about Vue.JS is by default it makes each site into two files toto. The JS file is pretty huge though. (There's some dynamic view loading stuff you can use if it gets ridiculous.)



  • You know it just occurred to me that if JS could read HTTP headers of files already downloaded, you could just tell the webserver to add a X-API-Server header that tells the app which API URL to use.


  • Notification Spam Recipient

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    I'm a software engineer.

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    I want my shit to be correct.

    ....
    .....

    ........

    Are you sure?????



  • @Tsaukpaetra Sure about which part?


  • Notification Spam Recipient

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @Tsaukpaetra Well one nice thing about Vue.JS is by default it makes each site into two files toto. The JS file is pretty huge though. (There's some dynamic view loading stuff you can use if it gets ridiculous.)

    Oh shit... I just realized, you actually managed to get all the gulp and shit working?!?

    Props!

    I couldn't figure it out, I just take the packaged version and modules things and include them by hand. It would be nice if I got it working with the build things, I have to use a lot of ugly workarounds...


  • Notification Spam Recipient

    @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @Tsaukpaetra Sure about which part?

    Being a software engineer and simultaneously wanting your shit to be correct. It just feels to me that you must be unusual if this is true...



  • @blakeyrat said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    @KattMan said in Deploying Vue.JS Single Page App to multiple environments-- how?:

    Configuration should not be compiled in, configuration by definition should be able to be changed without a recompile and considered part of the environment not part of the code.

    I'm glad there are still people in front-end development who get it.

    Heh I'm not in front end development. I'm a team lead that sits over both front and back end developers but also expected to write code about 30% of the time. For the most part I review, keep the team on track, and manage the work load and keep management happy without impacting my team. I'm a manager without the title, pay, or additional responsibilities like hiring or firing. On some cases it is the perfect balance.
    I actually dinged the developer when he said he had to recompile between environments until he educated me on how this worked and we went around in circles a few times trying to solve this problem and ended up realizing it's not a solvable problem within that technology. Solving it actually moves you away from this technology which I wish we did fully and completely, but you know.. deadlines.



  • Pardon the late intrusion, but if youre talking about what I think you're talking about... it is also a bit of a peeve of mine too. I've seen some applications here with urls baked into JavaScript files etc. Yuk.

    For my more recent SPAs, I make use of ASP.NET MVC to deliver the initial HTML. I have a _Layout.cshtml file and a single Home/Index.cshtml file with the application shell (style tags, script tags, main page, nagivation etc.). All the Angular view files are static .html files.

    So, in the Index.cshtml file, I can use a bit of Razr magic...

    <script type="text/javascript">
            megacorp.utils.setBaseUrl(window.location.protocol + '//' + window.location.host + '@BaseDirectory()');
            megacorp.config.something = '@ConfigurationManager.AppSettings["Something"]';
    </script>
    

    Then in JavaScript-land, I just read the variable megacorp.config.something and I have my values from C# land (which could come from web.config via transformations, or SQL databases etc.).

    Similarly, I've not found anything better than Microsoft's Bundler for my scripts and css. It 'just works', and reading about gulp etc. just gives me shivers!



  • @richw That doesn't work with Vue.JS because it builds its own homepage with its own scripts/css paths and those paths change every build. (Although I'm not sure why... cache busting?)

    Also mixing and matching sucks, because that removes (or at least severely limits) my ability to put the front-end on its own server.


  • Considered Harmful

    @richw Welcome back!



  • @blakeyrat Ah, I must admit to total ignorance of Vue.JS - thought it was just 'yet another framework' in the slop that is the JavaScript ecosystem! Cache-busting could be relevant, but it sounds a bit of a smelly reason. Microsoft's bundler sorts that out too - when I build in release mode, I get cache-busting URLs and minification etc.

    I don't mind a bit of mix-and-match C#/Razr with my JS SPA: I get good control from the former, so I can introduce a little bit of grown up behaviour into the world of JS. :)

    P.S. I didn't mean to leave the first script line in: that's just me setting my base URL so that I can use my creations over ngrok for internal review, localhost for development, and wherever-the-hell.com for the deploy - no code/config changes needed.

    @pie_flavor Thanks. I'm a bad user. I've read this forum on-and-off for over a dozen years, but only recently have I bothered to sign up, and only posted a handful of times. Must do better...


Log in to reply