mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 07:05:11 +00:00
feat(vite)!: upgrade vite to v3 (#5398)
This commit is contained in:
parent
2e794e7a19
commit
fa8b0f7c79
@ -42,7 +42,7 @@
|
||||
"nuxi": "link:./packages/nuxi",
|
||||
"nuxt": "link:./packages/nuxt",
|
||||
"nuxt3": "link:./packages/nuxt",
|
||||
"vite": "^2.9.14",
|
||||
"vite": "~3.0.0",
|
||||
"unbuild": "^0.7.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -31,8 +31,8 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
||||
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
||||
const query = parseQuery(search)
|
||||
// we only transform render functions
|
||||
// from `type=template` (in Webpack) and bare `.vue` file (in Vite)
|
||||
return pathname.endsWith('.vue') && (query.type === 'template' || !!query.macro || !search)
|
||||
// from `type=template` (in Webpack), bare `.vue` file and setup=true (Vite 2/3)
|
||||
return pathname.endsWith('.vue') && (query.type === 'template' || !!query.macro || !!query.setup || !search)
|
||||
},
|
||||
transform (code, id) {
|
||||
const components = options.getComponents()
|
||||
|
@ -41,10 +41,7 @@ export async function initNitro (nuxt: Nuxt) {
|
||||
generateTsConfig: false
|
||||
},
|
||||
publicAssets: [
|
||||
{
|
||||
baseURL: nuxt.options.app.buildAssetsDir,
|
||||
dir: resolve(nuxt.options.buildDir, 'dist/client')
|
||||
},
|
||||
{ dir: resolve(nuxt.options.buildDir, 'dist/client') },
|
||||
...nuxt.options._layers
|
||||
.map(layer => join(layer.config.srcDir, layer.config.dir?.public || 'public'))
|
||||
.filter(dir => existsSync(dir))
|
||||
|
@ -211,7 +211,10 @@ export const publicPathTemplate: NuxtTemplate = {
|
||||
'export const publicAssetsURL = (...path) => {',
|
||||
' const publicBase = appConfig.cdnURL || appConfig.baseURL',
|
||||
' return path.length ? joinURL(publicBase, ...path) : publicBase',
|
||||
'}'
|
||||
'}',
|
||||
|
||||
'globalThis.__buildAssetsURL = buildAssetsURL',
|
||||
'globalThis.__publicAssetsURL = publicAssetsURL'
|
||||
].filter(Boolean).join('\n')
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { createUnplugin } from 'unplugin'
|
||||
import { parseQuery, parseURL, withQuery } from 'ufo'
|
||||
import { findStaticImports, findExports } from 'mlly'
|
||||
import MagicString from 'magic-string'
|
||||
import { isAbsolute } from 'pathe'
|
||||
|
||||
export interface TransformMacroPluginOptions {
|
||||
macros: Record<string, string>
|
||||
@ -48,7 +49,8 @@ export const TransformMacroPlugin = createUnplugin((options: TransformMacroPlugi
|
||||
if (scriptImport) {
|
||||
// https://github.com/vuejs/vue-loader/pull/1911
|
||||
// https://github.com/vitejs/vite/issues/8473
|
||||
const parsed = parseURL(scriptImport.specifier.replace('?macro=true', ''))
|
||||
const url = isAbsolute(scriptImport.specifier) ? pathToFileURL(scriptImport.specifier).href : scriptImport.specifier
|
||||
const parsed = parseURL(decodeURIComponent(url).replace('?macro=true', ''))
|
||||
const specifier = withQuery(parsed.pathname, { macro: 'true', ...parseQuery(parsed.search) })
|
||||
s.overwrite(0, code.length, `export { meta } from "${specifier}"`)
|
||||
return result()
|
||||
|
@ -17,7 +17,7 @@
|
||||
"@types/lodash.template": "^4",
|
||||
"@types/semver": "^7",
|
||||
"unbuild": "latest",
|
||||
"vite": "^2.9.14"
|
||||
"vite": "~3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"c12": "^0.2.8",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { joinURL, withoutLeadingSlash } from 'ufo'
|
||||
import { withoutLeadingSlash } from 'ufo'
|
||||
|
||||
export default {
|
||||
/**
|
||||
@ -28,11 +28,6 @@ export default {
|
||||
resolve: {
|
||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
|
||||
},
|
||||
base: {
|
||||
$resolve: (val, get) => val ?? get('dev')
|
||||
? joinURL(get('app').baseURL, get('app').buildAssetsDir)
|
||||
: '/__NUXT_BASE__/',
|
||||
},
|
||||
publicDir: {
|
||||
$resolve: (val, get) => val ?? resolve(get('srcDir'), get('dir').public),
|
||||
},
|
||||
@ -61,7 +56,7 @@ export default {
|
||||
clearScreen: false,
|
||||
build: {
|
||||
assetsDir: {
|
||||
$resolve: (val, get) => val ?? get('dev') ? withoutLeadingSlash(get('app').buildAssetsDir) : '.',
|
||||
$resolve: (val, get) => val ?? withoutLeadingSlash(get('app').buildAssetsDir),
|
||||
},
|
||||
emptyOutDir: false,
|
||||
},
|
||||
|
@ -21,8 +21,8 @@
|
||||
"dependencies": {
|
||||
"@nuxt/kit": "^3.0.0-rc.6",
|
||||
"@rollup/plugin-replace": "^4.0.0",
|
||||
"@vitejs/plugin-vue": "^2.3.3",
|
||||
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
||||
"@vitejs/plugin-vue": "^3.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^2.0.0",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"chokidar": "^3.5.3",
|
||||
"cssnano": "^5.1.12",
|
||||
@ -47,7 +47,7 @@
|
||||
"rollup-plugin-visualizer": "^5.7.1",
|
||||
"ufo": "^0.8.5",
|
||||
"unplugin": "^0.7.2",
|
||||
"vite": "^2.9.14",
|
||||
"vite": "~3.0.0",
|
||||
"vite-node": "^0.18.1",
|
||||
"vite-plugin-checker": "^0.4.9"
|
||||
},
|
||||
|
@ -1,21 +1,36 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { join, resolve } from 'pathe'
|
||||
import * as vite from 'vite'
|
||||
import vuePlugin from '@vitejs/plugin-vue'
|
||||
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
|
||||
import type { Connect } from 'vite'
|
||||
import { logger } from '@nuxt/kit'
|
||||
import { joinURL } from 'ufo'
|
||||
import { getPort } from 'get-port-please'
|
||||
import { joinURL, withLeadingSlash, withoutLeadingSlash, withTrailingSlash } from 'ufo'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import { cacheDirPlugin } from './plugins/cache-dir'
|
||||
import { analyzePlugin } from './plugins/analyze'
|
||||
import { wpfs } from './utils/wpfs'
|
||||
import type { ViteBuildContext, ViteOptions } from './vite'
|
||||
import { writeManifest } from './manifest'
|
||||
import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
|
||||
import { RelativeAssetPlugin } from './plugins/dynamic-base'
|
||||
import { viteNodePlugin } from './vite-node'
|
||||
|
||||
export async function buildClient (ctx: ViteBuildContext) {
|
||||
const hmrPortDefault = 24678 // Vite's default HMR port
|
||||
const hmrPort = await getPort({
|
||||
port: hmrPortDefault,
|
||||
ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i)
|
||||
})
|
||||
const clientConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, {
|
||||
experimental: {
|
||||
renderBuiltUrl: (filename, { type, hostType }) => {
|
||||
if (hostType !== 'js' || type === 'asset') {
|
||||
// In CSS we only use relative paths until we craft a clever runtime CSS hack
|
||||
return { relative: true }
|
||||
}
|
||||
return { runtime: `globalThis.__publicAssetsURL(${JSON.stringify(filename)})` }
|
||||
}
|
||||
},
|
||||
define: {
|
||||
'process.server': false,
|
||||
'process.client': true,
|
||||
@ -30,8 +45,10 @@ export async function buildClient (ctx: ViteBuildContext) {
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
chunkFileNames: ctx.nuxt.options.dev ? undefined : '[name]-[hash].mjs',
|
||||
entryFileNames: ctx.nuxt.options.dev ? 'entry.mjs' : '[name]-[hash].mjs'
|
||||
// https://github.com/vitejs/vite/tree/main/packages/vite/src/node/build.ts#L464-L478
|
||||
assetFileNames: ctx.nuxt.options.dev ? undefined : withoutLeadingSlash(join(ctx.nuxt.options.app.buildAssetsDir, '[name].[hash].[ext]')),
|
||||
chunkFileNames: ctx.nuxt.options.dev ? undefined : withoutLeadingSlash(join(ctx.nuxt.options.app.buildAssetsDir, '[name].[hash].mjs')),
|
||||
entryFileNames: ctx.nuxt.options.dev ? 'entry.mjs' : withoutLeadingSlash(join(ctx.nuxt.options.app.buildAssetsDir, '[name].[hash].mjs'))
|
||||
}
|
||||
},
|
||||
manifest: true,
|
||||
@ -41,18 +58,30 @@ export async function buildClient (ctx: ViteBuildContext) {
|
||||
cacheDirPlugin(ctx.nuxt.options.rootDir, 'client'),
|
||||
vuePlugin(ctx.config.vue),
|
||||
viteJsxPlugin(),
|
||||
RelativeAssetPlugin(),
|
||||
devStyleSSRPlugin({
|
||||
rootDir: ctx.nuxt.options.rootDir,
|
||||
buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir)
|
||||
}),
|
||||
viteNodePlugin(ctx)
|
||||
],
|
||||
appType: 'custom',
|
||||
server: {
|
||||
hmr: {
|
||||
// https://github.com/nuxt/framework/issues/4191
|
||||
protocol: 'ws',
|
||||
clientPort: hmrPort,
|
||||
port: hmrPort
|
||||
},
|
||||
middlewareMode: true
|
||||
}
|
||||
} as ViteOptions)
|
||||
|
||||
// In build mode we explicitly override any vite options that vite is relying on
|
||||
// to detect whether to inject production or development code (such as HMR code)
|
||||
if (!ctx.nuxt.options.dev) {
|
||||
clientConfig.server.hmr = false
|
||||
}
|
||||
|
||||
// Add analyze plugin if needed
|
||||
if (ctx.nuxt.options.build.analyze) {
|
||||
clientConfig.plugins.push(...analyzePlugin(ctx))
|
||||
@ -65,10 +94,11 @@ export async function buildClient (ctx: ViteBuildContext) {
|
||||
const viteServer = await vite.createServer(clientConfig)
|
||||
ctx.clientServer = viteServer
|
||||
await ctx.nuxt.callHook('vite:serverCreated', viteServer, { isClient: true, isServer: false })
|
||||
|
||||
const BASE_RE = new RegExp(`^${escapeRE(withTrailingSlash(withLeadingSlash(joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir))))}`)
|
||||
const viteMiddleware: Connect.NextHandleFunction = (req, res, next) => {
|
||||
// Workaround: vite devmiddleware modifies req.url
|
||||
const originalURL = req.url
|
||||
req.url = req.url.replace(BASE_RE, '/')
|
||||
viteServer.middlewares.handle(req, res, (err) => {
|
||||
req.url = originalURL
|
||||
next(err)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { builtinModules } from 'node:module'
|
||||
import { resolve } from 'pathe'
|
||||
import { isAbsolute, resolve } from 'pathe'
|
||||
import * as vite from 'vite'
|
||||
import { ExternalsOptions, isExternal as _isExternal, ExternalsDefaults } from 'externality'
|
||||
import { genDynamicImport, genObjectFromRawEntries } from 'knitwork'
|
||||
@ -77,7 +77,7 @@ async function transformRequest (opts: TransformOptions, id: string) {
|
||||
if (await isExternal(opts, withoutVersionQuery)) {
|
||||
const path = builtinModules.includes(withoutVersionQuery.split('node:').pop())
|
||||
? withoutVersionQuery
|
||||
: pathToFileURL(withoutVersionQuery).href
|
||||
: isAbsolute(withoutVersionQuery) ? pathToFileURL(withoutVersionQuery).href : withoutVersionQuery
|
||||
return {
|
||||
code: `(global, module, _, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) =>
|
||||
${genDynamicImport(path, { wrapper: false })}
|
||||
@ -140,11 +140,11 @@ export async function bundleRequest (opts: TransformOptions, entryURL: string) {
|
||||
// Parents: \n${listIds(chunk.parents)}
|
||||
// Dependencies: \n${listIds(chunk.deps)}
|
||||
// --------------------
|
||||
const ${hashId(chunk.id)} = ${chunk.code}
|
||||
const ${hashId(chunk.id + '-' + chunk.code)} = ${chunk.code}
|
||||
`).join('\n')
|
||||
|
||||
const manifestCode = `const __modules__ = ${
|
||||
genObjectFromRawEntries(chunks.map(chunk => [chunk.id, hashId(chunk.id)]))
|
||||
genObjectFromRawEntries(chunks.map(chunk => [chunk.id, hashId(chunk.id + '-' + chunk.code)]))
|
||||
}`
|
||||
|
||||
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/ssr/ssrModuleLoader.ts
|
||||
|
@ -1,6 +1,7 @@
|
||||
import fse from 'fs-extra'
|
||||
import { resolve } from 'pathe'
|
||||
import { joinURL } from 'ufo'
|
||||
import { joinURL, withoutLeadingSlash, withTrailingSlash } from 'ufo'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import type { ViteBuildContext } from './vite'
|
||||
|
||||
export async function writeManifest (ctx: ViteBuildContext, extraEntries: string[] = []) {
|
||||
@ -27,6 +28,18 @@ export async function writeManifest (ctx: ViteBuildContext, extraEntries: string
|
||||
? devClientManifest
|
||||
: await fse.readJSON(resolve(clientDist, 'manifest.json'))
|
||||
|
||||
const BASE_RE = new RegExp(`^${escapeRE(withTrailingSlash(withoutLeadingSlash(joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir))))}`)
|
||||
for (const key in clientManifest) {
|
||||
if (clientManifest[key].file) {
|
||||
clientManifest[key].file = clientManifest[key].file.replace(BASE_RE, '')
|
||||
}
|
||||
for (const item of ['css', 'assets']) {
|
||||
if (clientManifest[key][item]) {
|
||||
clientManifest[key][item] = clientManifest[key][item].map(i => i.replace(BASE_RE, ''))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await fse.mkdirp(serverDist)
|
||||
await fse.writeFile(resolve(serverDist, 'client.manifest.json'), JSON.stringify(clientManifest, null, 2), 'utf8')
|
||||
await fse.writeFile(resolve(serverDist, 'client.manifest.mjs'), 'export default ' + JSON.stringify(clientManifest, null, 2), 'utf8')
|
||||
|
@ -1,103 +0,0 @@
|
||||
import { createUnplugin } from 'unplugin'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import type { Plugin } from 'vite'
|
||||
import MagicString from 'magic-string'
|
||||
|
||||
interface DynamicBasePluginOptions {
|
||||
globalPublicPath?: string
|
||||
sourcemap?: boolean
|
||||
}
|
||||
|
||||
export const RelativeAssetPlugin = function (): Plugin {
|
||||
return {
|
||||
name: 'nuxt:vite-relative-asset',
|
||||
generateBundle (_, bundle) {
|
||||
const generatedAssets = Object.entries(bundle).filter(([_, asset]) => asset.type === 'asset').map(([key]) => escapeRE(key))
|
||||
const assetRE = new RegExp(`\\/__NUXT_BASE__\\/(${generatedAssets.join('|')})`, 'g')
|
||||
|
||||
for (const file in bundle) {
|
||||
const asset = bundle[file]
|
||||
if (asset.fileName.includes('legacy') && asset.type === 'chunk' && asset.code.includes('innerHTML')) {
|
||||
for (const delimiter of ['`', '"', "'"]) {
|
||||
asset.code = asset.code.replace(
|
||||
new RegExp(`(?<=innerHTML=)${delimiter}([^${delimiter}]*)\\/__NUXT_BASE__\\/([^${delimiter}]*)${delimiter}`, 'g'),
|
||||
/* eslint-disable-next-line no-template-curly-in-string */
|
||||
'`$1${(window?.__NUXT__?.config.app.cdnURL || window?.__NUXT__?.config.app.baseURL) + window?.__NUXT__?.config.app.buildAssetsDir.slice(1)}$2`'
|
||||
)
|
||||
}
|
||||
}
|
||||
if (asset.type === 'asset' && typeof asset.source === 'string' && asset.fileName.endsWith('.css')) {
|
||||
const depth = file.split('/').length - 1
|
||||
const assetBase = depth === 0 ? '.' : Array.from({ length: depth }).map(() => '..').join('/')
|
||||
const publicBase = Array.from({ length: depth + 1 }).map(() => '..').join('/')
|
||||
asset.source = asset.source
|
||||
.replace(assetRE, r => r.replace(/\/__NUXT_BASE__/g, assetBase))
|
||||
.replace(/\/__NUXT_BASE__/g, publicBase)
|
||||
}
|
||||
if (asset.type === 'chunk' && typeof asset.code === 'string') {
|
||||
asset.code = asset.code
|
||||
.replace(/`\$\{(_?_?publicAssetsURL|buildAssetsURL|)\(\)\}([^`]*)`/g, '$1(`$2`)')
|
||||
.replace(/"\/__NUXT_BASE__\/([^"]*)"\.replace\("\/__NUXT_BASE__", ""\)/g, '"$1"')
|
||||
.replace(/'\/__NUXT_BASE__\/([^']*)'\.replace\("\/__NUXT_BASE__", ""\)/g, '"$1"')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const VITE_ASSET_RE = /^export default ["'](__VITE_ASSET.*)["']$/
|
||||
|
||||
export const DynamicBasePlugin = createUnplugin(function (options: DynamicBasePluginOptions = {}) {
|
||||
return {
|
||||
name: 'nuxt:dynamic-base-path',
|
||||
resolveId (id) {
|
||||
if (id.startsWith('/__NUXT_BASE__')) {
|
||||
return id.replace('/__NUXT_BASE__', '')
|
||||
}
|
||||
return null
|
||||
},
|
||||
enforce: 'post',
|
||||
transform (code, id) {
|
||||
const s = new MagicString(code)
|
||||
|
||||
if (options.globalPublicPath && id.includes('paths.mjs') && code.includes('const appConfig = ')) {
|
||||
s.append(`${options.globalPublicPath} = buildAssetsURL();\n`)
|
||||
}
|
||||
|
||||
const assetId = code.match(VITE_ASSET_RE)
|
||||
if (assetId) {
|
||||
s.overwrite(0, code.length,
|
||||
[
|
||||
'import { buildAssetsURL } from \'#build/paths.mjs\';',
|
||||
`export default buildAssetsURL("${assetId[1]}".replace("/__NUXT_BASE__", ""));`
|
||||
].join('\n')
|
||||
)
|
||||
}
|
||||
|
||||
if (!id.includes('paths.mjs') && code.includes('NUXT_BASE') && !code.includes('import { publicAssetsURL as __publicAssetsURL }')) {
|
||||
s.prepend('import { publicAssetsURL as __publicAssetsURL } from \'#build/paths.mjs\';\n')
|
||||
}
|
||||
|
||||
if (id === 'vite/preload-helper') {
|
||||
// Define vite base path as buildAssetsUrl (i.e. including _nuxt/)
|
||||
s.prepend('import { buildAssetsURL } from \'#build/paths.mjs\';\n')
|
||||
s.replace(/const base = ['"]\/__NUXT_BASE__\/['"]/, 'const base = buildAssetsURL()')
|
||||
}
|
||||
|
||||
// Sanitize imports
|
||||
s.replace(/from *['"]\/__NUXT_BASE__(\/[^'"]*)['"]/g, 'from "$1"')
|
||||
|
||||
// Dynamically compute string URLs featuring baseURL
|
||||
const delimiterRE = /(?<!(const base = |from *))((?<!\\)`([^`]*)\/__NUXT_BASE__\/([^`]*)(?<!\\)`|(?<!\\)'([^\n']*)\/__NUXT_BASE__\/([^\n']*)(?<!\\)'|(?<!\\)"([^\n"]*)\/__NUXT_BASE__\/([^\n"]*)(?<!\\)")/g
|
||||
/* eslint-disable-next-line no-template-curly-in-string */
|
||||
s.replace(delimiterRE, r => '`' + r.replace(/\/__NUXT_BASE__\//g, '${__publicAssetsURL()}').slice(1, -1) + '`')
|
||||
|
||||
if (s.hasChanged()) {
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
@ -1,23 +1,40 @@
|
||||
import { resolve, join, normalize } from 'pathe'
|
||||
import { resolve, normalize } from 'pathe'
|
||||
import * as vite from 'vite'
|
||||
import vuePlugin from '@vitejs/plugin-vue'
|
||||
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
|
||||
import { logger, resolveModule, isIgnored } from '@nuxt/kit'
|
||||
import fse from 'fs-extra'
|
||||
import { debounce } from 'perfect-debounce'
|
||||
import { withoutTrailingSlash } from 'ufo'
|
||||
import { joinURL, withoutLeadingSlash, withTrailingSlash } from 'ufo'
|
||||
import { ViteBuildContext, ViteOptions } from './vite'
|
||||
import { wpfs } from './utils/wpfs'
|
||||
import { cacheDirPlugin } from './plugins/cache-dir'
|
||||
import { prepareDevServerEntry } from './vite-node'
|
||||
import { isCSS, isDirectory, readDirRecursively } from './utils'
|
||||
import { isCSS } from './utils'
|
||||
import { bundleRequest } from './dev-bundler'
|
||||
import { writeManifest } from './manifest'
|
||||
import { RelativeAssetPlugin } from './plugins/dynamic-base'
|
||||
|
||||
export async function buildServer (ctx: ViteBuildContext) {
|
||||
const _resolve = id => resolveModule(id, { paths: ctx.nuxt.options.modulesDir })
|
||||
const serverConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, {
|
||||
base: ctx.nuxt.options.dev
|
||||
? joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir)
|
||||
: undefined,
|
||||
experimental: {
|
||||
renderBuiltUrl: (filename, { type, hostType }) => {
|
||||
if (hostType !== 'js') {
|
||||
// In CSS we only use relative paths until we craft a clever runtime CSS hack
|
||||
return { relative: true }
|
||||
}
|
||||
if (type === 'public') {
|
||||
return { runtime: `globalThis.__publicAssetsURL(${JSON.stringify(filename)})` }
|
||||
}
|
||||
if (type === 'asset') {
|
||||
const relativeFilename = filename.replace(withTrailingSlash(withoutLeadingSlash(ctx.nuxt.options.app.buildAssetsDir)), '')
|
||||
return { runtime: `globalThis.__buildAssetsURL(${JSON.stringify(relativeFilename)})` }
|
||||
}
|
||||
}
|
||||
},
|
||||
define: {
|
||||
'process.server': true,
|
||||
'process.client': false,
|
||||
@ -30,21 +47,22 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
resolve: {
|
||||
alias: {
|
||||
'#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server'),
|
||||
// Alias vue to ensure we're using the same context in development
|
||||
'vue/server-renderer': _resolve('vue/server-renderer'),
|
||||
'vue/compiler-sfc': _resolve('vue/compiler-sfc'),
|
||||
...ctx.nuxt.options.experimental.externalVue
|
||||
...ctx.nuxt.options.experimental.externalVue || ctx.nuxt.options.dev
|
||||
? {}
|
||||
: {
|
||||
'@vue/reactivity': _resolve(`@vue/reactivity/dist/reactivity.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`),
|
||||
'@vue/shared': _resolve(`@vue/shared/dist/shared.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`),
|
||||
'vue-router': _resolve(`vue-router/dist/vue-router.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`)
|
||||
},
|
||||
vue: _resolve(`vue/dist/vue.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`)
|
||||
'vue-router': _resolve(`vue-router/dist/vue-router.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`),
|
||||
'vue/server-renderer': _resolve('vue/server-renderer'),
|
||||
'vue/compiler-sfc': _resolve('vue/compiler-sfc'),
|
||||
vue: _resolve(`vue/dist/vue.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`)
|
||||
}
|
||||
}
|
||||
},
|
||||
ssr: {
|
||||
external: ctx.nuxt.options.experimental.externalVue ? ['#internal/nitro', 'vue', 'vue-router'] : ['#internal/nitro'],
|
||||
external: ctx.nuxt.options.experimental.externalVue
|
||||
? ['#internal/nitro', '#internal/nitro/utils', 'vue', 'vue-router']
|
||||
: ['#internal/nitro', '#internal/nitro/utils'],
|
||||
noExternal: [
|
||||
...ctx.nuxt.options.build.transpile,
|
||||
// TODO: Use externality for production (rollup) build
|
||||
@ -81,7 +99,6 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
},
|
||||
plugins: [
|
||||
cacheDirPlugin(ctx.nuxt.options.rootDir, 'server'),
|
||||
RelativeAssetPlugin(),
|
||||
vuePlugin(ctx.config.vue),
|
||||
viteJsxPlugin()
|
||||
]
|
||||
@ -95,37 +112,6 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
|
||||
await ctx.nuxt.callHook('vite:extendConfig', serverConfig, { isClient: false, isServer: true })
|
||||
|
||||
ctx.nuxt.hook('nitro:build:before', async () => {
|
||||
if (ctx.nuxt.options.dev) {
|
||||
return
|
||||
}
|
||||
const clientDist = resolve(ctx.nuxt.options.buildDir, 'dist/client')
|
||||
|
||||
// Remove public files that have been duplicated into buildAssetsDir
|
||||
// TODO: Add option to configure this behavior in vite
|
||||
const publicDir = join(ctx.nuxt.options.srcDir, ctx.nuxt.options.dir.public)
|
||||
let publicFiles: string[] = []
|
||||
if (await isDirectory(publicDir)) {
|
||||
publicFiles = readDirRecursively(publicDir).map(r => r.replace(publicDir, ''))
|
||||
for (const file of publicFiles) {
|
||||
try {
|
||||
fse.rmSync(join(clientDist, file))
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy doubly-nested /_nuxt/_nuxt files into buildAssetsDir
|
||||
// TODO: Workaround vite issue
|
||||
if (await isDirectory(clientDist)) {
|
||||
const nestedAssetsPath = withoutTrailingSlash(join(clientDist, ctx.nuxt.options.app.buildAssetsDir))
|
||||
|
||||
if (await isDirectory(nestedAssetsPath)) {
|
||||
await fse.copy(nestedAssetsPath, clientDist, { recursive: true })
|
||||
await fse.remove(nestedAssetsPath)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const onBuild = () => ctx.nuxt.callHook('build:resources', wpfs)
|
||||
|
||||
// Production build
|
||||
|
@ -6,11 +6,9 @@ import { logger, isIgnored } from '@nuxt/kit'
|
||||
import type { Options } from '@vitejs/plugin-vue'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
import { sanitizeFilePath } from 'mlly'
|
||||
import { getPort } from 'get-port-please'
|
||||
import { buildClient } from './client'
|
||||
import { buildServer } from './server'
|
||||
import virtual from './plugins/virtual'
|
||||
import { DynamicBasePlugin } from './plugins/dynamic-base'
|
||||
import { warmupViteServer } from './utils/warmup'
|
||||
import { resolveCSSOptions } from './css'
|
||||
import { composableKeysPlugin } from './plugins/composable-keys'
|
||||
@ -28,12 +26,6 @@ export interface ViteBuildContext {
|
||||
}
|
||||
|
||||
export async function bundle (nuxt: Nuxt) {
|
||||
const hmrPortDefault = 24678 // Vite's default HMR port
|
||||
const hmrPort = await getPort({
|
||||
port: hmrPortDefault,
|
||||
ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i)
|
||||
})
|
||||
|
||||
const ctx: ViteBuildContext = {
|
||||
nuxt,
|
||||
config: vite.mergeConfig(
|
||||
@ -74,20 +66,13 @@ export async function bundle (nuxt: Nuxt) {
|
||||
...Object.fromEntries([';', '(', '{', '}', ' ', '\t', '\n'].map(d => [`${d}global.`, `${d}globalThis.`])),
|
||||
preventAssignment: true
|
||||
}),
|
||||
virtual(nuxt.vfs),
|
||||
DynamicBasePlugin.vite({ sourcemap: nuxt.options.sourcemap })
|
||||
virtual(nuxt.vfs)
|
||||
],
|
||||
vue: {
|
||||
reactivityTransform: nuxt.options.experimental.reactivityTransform
|
||||
},
|
||||
server: {
|
||||
watch: { ignored: isIgnored },
|
||||
hmr: {
|
||||
// https://github.com/nuxt/framework/issues/4191
|
||||
protocol: 'ws',
|
||||
clientPort: hmrPort,
|
||||
port: hmrPort
|
||||
},
|
||||
fs: {
|
||||
allow: [
|
||||
nuxt.options.appDir
|
||||
@ -102,7 +87,6 @@ export async function bundle (nuxt: Nuxt) {
|
||||
// In build mode we explicitly override any vite options that vite is relying on
|
||||
// to detect whether to inject production or development code (such as HMR code)
|
||||
if (!nuxt.options.dev) {
|
||||
ctx.config.server.hmr = false
|
||||
ctx.config.server.watch = undefined
|
||||
ctx.config.build.watch = undefined
|
||||
}
|
||||
|
31
packages/webpack/src/plugins/dynamic-base.ts
Normal file
31
packages/webpack/src/plugins/dynamic-base.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { createUnplugin } from 'unplugin'
|
||||
import MagicString from 'magic-string'
|
||||
|
||||
interface DynamicBasePluginOptions {
|
||||
globalPublicPath?: string
|
||||
sourcemap?: boolean
|
||||
}
|
||||
|
||||
const defaults: DynamicBasePluginOptions = {
|
||||
globalPublicPath: '__webpack_public_path__',
|
||||
sourcemap: true
|
||||
}
|
||||
|
||||
export const DynamicBasePlugin = createUnplugin((options: DynamicBasePluginOptions = {}) => {
|
||||
options = { ...defaults, ...options }
|
||||
return {
|
||||
name: 'nuxt:dynamic-base-path',
|
||||
enforce: 'post',
|
||||
transform (code, id) {
|
||||
if (!id.includes('paths.mjs') || !code.includes('const appConfig = ')) {
|
||||
return
|
||||
}
|
||||
const s = new MagicString(code)
|
||||
s.append(`${options.globalPublicPath} = buildAssetsURL();\n`)
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
@ -196,7 +196,7 @@ function getOutput (ctx: WebpackConfigContext): webpack.Configuration['output']
|
||||
const { options } = ctx
|
||||
|
||||
return {
|
||||
path: resolve(options.buildDir, 'dist', ctx.isServer ? 'server' : 'client'),
|
||||
path: resolve(options.buildDir, 'dist', ctx.isServer ? 'server' : joinURL('client', options.app.buildAssetsDir)),
|
||||
filename: fileName(ctx, 'app'),
|
||||
chunkFilename: fileName(ctx, 'chunk'),
|
||||
publicPath: joinURL(options.app.baseURL, options.app.buildAssetsDir)
|
||||
|
@ -8,8 +8,8 @@ import type { Compiler, Watching } from 'webpack'
|
||||
import type { Nuxt } from '@nuxt/schema'
|
||||
import { joinURL } from 'ufo'
|
||||
import { logger, useNuxt } from '@nuxt/kit'
|
||||
import { DynamicBasePlugin } from '../../vite/src/plugins/dynamic-base'
|
||||
import { composableKeysPlugin } from '../../vite/src/plugins/composable-keys'
|
||||
import { DynamicBasePlugin } from './plugins/dynamic-base'
|
||||
import { createMFS } from './utils/mfs'
|
||||
import { registerVirtualModules } from './virtual-modules'
|
||||
import { client, server } from './configs'
|
||||
@ -35,8 +35,7 @@ export async function bundle (nuxt: Nuxt) {
|
||||
// Configure compilers
|
||||
const compilers = webpackConfigs.map((config) => {
|
||||
config.plugins.push(DynamicBasePlugin.webpack({
|
||||
sourcemap: nuxt.options.sourcemap,
|
||||
globalPublicPath: '__webpack_public_path__'
|
||||
sourcemap: nuxt.options.sourcemap
|
||||
}))
|
||||
config.plugins.push(composableKeysPlugin.webpack({
|
||||
sourcemap: nuxt.options.sourcemap,
|
||||
|
@ -3,9 +3,11 @@ import { defineConfig } from 'vite'
|
||||
import { isWindows } from 'std-env'
|
||||
|
||||
export default defineConfig({
|
||||
alias: {
|
||||
'#app': resolve('./packages/nuxt/src/app/index.ts'),
|
||||
'@nuxt/test-utils': resolve('./packages/test-utils/src/index.ts')
|
||||
resolve: {
|
||||
alias: {
|
||||
'#app': resolve('./packages/nuxt/src/app/index.ts'),
|
||||
'@nuxt/test-utils': resolve('./packages/test-utils/src/index.ts')
|
||||
}
|
||||
},
|
||||
esbuild: {
|
||||
tsconfigRaw: '{}'
|
||||
|
68
yarn.lock
68
yarn.lock
@ -48,7 +48,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/core@npm:^7.17.7, @babel/core@npm:^7.17.9":
|
||||
"@babel/core@npm:^7.17.7, @babel/core@npm:^7.18.6":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/core@npm:7.18.6"
|
||||
dependencies:
|
||||
@ -408,7 +408,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-typescript@npm:^7.16.8":
|
||||
"@babel/plugin-transform-typescript@npm:^7.18.8":
|
||||
version: 7.18.8
|
||||
resolution: "@babel/plugin-transform-typescript@npm:7.18.8"
|
||||
dependencies:
|
||||
@ -1805,7 +1805,7 @@ __metadata:
|
||||
ufo: ^0.8.5
|
||||
unbuild: latest
|
||||
unimport: ^0.4.5
|
||||
vite: ^2.9.14
|
||||
vite: ~3.0.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@ -1896,8 +1896,8 @@ __metadata:
|
||||
"@nuxt/schema": ^3.0.0-rc.6
|
||||
"@rollup/plugin-replace": ^4.0.0
|
||||
"@types/cssnano": ^5
|
||||
"@vitejs/plugin-vue": ^2.3.3
|
||||
"@vitejs/plugin-vue-jsx": ^1.3.10
|
||||
"@vitejs/plugin-vue": ^3.0.0
|
||||
"@vitejs/plugin-vue-jsx": ^2.0.0
|
||||
autoprefixer: ^10.4.7
|
||||
chokidar: ^3.5.3
|
||||
cssnano: ^5.1.12
|
||||
@ -1923,7 +1923,7 @@ __metadata:
|
||||
ufo: ^0.8.5
|
||||
unbuild: latest
|
||||
unplugin: ^0.7.2
|
||||
vite: ^2.9.14
|
||||
vite: ~3.0.0
|
||||
vite-node: ^0.18.1
|
||||
vite-plugin-checker: ^0.4.9
|
||||
vue: 3.2.37
|
||||
@ -2277,7 +2277,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rollup/pluginutils@npm:^4.1.1, @rollup/pluginutils@npm:^4.2.0, @rollup/pluginutils@npm:^4.2.1":
|
||||
"@rollup/pluginutils@npm:^4.1.1, @rollup/pluginutils@npm:^4.2.1":
|
||||
version: 4.2.1
|
||||
resolution: "@rollup/pluginutils@npm:4.2.1"
|
||||
dependencies:
|
||||
@ -3014,27 +3014,28 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitejs/plugin-vue-jsx@npm:^1.3.10":
|
||||
version: 1.3.10
|
||||
resolution: "@vitejs/plugin-vue-jsx@npm:1.3.10"
|
||||
"@vitejs/plugin-vue-jsx@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "@vitejs/plugin-vue-jsx@npm:2.0.0"
|
||||
dependencies:
|
||||
"@babel/core": ^7.17.9
|
||||
"@babel/core": ^7.18.6
|
||||
"@babel/plugin-syntax-import-meta": ^7.10.4
|
||||
"@babel/plugin-transform-typescript": ^7.16.8
|
||||
"@rollup/pluginutils": ^4.2.0
|
||||
"@babel/plugin-transform-typescript": ^7.18.8
|
||||
"@vue/babel-plugin-jsx": ^1.1.1
|
||||
hash-sum: ^2.0.0
|
||||
checksum: 868e90363e1234be43c3ced5097c8da430b9feed526c1f6c2dcc8a0546182e942018e6b5e1a0c16c66810b82cd17fa3a8e04ba969db6f253c6f7c490dce83a0b
|
||||
peerDependencies:
|
||||
vite: ^3.0.0
|
||||
vue: ^3.0.0
|
||||
checksum: 197b0dd0263b5b7df22a055155da6d9b7f21098f7de43e94589ce8daa494c12c9850157bc4e228a766fbe602aafa5935e4bef0edec9158a0507cee5581f0a067
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitejs/plugin-vue@npm:^2.3.3":
|
||||
version: 2.3.3
|
||||
resolution: "@vitejs/plugin-vue@npm:2.3.3"
|
||||
"@vitejs/plugin-vue@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "@vitejs/plugin-vue@npm:3.0.0"
|
||||
peerDependencies:
|
||||
vite: ^2.5.10
|
||||
vite: ^3.0.0
|
||||
vue: ^3.2.25
|
||||
checksum: 9303dcb9c8580d0ee9b33542639ac1a36ad9cc0e773a1f9b9b05623d74574f6a901ce781918b53f5a58eb3c6218ba96c27ef6efbf3e7ef6be16864fc1cae1626
|
||||
checksum: e2c3e31afc39f83b16174ef4742e88e07b5516688f02dcbe9814afd62c859925173ec2d6a9f088c6098eb45cdae926122308596a8ece90028ffea169f15c685f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -5708,7 +5709,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild@npm:^0.14.27, esbuild@npm:^0.14.39, esbuild@npm:^0.14.47, esbuild@npm:^0.14.49":
|
||||
"esbuild@npm:^0.14.39, esbuild@npm:^0.14.47, esbuild@npm:^0.14.49":
|
||||
version: 0.14.49
|
||||
resolution: "esbuild@npm:0.14.49"
|
||||
dependencies:
|
||||
@ -11353,7 +11354,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0":
|
||||
"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:^1.22.1":
|
||||
version: 1.22.1
|
||||
resolution: "resolve@npm:1.22.1"
|
||||
dependencies:
|
||||
@ -11366,7 +11367,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"resolve@patch:resolve@^1.1.7#~builtin<compat/resolve>, resolve@patch:resolve@^1.10.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.10.1#~builtin<compat/resolve>, resolve@patch:resolve@^1.17.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.19.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.0#~builtin<compat/resolve>":
|
||||
"resolve@patch:resolve@^1.1.7#~builtin<compat/resolve>, resolve@patch:resolve@^1.10.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.10.1#~builtin<compat/resolve>, resolve@patch:resolve@^1.17.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.19.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.1#~builtin<compat/resolve>":
|
||||
version: 1.22.1
|
||||
resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin<compat/resolve>::version=1.22.1&hash=07638b"
|
||||
dependencies:
|
||||
@ -11512,7 +11513,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rollup@npm:^2.59.0, rollup@npm:^2.76.0":
|
||||
"rollup@npm:^2.75.6, rollup@npm:^2.76.0":
|
||||
version: 2.76.0
|
||||
resolution: "rollup@npm:2.76.0"
|
||||
dependencies:
|
||||
@ -13217,19 +13218,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:^2.9.14":
|
||||
version: 2.9.14
|
||||
resolution: "vite@npm:2.9.14"
|
||||
"vite@npm:~3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "vite@npm:3.0.0"
|
||||
dependencies:
|
||||
esbuild: ^0.14.27
|
||||
esbuild: ^0.14.47
|
||||
fsevents: ~2.3.2
|
||||
postcss: ^8.4.13
|
||||
resolve: ^1.22.0
|
||||
rollup: ^2.59.0
|
||||
postcss: ^8.4.14
|
||||
resolve: ^1.22.1
|
||||
rollup: ^2.75.6
|
||||
peerDependencies:
|
||||
less: "*"
|
||||
sass: "*"
|
||||
stylus: "*"
|
||||
terser: ^5.4.0
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
@ -13240,9 +13242,11 @@ __metadata:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
terser:
|
||||
optional: true
|
||||
bin:
|
||||
vite: bin/vite.js
|
||||
checksum: f78b54f58482ea97d385e36873ae1aa4744c5e467c1d6d4e0835bd55494d2d8f6ce763f17c241c66104be687d5ee535b8e1e96c14210c9ba0c343fe78c58f694
|
||||
checksum: 4920b5b0a4d4bd4a003121b2eb6ed41ac2ab69e6ab055db645e678c14e68d6eef780362d4d482cf439b576c37fb65dc9a7ebbbf90354e7ae362034a28eac9130
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user