How to serve lazy-loaded Vue JS chunks from CDN - laravel

I work on a single-page application written in Vue.js 3 and built by Vue CLI 5 (Webpack 5). The app is being served from a Laravel app which is deployed to AWS by Laravel Vapor. This tool also uploads all static assets (including JS chunks) to AWS S3 and make them available via CloudFront.
I want to load all static assets used in the Vue.js app from this CDN. The URL of the CloudFront distribution is available at build time in ASSET_URL environment variable. I have written my own asset functions in both TS and SCSS which are able to resolve asset paths properly for both local development and production environment. I use these functions whenever I write a URL of a static asset (image, font, etc.) in either .scss or .vue file and everything works fine.
But I am not able to make Vue.js app load JS chunks from CDN. When I modify publicPath option in vue.config.js, Vue Router gets broken. If I try to change output.publicPath directly in Webpack config, I get an error from Vue CLI saying that I cannot modify it directly.
So I have written a script that rewrites all URLs pointing to static assets in the generated index.blade.php file (similar to index.html in a typical Vue.js project) and initial JS chunks are loaded from CDN now. However, all lazy-loaded chunks are still being loaded from the server where Laravel app is deployed. It looks like these paths are somehow defined the generated app.f73fadef.js file.
So my question is, how can I load all static assets (including JS chunks) from CDN while serving an app from a dynamic web server? Is it even possible to do this just by changing Vue CLI or Webpack config and without any dirty "hacks" (like modifying generated JS files)?

I have finally been able to solve this. The problem was caused by the following router initialization code:
createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
Once I remove the parameter of createWebHistory function, I was able to set publicPath option in vue.config.js to my CloudFront distribution URL and everything started to work properly. I was even able to remove my own script that changed the URLs in index.blade.php since it was no longer needed.

Related

Move file from laravel server to Nuxt server

I have two separate project, laravel and nuxt;
i want to, when i upload file from the laravel, it'll be stored on static folder of the nuxt project. Is there any way for that?
For that, you'll need to send your file upload to a CI that will inject it into the Nuxt project, and rebuild the whole Nuxt app.
Also, remember that static is not bundled via Webpack.
Meaning that it will be shipped raw: if it's uploaded while not being properly optimized, it'll be shipped as is (would be better suited into an /assets directory but still >> build time for the whole project required here).
Even hosting it on your Laravel server is more worth at this point.
TLDR: it's not worth to send it to Nuxt's static directory.
I recommend hosting it on a CDN or alike.

No images on Nuxt static site after running npm run generate

I am working on a small nuxt website for a client, i havnt been using nuxt for very long but so far what i do is add target: "static" to the config when i'm ready to build for production, then send the dist folder to backend for deployment, but now i notice that after i run npm run generate images and others assets like js files do not get added to he page.. i have tried to create a new dummy project just to test, chose static mode when setting up the project, added 1 image to the project and display it in index page using
<img src="~/path-to-file" />
the image will appear normally in dev server, will also appear if project is hosted on netlify, but will not appear in git-pages or local apache server
i am confused on why this is happening, typically adding target static fixes issues like this but not this time, please help
There are two main ways to display images through nuxt. One via the assets folder, the other via the static folder.
Any images in the /assets folder will be bundled with webpack. These images can be referenced using:
<img src="~/assets/image.png"/>
If you do not want images to be bundled by webpack, then save them in the /static folder and reference using the following format:
<img src="/image.png"/>
Currently, you are using ~/ , which is shorthand to the base directory. Once you build your site for production this will no longer work, because the structure is transformed - which is why there is a discrepancy between your environments.

Vue files on Laravel does not reflect changes after pulling changes from repository on production server

im workin with LARAVEL and vue. i'have launched a project on digital ocean using ubuntun and nginx. Since the launch i'have add more features. Today i pulled those change on the production server, but they do not appear on the browser..
Using nano i'have chechked all the files, and yes, the files have changed but they do not reflect on the browser.
I'have used
npm run dev, npm run watch
php artisan config:cache, php artisan cache:clear but yet it doesnt seems to work
any idea ?
Before you push your updated Vue files you need to run npm run prod to prepare your assets as production ready.
Laravel uses mix to compile assets: https://laravel.com/docs/8.x/mix
Now you have your freshly compiled assets in your public/ directory, therefore you can pull to digitalocean machine. But now the browser might still be using cached asset (if name stays same, browser doesn't fetch same asset again for a while)
So, Mix Versioning comes to help: https://laravel.com/docs/8.x/mix#versioning-and-cache-busting
In your webmack.mix.js file you need to add .version() at the end of mix piping. End result will be something like this;
mix.js('resources/js/app.js', 'public/js')
.version();
As you want to use versioning, now you need to resolve asset urls with mix(...) instead of asset(...) in your blade files;
<script src="{{ mix('/js/app.js') }}"></script>
Now whenever you compile your assets, mix will assign them new version numbers and will at them to end of assets' urls in your blade. Browser will understand there is a update in file (because of a different version number) and will fetch updated asset.
Did you clear your browser's cache?
If you are working with Vue and/or Sass and therefore your files are changing from time to time, I suggest you to use mix() instead of asset() for cache busting. Otherwise all of your users will have to delete their cache (this is obv. not a good approach)
https://laravel.com/docs/8.x/mix#versioning-and-cache-busting

Laravel Vapor - Assets (logo) on maintenance mode page

According to the docs we are able to put a 503.html document inside the root of our Laravel project.
You may customize the maintenance mode splash screen for your application by placing a 503.html file in your application's root directory.
I would however love to be able to put one or more assets on this page (for example our Logo) to make this page better more personal. Laravel Vapor automatically uploads your static assets to cloudfront, which is not a problem if you're using the asset() helper. However, are there any solutions already being made? I can't find any.
Is there anyone who has created a solution to make this happen?
With Vapor every time you deploy all the assets get a new cloudfront url. This is mostly fine for js and css which we change often. Images, logos etc do not change much.
Better to make another bucket on aws and hard code the path the image file in your 503. Doesn't need to be deployed every time. Your users browsers can cache it for as long as you set it in the bucket.
I'd like Vapor to only change asset urls if the files have changed but so far that is not the case.

Vue: Having frontend in it's own Github repo?

I am working on a Laravel project and part of the app was converted to a Vue app. Ultimately, the blade file is reading from the source of /dist/app.js , which is generated after running npm run production and runs the whole Vue app. The company only wants 1 engineer to run deploys to ensure backend code doesn't get inadvertantly changed.
To make strictly frontend changes, can I technically have the src read off a CDN in the Blade file and then just remove the Vue app entirely from the github repo into it's own so I can continuously make changes on my own. That way, I can make changes and then upload the new bundle to the CDN without touching the backend repo. Is that doable?

Resources