Skip to content

Commit

Permalink
Help users that visit the Vite dev server directly (#57)
Browse files Browse the repository at this point in the history
* Help users that visit the Vite dev server directly

* send 404 response status

* Update console wording

Co-authored-by: Tim MacDonald <hello@timacdonald.me>

* Formatting

* Update dev-server-index.html

Co-authored-by: Tim MacDonald <hello@timacdonald.me>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
3 people committed Jul 14, 2022
1 parent b8d41ae commit 4191e57
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
"scripts": {
"build": "npm run build-plugin && npm run build-inertia-helpers",
"build-plugin": "rm -rf dist && tsc",
"build-plugin": "rm -rf dist && tsc && cp src/dev-server-index.html dist/",
"build-inertia-helpers": "rm -rf inertia-helpers && tsc --project tsconfig.inertia-helpers.json",
"lint": "eslint --ext .ts ./src ./tests",
"ssr:serve": "vite build --ssr && node storage/ssr/ssr.js",
Expand Down
76 changes: 76 additions & 0 deletions src/dev-server-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Laravel Vite</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">

<!-- Styles -->
<style>
body {
font-family: 'Nunito', sans-serif;
}
</style>
<style>
/* ! tailwindcss v3.1.4 | MIT License | https://tailwindcss.com */*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#edf2f7}:before,:after{--tw-content:''}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#cbd5e0}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}*,:before,:after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x:;--tw-pan-y:;--tw-pinch-zoom:;--tw-scroll-snap-strictness:proximity;--tw-ordinal:;--tw-slashed-zero:;--tw-numeric-figure:;--tw-numeric-spacing:;--tw-numeric-fraction:;--tw-ring-inset:;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur:;--tw-brightness:;--tw-contrast:;--tw-grayscale:;--tw-hue-rotate:;--tw-invert:;--tw-saturate:;--tw-sepia:;--tw-drop-shadow:;--tw-backdrop-blur:;--tw-backdrop-brightness:;--tw-backdrop-contrast:;--tw-backdrop-grayscale:;--tw-backdrop-hue-rotate:;--tw-backdrop-invert:;--tw-backdrop-opacity:;--tw-backdrop-saturate:;--tw-backdrop-sepia:}::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x:;--tw-pan-y:;--tw-pinch-zoom:;--tw-scroll-snap-strictness:proximity;--tw-ordinal:;--tw-slashed-zero:;--tw-numeric-figure:;--tw-numeric-spacing:;--tw-numeric-fraction:;--tw-ring-inset:;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur:;--tw-brightness:;--tw-contrast:;--tw-grayscale:;--tw-hue-rotate:;--tw-invert:;--tw-saturate:;--tw-sepia:;--tw-drop-shadow:;--tw-backdrop-blur:;--tw-backdrop-brightness:;--tw-backdrop-contrast:;--tw-backdrop-grayscale:;--tw-backdrop-hue-rotate:;--tw-backdrop-invert:;--tw-backdrop-opacity:;--tw-backdrop-saturate:;--tw-backdrop-sepia:}::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x:;--tw-pan-y:;--tw-pinch-zoom:;--tw-scroll-snap-strictness:proximity;--tw-ordinal:;--tw-slashed-zero:;--tw-numeric-figure:;--tw-numeric-spacing:;--tw-numeric-fraction:;--tw-ring-inset:;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur:;--tw-brightness:;--tw-contrast:;--tw-grayscale:;--tw-hue-rotate:;--tw-invert:;--tw-saturate:;--tw-sepia:;--tw-drop-shadow:;--tw-backdrop-blur:;--tw-backdrop-brightness:;--tw-backdrop-contrast:;--tw-backdrop-grayscale:;--tw-backdrop-hue-rotate:;--tw-backdrop-invert:;--tw-backdrop-opacity:;--tw-backdrop-saturate:;--tw-backdrop-sepia:}.relative{position:relative}.mx-auto{margin-left:auto;margin-right:auto}.mt-6{margin-top:1.5rem}.flex{display:flex}.h-16{height:4rem}.h-6{height:1.5rem}.min-h-screen{min-height:100vh}.w-auto{width:auto}.w-6{width:1.5rem}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1.5rem*var(--tw-space-x-reverse));margin-left:calc(1.5rem*calc(1 - var(--tw-space-x-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-gray-300>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(226 232 240/var(--tw-divide-opacity))}.overflow-hidden{overflow:hidden}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(247 250 252/var(--tw-bg-opacity))}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-10{padding-top:2.5rem}.pb-8{padding-bottom:2rem}.pt-8{padding-top:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.leading-7{line-height:1.75rem}.text-gray-600{--tw-text-opacity:1;color:rgb(113 128 150/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(160 174 192/var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgb(249 50 44/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(26 32 44/var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgb(235 68 50/var(--tw-text-opacity))}.shadow-xl{--tw-shadow:0 20px 25px -5px rgb(0 0 0/0.1),0 8px 10px -6px rgb(0 0 0/0.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-gray-900\/5{--tw-ring-color:rgb(26 32 44/0.05)}.hover\:text-red-600:hover{--tw-text-opacity:1;color:rgb(235 68 50/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.dark\:divide-gray-700>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(74 85 104/var(--tw-divide-opacity))}.dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(26 32 44/var(--tw-bg-opacity))}.dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(45 55 72/var(--tw-bg-opacity))}.dark\:text-gray-400{--tw-text-opacity:1;color:rgb(203 213 224/var(--tw-text-opacity))}.dark\:text-gray-100{--tw-text-opacity:1;color:rgb(247 250 252/var(--tw-text-opacity))}}@media (min-width:640px){.sm\:mx-auto{margin-left:auto;margin-right:auto}.sm\:max-w-xl{max-width:36rem}.sm\:rounded-lg{border-radius:.5rem}.sm\:py-12{padding-top:3rem;padding-bottom:3rem}.sm\:px-10{padding-left:2.5rem;padding-right:2.5rem}}
</style>
</head>
<body class="antialiased">
<div class="relative flex min-h-screen flex-col justify-center overflow-hidden bg-gray-100 text-gray-600 dark:text-gray-400 dark:bg-gray-900 py-6 sm:py-12">
<div class="relative bg-white dark:bg-gray-800 px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-xl sm:rounded-lg sm:px-10">
<div class="mx-auto">
<div class="flex items-center justify-center space-x-6">
<a href="https://laravel.com">
<svg viewBox="0 0 316 316" xmlns="http://www.w3.org/2000/svg" class="h-16 w-auto">
<path fill="#EF3B2D" d="M305.8 81.125C305.77 80.995 305.69 80.885 305.65 80.755C305.56 80.525 305.49 80.285 305.37 80.075C305.29 79.935 305.17 79.815 305.07 79.685C304.94 79.515 304.83 79.325 304.68 79.175C304.55 79.045 304.39 78.955 304.25 78.845C304.09 78.715 303.95 78.575 303.77 78.475L251.32 48.275C249.97 47.495 248.31 47.495 246.96 48.275L194.51 78.475C194.33 78.575 194.19 78.725 194.03 78.845C193.89 78.955 193.73 79.045 193.6 79.175C193.45 79.325 193.34 79.515 193.21 79.685C193.11 79.815 192.99 79.935 192.91 80.075C192.79 80.285 192.71 80.525 192.63 80.755C192.58 80.875 192.51 80.995 192.48 81.125C192.38 81.495 192.33 81.875 192.33 82.265V139.625L148.62 164.795V52.575C148.62 52.185 148.57 51.805 148.47 51.435C148.44 51.305 148.36 51.195 148.32 51.065C148.23 50.835 148.16 50.595 148.04 50.385C147.96 50.245 147.84 50.125 147.74 49.995C147.61 49.825 147.5 49.635 147.35 49.485C147.22 49.355 147.06 49.265 146.92 49.155C146.76 49.025 146.62 48.885 146.44 48.785L93.99 18.585C92.64 17.805 90.98 17.805 89.63 18.585L37.18 48.785C37 48.885 36.86 49.035 36.7 49.155C36.56 49.265 36.4 49.355 36.27 49.485C36.12 49.635 36.01 49.825 35.88 49.995C35.78 50.125 35.66 50.245 35.58 50.385C35.46 50.595 35.38 50.835 35.3 51.065C35.25 51.185 35.18 51.305 35.15 51.435C35.05 51.805 35 52.185 35 52.575V232.235C35 233.795 35.84 235.245 37.19 236.025L142.1 296.425C142.33 296.555 142.58 296.635 142.82 296.725C142.93 296.765 143.04 296.835 143.16 296.865C143.53 296.965 143.9 297.015 144.28 297.015C144.66 297.015 145.03 296.965 145.4 296.865C145.5 296.835 145.59 296.775 145.69 296.745C145.95 296.655 146.21 296.565 146.45 296.435L251.36 236.035C252.72 235.255 253.55 233.815 253.55 232.245V174.885L303.81 145.945C305.17 145.165 306 143.725 306 142.155V82.265C305.95 81.875 305.89 81.495 305.8 81.125ZM144.2 227.205L100.57 202.515L146.39 176.135L196.66 147.195L240.33 172.335L208.29 190.625L144.2 227.205ZM244.75 114.995V164.795L226.39 154.225L201.03 139.625V89.825L219.39 100.395L244.75 114.995ZM249.12 57.105L292.81 82.265L249.12 107.425L205.43 82.265L249.12 57.105ZM114.49 184.425L96.13 194.995V85.305L121.49 70.705L139.85 60.135V169.815L114.49 184.425ZM91.76 27.425L135.45 52.585L91.76 77.745L48.07 52.585L91.76 27.425ZM43.67 60.135L62.03 70.705L87.39 85.305V202.545V202.555V202.565C87.39 202.735 87.44 202.895 87.46 203.055C87.49 203.265 87.49 203.485 87.55 203.695V203.705C87.6 203.875 87.69 204.035 87.76 204.195C87.84 204.375 87.89 204.575 87.99 204.745C87.99 204.745 87.99 204.755 88 204.755C88.09 204.905 88.22 205.035 88.33 205.175C88.45 205.335 88.55 205.495 88.69 205.635L88.7 205.645C88.82 205.765 88.98 205.855 89.12 205.965C89.28 206.085 89.42 206.225 89.59 206.325C89.6 206.325 89.6 206.325 89.61 206.335C89.62 206.335 89.62 206.345 89.63 206.345L139.87 234.775V285.065L43.67 229.705V60.135ZM244.75 229.705L148.58 285.075V234.775L219.8 194.115L244.75 179.875V229.705ZM297.2 139.625L253.49 164.795V114.995L278.85 100.395L297.21 89.825V139.625H297.2Z" />
</svg>
</a>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
</svg>
<a href="https://vitejs.dev">
<svg viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-16 w-auto">
<path d="M399.641 59.5246L215.643 388.545C211.844 395.338 202.084 395.378 198.228 388.618L10.5817 59.5563C6.38087 52.1896 12.6802 43.2665 21.0281 44.7586L205.223 77.6824C206.398 77.8924 207.601 77.8904 208.776 77.6763L389.119 44.8058C397.439 43.2894 403.768 52.1434 399.641 59.5246Z" fill="url(#paint0_linear)" />
<path d="M292.965 1.5744L156.801 28.2552C154.563 28.6937 152.906 30.5903 152.771 32.8664L144.395 174.33C144.198 177.662 147.258 180.248 150.51 179.498L188.42 170.749C191.967 169.931 195.172 173.055 194.443 176.622L183.18 231.775C182.422 235.487 185.907 238.661 189.532 237.56L212.947 230.446C216.577 229.344 220.065 232.527 219.297 236.242L201.398 322.875C200.278 328.294 207.486 331.249 210.492 326.603L212.5 323.5L323.454 102.072C325.312 98.3645 322.108 94.137 318.036 94.9228L279.014 102.454C275.347 103.161 272.227 99.746 273.262 96.1583L298.731 7.86689C299.767 4.27314 296.636 0.855181 292.965 1.5744Z" fill="url(#paint1_linear)" />
<defs>
<linearGradient id="paint0_linear" x1="6.00017" y1="32.9999" x2="235" y2="344" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF" />
<stop offset="1" stop-color="#BD34FE" />
</linearGradient>
<linearGradient id="paint1_linear" x1="194.651" y1="8.81818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83" />
<stop offset="0.0833333" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</linearGradient>
</defs>
</svg>
</a>
</div>
<div class="divide-y divide-gray-300 dark:divide-gray-700">
<div class="py-8 text-base leading-7">
<p>This is the Vite development server that provides Hot Module Replacement for your Laravel application.</p>
<p class="mt-6">To access your Laravel application, you will need to run a local development server.</p>
<h2 class="mt-6"><a href="https://laravel.com/docs/9.x/installation#your-first-laravel-project" class="font-semibold text-red-500 hover:text-red-600">Artisan Serve</a></h2>
<p>Laravel's local development server powered by PHP's built-in web server.</p>
<h2 class="mt-6"><a href="https://laravel.com/docs/sail" class="font-semibold text-red-500 hover:text-red-600">Laravel Sail</a></h2>
<p>A light-weight command-line interface for interacting with Laravel's default Docker development environment.</p>
</div>
<div class="pt-8 text-base leading-7">
<p>
Your Laravel application's configured <code class="text-sm font-bold text-gray-900 dark:text-gray-100">APP_URL</code> is:<br />
<a href="{{ APP_URL }}" class="font-semibold text-red-500 hover:text-red-600">{{ APP_URL }}</a>
</p>
<p class="mt-6">Want more information on Laravel's Vite integration?</p>
<p>
<a href="https://laravel.com/docs/vite" class="font-semibold text-red-500 hover:text-red-600">Read the docs &rarr;</a>
</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
24 changes: 21 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug
configureServer(server) {
const hotFile = path.join(pluginConfig.publicDirectory, 'hot')

const envDir = resolvedConfig.envDir || process.cwd()
const appUrl = loadEnv('', envDir, 'APP_URL').APP_URL

server.httpServer?.once('listening', () => {
const address = server.httpServer?.address()

Expand All @@ -155,9 +158,6 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug
viteDevServerUrl = resolveDevServerUrl(address, server.config)
fs.writeFileSync(hotFile, viteDevServerUrl)

const envDir = resolvedConfig.envDir || process.cwd()
const appUrl = loadEnv('', envDir, 'APP_URL').APP_URL

setTimeout(() => {
server.config.logger.info(colors.red(`\n Laravel ${laravelVersion()} `))
server.config.logger.info(`\n > APP_URL: ` + colors.cyan(appUrl))
Expand All @@ -181,6 +181,24 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug
process.on('SIGHUP', process.exit)

exitHandlersBound = true

return () => server.middlewares.use((req, res, next) => {
if (req.url === '/index.html') {
server.config.logger.warn(
"\n" + colors.bgYellow(
colors.black(`The Vite server should not be accessed directly. Your Laravel application's configured APP_URL is: ${appUrl}`)
)
)

res.statusCode = 404

res.end(
fs.readFileSync(path.join(__dirname, 'dev-server-index.html')).toString().replace(/{{ APP_URL }}/g, appUrl)
)
}

next()
})
},

// The following two hooks are a workaround to help solve a "flash of unstyled content" with Blade.
Expand Down

0 comments on commit 4191e57

Please sign in to comment.