Laravel-mix: Using Laravel Vapor to try to inject publicPath to assets

Created on 16 Oct 2019  路  10Comments  路  Source: JeffreyWay/laravel-mix

When using vapor deploy the assets (images) are not uploaded to the CDN.

The images themselves are inside .vue files. Mix/Webpack is rewriting the URLs, but not using the publicPath variable supplied via Vapor to serve them from cloudfront, the images themselves are copied to cloudfront.

For example, a vue file: Login.vue in resources/js/views/Login.vue has the following tag:

<img src="../../images/logos/logo.png" alt="Logo" class="w-32 m-auto mb-5" />

Which related to a file in /resources/images/logos/logo.png.

When npm run dev is executed, this is rewritten to /images/logo.png, and logo.png is copied to /public/images/logo.png as expected. When served locally this works fine.

However, when using the following code in webpack.mix.js (as taken from the Laravel Vapor docs) to inject a publicPath variable for serving the assets:

    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
            }
        };
    });

It seems to completely ignore the publicPath output and still just rewriting the URL to /images/logo.png. The expected result is for it to prepend the ASSET_URL/publicPath provided. I have console.log() the ASSET_URL during a npm run dev(/production) and the URL is outputted correctly, so the issue is getting webpack/laravel-mix to actually using that in the complied source.

Using mix() inside blade files works as expected, but the image URLs are inside Vue files so webpack/laravel-mix needs to do the injecting.

Not sure if this is a bug or we're doing something wrong, but seemingly have tried everything.

stale

Most helpful comment

Issue needs te be opened

problem is still there

All 10 comments

Same issue here. I have a slightly different setup because I'm using tailwindcss also. For this reason, I had to turn "processCssUrls" off.

/* https://tailwindcss.com/docs/installation#laravel-mix */
processCssUrls: false,

We're using Tailwinds CSS too, had to disable processCssUrl for that reason. But even with that enabled it wouldn't fix it in the Vue.

Found a work around, but it's not pretty. Credit - https://kevinchoppin.dev/blog/adding-your-cdn-to-image-references-in-js-and-css-with-laravel-mix

mix.imgCDN = function (path, cdn) {
    let file = new File(path);

    // Replace all occurrences of /images/ with CDN URL prepended
    let contents = file.read().replace(/\/images\//g, cdn+"/images/");
    file.write(contents);

    // Update version hash in manifest
    Mix.manifest.hash(file.pathFromPublic()).refresh();

    return this;
}.bind(mix);

mix.then(function(){
    let cdn = process.env.ASSET_URL;
    if (cdn !== undefined) {
        mix
            .imgCDN('public/css/app.css', cdn)
            .imgCDN('public/js/app.js', cdn);
    }
});

Basically do a massive search and replace in the code to find any instance of "/images/" and replace it with the CDN URL. It just seems like a really blunt tool - I wish mix/Webpack supported it correctly,

Thanks, will use this, for now, not pretty but better than missing images :)

I spent far too much time looking into this and trying various combinations of suggested solutions. In the end, the solution was extremely simple. You just need to use setResourceRoot. (The setPublicPath method is super misleading and doesn't work.)

In my case, setting the output: { publicPath: ... } config is not necessary. Combine your webpack custom configs with this:

const ASSET_URL = `${process.env.ASSET_URL || ''}/`

mix.setResourceRoot(ASSET_URL)

It is working for me now to deploy my React project with full image URLs.

I'm using Vue, the images were missing the CDN's path only in .vue files

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Issue needs te be opened

problem is still there

I found this section of the Vapor documentation very helpful: https://docs.vapor.build/1.0/projects/deployments.html#assets

anyone has an idea how you would replace image path in a manifest file for vapor?

like: manifest.webmanifest

Following the instructions on Vapor resolved the CSS and JS assets loading from the CDN. Then following @joelvh's instructions for using mix.setResourceRoot resolved assets being imported from within JS.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Cheddam picture Cheddam  路  3Comments

amin101 picture amin101  路  3Comments

sdebacker picture sdebacker  路  3Comments

terion-name picture terion-name  路  3Comments

Micaso picture Micaso  路  3Comments