Skip to content

Commit

Permalink
Merge pull request #77 from laravel/vite-3
Browse files Browse the repository at this point in the history
[0.4.x] Vite 3 support
  • Loading branch information
jessarcher authored Jul 19, 2022
2 parents d0b8894 + 70db475 commit 638365e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 78 deletions.
2 changes: 1 addition & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ If you prefer to build your assets on deploy instead of committing them to your
You may start the SSR server using `node`:

```sh
node bootstrap/ssr/ssr.js
node bootstrap/ssr/ssr.mjs
```

### Optional: Expose Vite port when using Laravel Sail
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
"eslint": "^8.14.0",
"picocolors": "^1.0.0",
"typescript": "^4.6.4",
"vite": "^2.9.6",
"vite": "^3.0.0",
"vitest": "^0.12.4"
},
"peerDependencies": {
"vite": "^2.9.9"
"vite": "^3.0.0"
},
"engines": {
"node": ">=14"
Expand Down
87 changes: 17 additions & 70 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs'
import { AddressInfo } from 'net'
import path from 'path'
import colors from 'picocolors'
import { Plugin, loadEnv, UserConfig, ConfigEnv, Manifest, ResolvedConfig, SSROptions, normalizePath, PluginOption } from 'vite'
import { Plugin, loadEnv, UserConfig, ConfigEnv, ResolvedConfig, SSROptions, PluginOption } from 'vite'
import fullReload, { Config as FullReloadConfig } from 'vite-plugin-full-reload'

interface PluginConfig {
Expand Down Expand Up @@ -85,7 +85,6 @@ export default function laravel(config: string|string[]|PluginConfig): [LaravelP
function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlugin {
let viteDevServerUrl: DevServerUrl
let resolvedConfig: ResolvedConfig
const cssManifest: Manifest = {}

const defaultAliases: Record<string, string> = {
'@': '/resources/js',
Expand Down Expand Up @@ -159,9 +158,10 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug
fs.writeFileSync(hotFile, viteDevServerUrl)

setTimeout(() => {
server.config.logger.info(colors.red(`\n Laravel ${laravelVersion()} `))
server.config.logger.info(`\n > APP_URL: ` + colors.cyan(appUrl))
})
server.config.logger.info(`\n ${colors.red(`${colors.bold('LARAVEL')} ${laravelVersion()}`)} ${colors.dim('plugin')} ${colors.bold(`v${pluginVersion()}`)}`)
server.config.logger.info('')
server.config.logger.info(` ${colors.green('➜')} ${colors.bold('APP_URL')}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
}, 100)
}
})

Expand Down Expand Up @@ -199,50 +199,6 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug

next()
})
},

// The following two hooks are a workaround to help solve a "flash of unstyled content" with Blade.
// They add any CSS entry points into the manifest because Vite does not currently do this.
renderChunk(_, chunk) {
const cssLangs = `\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)`
const cssLangRE = new RegExp(cssLangs)

if (! chunk.isEntry || chunk.facadeModuleId === null || ! cssLangRE.test(chunk.facadeModuleId)) {
return null
}

const relativeChunkPath = normalizePath(path.relative(resolvedConfig.root, chunk.facadeModuleId))

cssManifest[relativeChunkPath] = {
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
/* @ts-ignore */
file: Array.from(chunk.viteMetadata.importedCss)[0] ?? chunk.fileName,
src: relativeChunkPath,
isEntry: true,
}

return null
},
writeBundle() {
const manifestConfig = resolveManifestConfig(resolvedConfig)

if (manifestConfig === false) {
return;
}

const manifestPath = path.resolve(resolvedConfig.root, resolvedConfig.build.outDir, manifestConfig)

if (! fs.existsSync(manifestPath)) {
// The manifest does not exist yet when first writing the legacy asset bundle.
return;
}

const manifest = JSON.parse(fs.readFileSync(manifestPath).toString())
const newManifest = {
...manifest,
...cssManifest,
}
fs.writeFileSync(manifestPath, JSON.stringify(newManifest, null, 2))
}
}
}
Expand All @@ -260,6 +216,17 @@ function laravelVersion(): string {
}
}

/**
* The version of the Laravel Vite plugin being run.
*/
function pluginVersion(): string {
try {
return JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json')).toString())?.version
} catch {
return ''
}
}

/**
* Convert the users configuration into a standard structure with defaults.
*/
Expand Down Expand Up @@ -339,26 +306,6 @@ function resolveOutDir(config: Required<PluginConfig>, ssr: boolean): string|und
return path.join(config.publicDirectory, config.buildDirectory)
}

/**
* Resolve the Vite manifest config from the configuration.
*/
function resolveManifestConfig(config: ResolvedConfig): string|false
{
const manifestConfig = config.build.ssr
? config.build.ssrManifest
: config.build.manifest;

if (manifestConfig === false) {
return false
}

if (manifestConfig === true) {
return config.build.ssr ? 'ssr-manifest.json' : 'manifest.json'
}

return manifestConfig
}

function resolveFullReloadConfig({ refresh: config }: Required<PluginConfig>): PluginOption[]{
if (typeof config === 'boolean') {
return [];
Expand Down Expand Up @@ -413,7 +360,7 @@ function noExternalInertiaHelpers(config: UserConfig): true|Array<string|RegExp>
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
/* @ts-ignore */
const userNoExternal = (config.ssr as SSROptions|undefined)?.noExternal
const pluginNoExternal = ['laravel-vite-plugin']
const pluginNoExternal = ['laravel-vite-plugin/inertia-helpers']

if (userNoExternal === true) {
return true
Expand Down
10 changes: 5 additions & 5 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ describe('laravel-vite-plugin', () => {

const noSsrConfig = plugin.config({ build: { ssr: true } }, { command: 'build', mode: 'production' })
/* @ts-ignore */
expect(noSsrConfig.ssr.noExternal).toEqual(['laravel-vite-plugin'])
expect(noSsrConfig.ssr.noExternal).toEqual(['laravel-vite-plugin/inertia-helpers'])

/* @ts-ignore */
const nothingExternalConfig = plugin.config({ ssr: { noExternal: true }, build: { ssr: true } }, { command: 'build', mode: 'production' })
Expand All @@ -229,12 +229,12 @@ describe('laravel-vite-plugin', () => {
/* @ts-ignore */
const arrayNoExternalConfig = plugin.config({ ssr: { noExternal: ['foo'] }, build: { ssr: true } }, { command: 'build', mode: 'production' })
/* @ts-ignore */
expect(arrayNoExternalConfig.ssr.noExternal).toEqual(['foo', 'laravel-vite-plugin'])
expect(arrayNoExternalConfig.ssr.noExternal).toEqual(['foo', 'laravel-vite-plugin/inertia-helpers'])

/* @ts-ignore */
const stringNoExternalConfig = plugin.config({ ssr: { noExternal: 'foo' }, build: { ssr: true } }, { command: 'build', mode: 'production' })
/* @ts-ignore */
expect(stringNoExternalConfig.ssr.noExternal).toEqual(['foo', 'laravel-vite-plugin'])
expect(stringNoExternalConfig.ssr.noExternal).toEqual(['foo', 'laravel-vite-plugin/inertia-helpers'])
})

it('does not configure full reload when configuration it not an object', () => {
Expand Down Expand Up @@ -360,8 +360,8 @@ describe('inertia-helpers', () => {
expect(file.default).toBe('Dummy File')
})

it('pass globEager value to resolvePageComponent', async () => {
const file = await resolvePageComponent<{ default: string }>(path, import.meta.globEager('./__data__/*.ts'))
it('pass eagerly globed value to resolvePageComponent', async () => {
const file = await resolvePageComponent<{ default: string }>(path, import.meta.glob('./__data__/*.ts', { eager: true }))
expect(file.default).toBe('Dummy File')
})
})

0 comments on commit 638365e

Please sign in to comment.