aligajani's avatar

Why doesn't Laravel Vapor inject ASSET_URL in my build step?

This is from my Github action below. You can see that ASSET_URL is empty.

> @ production /github/workspace/.vapor/build/app
> cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

ASSET URL IS: 
 DONE  Compiled successfully in 26754ms11:23:07 PM

This is my code in webpack.mix.js. The ASSET_URL is not being injected.

// To deal with Laravel Vapor
if (mix.inProduction()) {
    const ASSET_URL = process.env.ASSET_URL;
    console.log("ASSET URL IS: " + ASSET_URL);

    mix.webpackConfig(webpack => {
        return {
            plugins: [
                new webpack.DefinePlugin({
                    "process.env.ASSET_PATH": JSON.stringify(ASSET_URL)
                })
            ],
            output: {
                publicPath: ASSET_URL
            }
        };
    });

However, assets() and mix() helpers in blade on index.blade.php work just fine.

0 likes
50 replies
fylzero's avatar

@aligajani Adding to process.env gives javascript access to it. Maybe Vapor references it with a script. Idk

aligajani's avatar

Vapor injects it but I am not sure why it won't work at the Mix level as it does work elsewhere like assets().

PaulMarshall's avatar

Had the same issue, we ended up passing it in from the env via the app.blade.php

window.__ASSET_URL__ = '{{ env('ASSET_URL') }}';

And then picking that up in app.js. Kind of a clumsy way of doing it.

1 like
fylzero's avatar

@aligajani It doesn't work with mix() or asset() because it is a javascript variable not a file reference.

Also webpack is what compiles your Javascript... it isn't part of your application. You cant access application PHP and Javascript in your webpack file.

aligajani's avatar

It is working with those helpers but not if I reference process.env.ASSET_URL in my webpack.mix.js and then subsequently process.env.ASSET_PATH in my app.js.

fylzero's avatar

@aligajani Webpack has ZERO access to your .env or compiled JavaScript files. It is NOT PART OF YOUR APP. It is simply a config file for webpack. There is literally NO WAY to get webpack.mix.js to access your compiled JavaScript.

1 like
aligajani's avatar

How did you pick it up in app.js? Ideally my goal is to prefix all assets from a computed value or method. What do you suggest ?

aligajani's avatar

You can actually use MIX_ environment variables to have that file pick up from a local .env file. It works during my local experiments.

fylzero's avatar

@aligajani You do realize you don't HAVE TO use the asset helper, right? You could just do this in a config.

config/app.php


    /*
    |--------------------------------------------------------------------------
    | Application URL
    |--------------------------------------------------------------------------
    |
    | This URL is used by the console to properly generate URLs when using
    | the Artisan command line tool. You should set this to the root of
    | your application so that it is used when running Artisan tasks.
    |
    */

    'url' => env('APP_URL', 'http://localhost'),

    'asset_url' => env('ASSET_URL', null),

You can either change the asset url here programmatically, OR add a new config and access it with...

config('app.my_crazy_ass_url');

Then instead of using...

{{ asset('css/app.css') }}

Use...

{{ config('app.my_crazy_ass_url').'/css/app.css' }}
aligajani's avatar

I don’t think you understand what I’m trying to do here. You need to look at the assets part of Vapor documentation. Taylor states that Vapor injects the ASSET_URL on two occasions. The

Build step and the environment. The former is what I’m trying to figure out here. The code I’ve shown is literally what Taylor wrote in the documentation.

fylzero's avatar

@aligajani You are absolutely correct and my apologies. I did not realize that was wired together in that way. Well, that's good. I learned something I thought I already new... next time I won't make a fool of myself over it. :)

1 like
fylzero's avatar

@aligajani Try defining ASSET_URL in your .env like this. Just curious if this works...

ASSET_URL=https://whateverurlyouaresettingthisto.com
MIX_ASSET_URL="${ASSET_URL}"

Do that and run npm run prod to see if it makes any difference.

1 like
fylzero's avatar

@aligajani Let me know if that worked, super curious as it does output when I try it.

Also, you may want to make sure to keep the trailing slash documented for...

const ASSET_URL = process.env.ASSET_URL + "/";

Unless you're explicitly adding that in the URL. I'm assuming they put that this way in the documentation for a reason. Maybe not, idk.

aligajani's avatar

@paulmarshall I could do this Paul, but I am finding the right solution. I have reached out to Taylor and Mohamed. Thank you for your hack though. How are you using this in your app.js? As a computed or a method?

aligajani's avatar

@fylzero Doesn't work.

I did update my environment files with MIX_ASSET_URL="${ASSET_URL}" and did vapor env:push production. Then ran the below from Github actions using vapor deploy production.

> @ production /github/workspace/.vapor/build/app
> cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

MIX_ASSET_URL=undefined
 DONE  Compiled successfully in 26430ms10:57:22 AM
PaulMarshall's avatar

@aligajani I spoke to Mohamed and did a lot of searching to try and find the 'correct' solution but unfortunately I couldn't get it to work.

In app.js I set the value to a const

const windowAssetURL = window.__ASSET_URL__ ? window.__ASSET_URL__ + '/' : '/';

Then just pass that in as a data property to the app and pick it up through a computed property in Vue

assetPath() {
      return this.$root.$data.windowAssetURL;
    },

@fylzero yeah I know I just couldn't get it to work on Vapor

fylzero's avatar

@paulmarshall Yeah, I mean according to Vapor docs...

Vapor injects an ASSET_URL environment variable which Laravel's asset helper will use when constructing your URLs

To accomplish this, you can take advantage of the ASSET_URL variable that Laravel Vapor injects into your environment during your build step:

mix
  .js("resources/js/app.js", "public/js")
  .sass("resources/sass/app.scss", "public/css");

if (mix.inProduction()) {
    const ASSET_URL = process.env.ASSET_URL + "/";

    mix.webpackConfig(webpack => {
        return {
            plugins: [
                new webpack.DefinePlugin({
                    "process.env.ASSET_PATH": JSON.stringify(ASSET_URL)
                })
            ],
            output: {
                publicPath: ASSET_URL
            }
        };
    });
}

This is supposed to be accessible.

Try This...

My only thinking is with the understanding of how Mix variables work in the env file... maybe try adding the MIX_ variable directly into your environment variables like so...

MIX_ASSET_URL=https://whateverurlyouaresettingthisto.com

Then reference with...

const ASSET_URL = process.env.MIX_ASSET_URL + "/";

See if that works. Could just be a typo in the documentation. If this doesn't work, something is off for sure.

aligajani's avatar

Guys I talked to Mohammed too and he said to update the Vapor library, however it did not work, so I am using what Paul suggested.

fylzero's avatar

@aligajani Wondering if you were able to try my last suggestion? I'd be curious to know if that fixed it... because if so, then it is just a typo in the Vapor docs. Which should be updated.

themsaid's avatar

Hey everyone. I'm trying to figure out why it's failing to read the environment variables for some people but working for others.

Can you please share the output of console.log(process.env) in your webpack.mix.js file after you run vapor deploy?

Notice that you must run vapor deploy not vapor build

aligajani's avatar

@themsaid Thank you Mohamed for taking this up. In Github actions, I am indeed running vapor deploy.

I logged process.env and I don't see ASSET_URL in there. I however do see VAPOR_API_TOKEN.

name: Deploy to staging

on:
  push:
    branches:
      - development

jobs:
  vapor:
    name: Deploy to staging
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: aligajani/laravel-vapor-action@master
        env:
          VAPOR_API_TOKEN: ${{ secrets.VAPOR_API_TOKEN }}
        with:
          args: "deploy staging"

themsaid's avatar

So that's not on your local machine? Seems like GitHub actions is overriding all environment variables and sets its own?

Please test on your local machine, if it's related to GitHub actions then you'll need to contact their support so they may explain.

1 like
aligajani's avatar

I have contacted them already, but no response yet. Maybe you should tweet them too, please. With your clout, I guess we are certain to get a faster response on Twitter. But thank you.

aligajani's avatar

@themsaid I don't deploy from my machine but I guess you're right. Github Actions is overriding them. I have reached out to them and have't received a response yet. But I suspect it is indeed the case. The last time I deployed via my machine, I wasn't using any assets so have to retest.

rogierv's avatar

I don't know if it helps but i resolved my issue using:

.options({
    resourceRoot: ASSET_PATH
})

this way my images and fonts got the correct cloudfront prefix :)

tuneless's avatar

Well I have the same problem with Chipper CI.

Somehow ASSET_URL is undefined after hitting vapor deploy production.

I am discussing with the Chipper CI devs right now. Tried all the suggestions here on board.

But ASSET_URL is still wrong in my compiled app.js.

Would be interesting to get more information about the env generation of vapor-cli and the ASSET_URL

benbjurstrom's avatar

Noticed that after I deleted my .env file process.env.ASSET_URL was no longer available in my webpack.mix.js when running vapor deploy.

Seems like vapor needs AWS_DEFAULT_REGION to be set for ASSET_URL to be available at that point in the deployment process.

Next

Please or to participate in this conversation.