Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.7.x] Provide hook to access dev url while transforming #195

Merged
merged 1 commit into from
Feb 1, 2023
Merged

[0.7.x] Provide hook to access dev url while transforming #195

merged 1 commit into from
Feb 1, 2023

Conversation

timacdonald
Copy link
Member

@timacdonald timacdonald commented Jan 30, 2023

This exposes a hook that allows developers to transform code in serve mode (npm run dev) while giving access to the dev server URL. Transforming code in serve mode is already possible, however the developer does not have access to the dev server url.

This is required for some plugins that assume absolute URLs starting with a / will be pointing at the vite dev server, e.g.

<img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">

should be interpreted as

<img src="{DEV_SERVER_URL}/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">

Due to the nature of the Laravel integration, these URLs do not point to the Vite dev server; they point to the backend web server, such as Nginx.

There are a number of ways this could be addressed, but I decided on a low level implementation with the config hook to give maximum control so we don't make the wrong assumption with a generalisation.

The issue outlined in #194 and its linked issue is solved with the following configuration:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import { imagetools } from 'vite-imagetools';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
            transformOnServe: (code, url) => code.replaceAll('/@imagetools', url+'/@imagetools'),
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
        imagetools()
    ],
});

Resulting in the following output HTML

- <img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">
+ <img src="http://[::1]:5173/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">

Alternative API

I did consider a "prefixWithDevServerUrl" config option, which does feel cleaner, but is more restrictive in its usage.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import { imagetools } from 'vite-imagetools';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
            prefixWithDevServerUrl: ['/@imagetools'],
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
        imagetools()
    ],
});

DIY example

It is possible to do this already with the existing tools on hand, but I do feel it is reasonable for us to include the proposed affordance.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import { imagetools } from 'vite-imagetools';
import fs from 'fs'

let resolvedConfig;

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
        }),
        {
            name: 'my-transform',
            configResolved(config) {
                resolvedConfig = config
            },
            transform(code) {
                if (resolvedConfig.command === 'serve') {
                    const url = fs.readFileSync('public/hot')

                    return code.replaceAll('/@imagetools', url+'/@imagetools')
                }
            },
        },
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
        imagetools()
    ],
});

fixes #194

@timacdonald timacdonald changed the title [0.7.x] Provides hook to access dev url while transforming [0.7.x] Provide hook to access dev url while transforming Jan 31, 2023
@HassanZahirnia
Copy link

Hey Tim
Thanks for making effort and looking into the vite-imagetools plugin integration with Laravel 🙌😊

I just tried the PR and it works great! 👍
Having access to Vite plugins that are powered by tools like Sharp would really be great. You can have real-time image manipulation/format conversions which is awesome for modern web development.

Thank you for also including a DIY example 👌

Any plans to merge this?

@taylorotwell taylorotwell merged commit b8ea8f4 into laravel:main Feb 1, 2023
@timacdonald timacdonald deleted the dev-server-prefix branch February 1, 2023 03:46
@HassanZahirnia
Copy link

Hey is there a way to solve this TS error on replaceAll ?
image

@driesvints
Copy link
Member

@timacdonald ^

@timacdonald
Copy link
Member Author

timacdonald commented Feb 7, 2023

You need to specify a "lib" configuration of "es2021" or later in your tsconfig.

https://www.typescriptlang.org/tsconfig#lib

Alternatively, you may use replace with a global regex flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[0.7.x] No way to prefix dev server url
5 participants