( server: ViteDevServer, )
| 122 | } |
| 123 | |
| 124 | export function serveStaticMiddleware( |
| 125 | server: ViteDevServer, |
| 126 | ): Connect.NextHandleFunction { |
| 127 | const dir = server.config.root |
| 128 | const serve = sirv( |
| 129 | dir, |
| 130 | sirvOptions({ |
| 131 | config: server.config, |
| 132 | getHeaders: () => server.config.server.headers, |
| 133 | }), |
| 134 | ) |
| 135 | |
| 136 | // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` |
| 137 | return function viteServeStaticMiddleware(req, res, next) { |
| 138 | // only serve the file if it's not an html request or ends with `/` |
| 139 | // so that html requests can fallthrough to our html middleware for |
| 140 | // special processing |
| 141 | // also skip internal requests `/@fs/ /@vite-client` etc... |
| 142 | const cleanedUrl = cleanUrl(req.url!) |
| 143 | if ( |
| 144 | cleanedUrl.endsWith('/') || |
| 145 | path.extname(cleanedUrl) === '.html' || |
| 146 | isInternalRequest(req.url!) || |
| 147 | // skip url starting with // as these will be interpreted as |
| 148 | // scheme relative URLs by new URL() and will not be a valid file path |
| 149 | req.url?.startsWith('//') |
| 150 | ) { |
| 151 | return next() |
| 152 | } |
| 153 | |
| 154 | const url = new URL(req.url!, 'http://example.com') |
| 155 | const pathname = decodeURIIfPossible(url.pathname) |
| 156 | if (pathname === undefined) { |
| 157 | return next() |
| 158 | } |
| 159 | |
| 160 | // apply aliases to static requests as well |
| 161 | let redirectedPathname: string | undefined |
| 162 | for (const { find, replacement } of server.config.resolve.alias) { |
| 163 | const matches = |
| 164 | typeof find === 'string' |
| 165 | ? pathname.startsWith(find) |
| 166 | : find.test(pathname) |
| 167 | if (matches) { |
| 168 | redirectedPathname = pathname.replace(find, replacement) |
| 169 | break |
| 170 | } |
| 171 | } |
| 172 | if (redirectedPathname) { |
| 173 | // dir is pre-normalized to posix style |
| 174 | if (redirectedPathname.startsWith(withTrailingSlash(dir))) { |
| 175 | redirectedPathname = redirectedPathname.slice(dir.length) |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | const resolvedPathname = redirectedPathname || pathname |
| 180 | let fileUrl = path.resolve(dir, removeLeadingSlash(resolvedPathname)) |
| 181 | if (resolvedPathname.endsWith('/') && fileUrl[fileUrl.length - 1] !== '/') { |
no test coverage detected