From 28bd2922fb0f663ce7ecc53ea19df4927c867305 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 17 Dec 2020 11:23:01 -0500 Subject: [PATCH] refactor: configResovled plugin hook --- packages/vite/package.json | 1 + packages/vite/src/node/config.ts | 16 ++++++++++---- packages/vite/src/node/index.ts | 4 ++-- packages/vite/src/node/plugin.ts | 19 +++++++---------- packages/vite/src/node/plugins/asset.ts | 14 +++++++------ packages/vite/src/node/plugins/css.ts | 21 +++++++++++-------- packages/vite/src/node/plugins/html.ts | 2 +- .../vite/src/node/plugins/importsAnalysis.ts | 13 +++++++++--- packages/vite/src/node/plugins/index.ts | 11 ++++------ packages/vite/src/node/server/index.ts | 8 +------ 10 files changed, 59 insertions(+), 50 deletions(-) diff --git a/packages/vite/package.json b/packages/vite/package.json index 21d985a41965cc..19603b0335565b 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -57,6 +57,7 @@ "@rollup/plugin-alias": "^3.1.1", "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^11.0.1", "@rollup/plugin-typescript": "^8.0.0", "@rollup/pluginutils": "^4.1.0", "@types/debug": "^4.1.5", diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 28d9f161ce2a08..4c0b38034cf0ce 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -88,6 +88,7 @@ export type ResolvedConfig = Readonly< Omit & { configPath: string | null root: string + command: 'build' | 'serve' mode: string env: Record plugins: readonly Plugin[] @@ -130,11 +131,11 @@ export async function resolveConfig( }) } - // run modifyConfig hooks + // run config hooks const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins] userPlugins.forEach((p) => { - if (p.modifyConfig) { - config = p.modifyConfig(config) || config + if (p.config) { + config = p.config(config) || config } }) @@ -163,6 +164,7 @@ export async function resolveConfig( ...config, configPath: configPath || null, root: resolvedRoot, + command, mode, alias: resolvedAlias, plugins: userPlugins, @@ -178,13 +180,19 @@ export async function resolveConfig( } resolved.plugins = resolvePlugins( - command, resolved, prePlugins, normalPlugins, postPlugins ) + // call configResolved hooks + userPlugins.forEach((p) => { + if (p.configResolved) { + p.configResolved(resolved) + } + }) + if (process.env.DEBUG) { debug(`using resolved config: %O`, { ...resolved, diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts index 264278c4c6826b..06cce11667c155 100644 --- a/packages/vite/src/node/index.ts +++ b/packages/vite/src/node/index.ts @@ -3,7 +3,7 @@ export * from './build' export * from './config' // additional types -export { Plugin, ConfigHook } from './plugin' +export { Plugin } from './plugin' export type { AliasOptions, ResolverFunction, @@ -25,7 +25,7 @@ export type { ModuleGraph, ModuleNode } from './server/moduleGraph' export type { ProxyOptions } from './server/middlewares/proxy' export type { TransformResult } from './server/transformRequest' export type { HmrOptions } from './server/hmr' -export { +export type { HMRPayload, ConnectedPayload, UpdatePayload, diff --git a/packages/vite/src/node/plugin.ts b/packages/vite/src/node/plugin.ts index ece99b2c445277..d970636932377c 100644 --- a/packages/vite/src/node/plugin.ts +++ b/packages/vite/src/node/plugin.ts @@ -4,8 +4,7 @@ import { ServerHook, ViteDevServer } from './server' import { BuildHook } from './build' import { IndexHtmlTransform } from './plugins/html' import { ModuleNode } from './server/moduleGraph' - -export type ConfigHook = (config: UserConfig) => UserConfig | void +import { ResolvedConfig } from './' /** * Vite plugins support a subset of Rollup plugin API with a few extra @@ -48,17 +47,15 @@ export interface Plugin extends RollupPlugin { * Note user plugins are resolved before this hook so adding plugins inside * a plugin's modifyConfig hook will have no effect. */ - modifyConfig?: ConfigHook + config?: (config: UserConfig) => UserConfig | null | void + /** + * Use this hook to read and store the final resolved vite config. + */ + configResolved?: (config: ResolvedConfig) => void /** * Configure the vite server. The hook receives the {@link ViteDevServer} - * instance which exposes the following: - * - * - `config`: resolved project config - * - `httpServer`: native http server - * - `app`: the connect middleware app - * - `watcher`: the chokidar file watcher - * - `ws`: a websocket server that can send messages to the client - * - `container`: the plugin container + * instance. This can also be used to store a reference to the server + * for use in other hooks. * * The hooks will be called before internal middlewares are applied. A hook * can return a post hook that will be called after internal middlewares diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 4799cb6c3ecdac..b7b97f3a87718c 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -1,10 +1,11 @@ import chalk from 'chalk' +import path from 'path' import fs, { promises as fsp } from 'fs' import qs from 'querystring' import { Plugin } from '../plugin' import { ResolvedConfig } from '../config' import { createDebugger, cleanUrl } from '../utils' -import { FILE_PREFIX } from '../constants' +import slash from 'slash' const debug = createDebugger('vite:asset') @@ -22,7 +23,7 @@ const assetsRE = new RegExp( /** * Also supports loading plain strings with import text from './foo.txt?raw' */ -export function assetPlugin(config: ResolvedConfig, isBuild: boolean): Plugin { +export function assetPlugin(config: ResolvedConfig): Plugin { return { name: 'vite:asset', async load(id) { @@ -37,7 +38,7 @@ export function assetPlugin(config: ResolvedConfig, isBuild: boolean): Plugin { return } - if (!isBuild) { + if (config.command === 'serve') { if (fs.existsSync(file)) { if (isRawRequest) { debug(`[raw] ${chalk.dim(file)}`) @@ -47,9 +48,10 @@ export function assetPlugin(config: ResolvedConfig, isBuild: boolean): Plugin { )}` } else { debug(`[import] ${chalk.dim(file)}`) - // return the location of the file. during dev, this will be - // the /@fs/ prefixed path as a string. - return `export default ${JSON.stringify(FILE_PREFIX + id)}` + // return the url of the file relative to served root. + return `export default ${JSON.stringify( + `/` + slash(path.relative(config.root, id)) + )}` } } } diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 212a282c76dd74..22f07df08746c3 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -3,7 +3,6 @@ import path from 'path' import fs, { promises as fsp } from 'fs' import { Plugin } from '../plugin' import { ResolvedConfig } from '../config' -import { useServer } from '../server' import postcssrc from 'postcss-load-config' import merge from 'merge-source-map' import { RollupError, SourceMap } from 'rollup' @@ -11,6 +10,7 @@ import { dataToEsm } from '@rollup/pluginutils' import chalk from 'chalk' import { CLIENT_PUBLIC_PATH } from '../constants' import { Result } from 'postcss' +import { ViteDevServer } from '../' const debug = createDebugger('vite:css') @@ -44,10 +44,16 @@ export const unwrapCSSProxy = (id: string) => { const cssModulesCache = new Map>() -export function cssPlugin(config: ResolvedConfig, isBuild: boolean): Plugin { +export function cssPlugin(config: ResolvedConfig): Plugin { + let server: ViteDevServer + return { name: 'vite:css', + configureServer(_server) { + server = _server + }, + // server only - this loads *.css.js requests which are a result // of import rewriting in ./rewrite.ts async load(id) { @@ -69,9 +75,9 @@ export function cssPlugin(config: ResolvedConfig, isBuild: boolean): Plugin { cssModulesCache.set(id, modules) } - if (!isBuild) { + if (config.command === 'serve') { // server only logic for handling CSS @import dependency hmr - const { moduleGraph } = useServer(this)! + const { moduleGraph } = server const thisModule = moduleGraph.getModuleById(id)! // CSS modules cannot self-accept since it exports values const isSelfAccepting = !modules @@ -116,10 +122,7 @@ export function cssPlugin(config: ResolvedConfig, isBuild: boolean): Plugin { /** * Plugin for converting css.js proxy modules into actual javascript. */ -export function cssPostPlugin( - config: ResolvedConfig, - isBuild: boolean -): Plugin { +export function cssPostPlugin(config: ResolvedConfig): Plugin { return { name: 'vite:css-post', transform(css, id) { @@ -148,7 +151,7 @@ export function cssPostPlugin( ].join('\n') } - if (isBuild) { + if (config.command === 'build') { // TODO collect css for extraction } diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 4cc21744ed60dd..1ab9b75566e9c4 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -5,7 +5,7 @@ import { OutputBundle } from 'rollup' import { cleanUrl } from '../utils' const htmlProxyRE = /\?html-proxy&index=(\d+)\.js$/ -export const isHTMLProxy = (id: string) => htmlProxyRE +export const isHTMLProxy = (id: string) => htmlProxyRE.test(id) export const scriptRE = /(]*type\s*=\s*(?:"module"|'module')[^>]*>)([\s\S]*?)<\/script>/gm export function htmlPlugin(): Plugin { diff --git a/packages/vite/src/node/plugins/importsAnalysis.ts b/packages/vite/src/node/plugins/importsAnalysis.ts index 709a1628435859..41bb8a8132e72d 100644 --- a/packages/vite/src/node/plugins/importsAnalysis.ts +++ b/packages/vite/src/node/plugins/importsAnalysis.ts @@ -1,7 +1,6 @@ import path from 'path' import { Plugin } from '../plugin' import { ResolvedConfig } from '../config' -import { useServer } from '../server' import chalk from 'chalk' import MagicString from 'magic-string' import { init, parse, ImportSpecifier } from 'es-module-lexer' @@ -12,6 +11,7 @@ import { debugHmr, handlePrunedModules } from '../server/hmr' import { FILE_PREFIX, CLIENT_PUBLIC_PATH } from '../constants' import { RollupError } from 'rollup' import { FAILED_RESOLVE } from './resolve' +import { ViteDevServer } from '../' const isDebug = !!process.env.DEBUG const debugRewrite = createDebugger('vite:rewrite') @@ -49,8 +49,15 @@ const canSkip = (id: string) => skipRE.test(id) || isCSSRequest(id) * ``` */ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { + let server: ViteDevServer + return { name: 'vite:imports', + + configureServer(_server) { + server = _server + }, + async transform(source, importer) { const prettyImporter = prettifyUrl(slash(importer), config.root) @@ -90,7 +97,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { let s: MagicString | undefined const str = () => s || (s = new MagicString(source)) // vite-only server context - const { moduleGraph } = useServer(this)! + const { moduleGraph } = server // since we are already in the transform phase of the importer, it must // have been loaded so its entry is guaranteed in the module graph. const importerModule = moduleGraph.getModuleById(importer)! @@ -251,7 +258,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { isSelfAccepting ) if (hasHMR && prunedImports) { - handlePrunedModules(prunedImports, useServer(this)!) + handlePrunedModules(prunedImports, server) } } diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index fc8e4c1a7fe1bc..c738622a1b1113 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -10,28 +10,25 @@ import { clientInjectionsPlugin } from './clientInjections' import { htmlPlugin } from './html' export function resolvePlugins( - command: 'build' | 'serve', config: ResolvedConfig, prePlugins: Plugin[], normalPlugins: Plugin[], postPlugins: Plugin[] ): Plugin[] { - const isBuild = command === 'build' - return [ aliasPlugin({ entries: config.alias }), ...prePlugins, resolvePlugin(config.root), htmlPlugin(), - cssPlugin(config, isBuild), + cssPlugin(config), esbuildPlugin(config.esbuild || {}), jsonPlugin(), - assetPlugin(config, isBuild), + assetPlugin(config), ...normalPlugins, ...postPlugins, - cssPostPlugin(config, isBuild), + cssPostPlugin(config), // internal server-only plugins are always applied after everything else - ...(isBuild + ...(config.command === 'build' ? [] : [clientInjectionsPlugin(config), importAnalysisPlugin(config)]) ].filter(Boolean) as Plugin[] diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index d2af690ddbc7d0..764d03e8e2d5be 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -29,7 +29,7 @@ import { errorMiddleware } from './middlewares/error' import { handleHMRUpdate, HmrOptions } from './hmr' import { openBrowser } from './openBrowser' import launchEditorMiddleware from 'launch-editor-middleware' -import { PluginContext, TransformResult } from 'rollup' +import { TransformResult } from 'rollup' import { transformRequest } from './transformRequest' import { transformWithEsbuild, @@ -166,12 +166,6 @@ export interface ViteDevServer { ): Promise } -// a type hack to allow using the server inside plugins (which has rollup's -// PluginContext `this` type) -export function useServer(ctx: PluginContext): ViteDevServer | undefined { - return (ctx as any).server -} - export async function createServer( inlineConfig: UserConfig = {}, mode = 'development',