From 7a608094841d03ce1ff6ba58e1b675abdd39e971 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Mon, 1 Jun 2020 22:54:00 +0800 Subject: [PATCH] feat: recalculate import graph when import change --- src/node/server/serverPluginCss.ts | 10 +++++-- src/node/server/serverPluginVue.ts | 11 +++++-- src/node/utils/cssUtils.ts | 47 +++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/node/server/serverPluginCss.ts b/src/node/server/serverPluginCss.ts index fede991b46d6c5..c8205121b31043 100644 --- a/src/node/server/serverPluginCss.ts +++ b/src/node/server/serverPluginCss.ts @@ -5,9 +5,10 @@ import { cleanUrl, isImportRequest, readBody } from '../utils' import { srcImportMap, vueCache } from './serverPluginVue' import { compileCss, - cssImportMap, + cssImporterMap, cssPreprocessLangRE, getCssImportBoundaries, + recordCssImportChain, rewriteCssUrls, isCSSRequest } from '../utils/cssUtils' @@ -44,7 +45,7 @@ export const cssPlugin: ServerPlugin = ({ root, app, watcher, resolver }) => { /** filter unused files */ if ( - !cssImportMap.has(filePath) && + !cssImporterMap.has(filePath) && !processedCSS.has(publicPath) && !srcImportMap.has(filePath) ) { @@ -135,10 +136,11 @@ export const cssPlugin: ServerPlugin = ({ root, app, watcher, resolver }) => { } const css = (await readBody(ctx.body))! + const filePath = resolver.requestToFile(ctx.path) const result = await compileCss(root, ctx.path, { id: '', source: css, - filename: resolver.requestToFile(ctx.path), + filename: filePath, scoped: false, modules: ctx.path.includes('.module'), preprocessLang: ctx.path.replace(cssPreprocessLangRE, '$2') as any, @@ -151,6 +153,8 @@ export const cssPlugin: ServerPlugin = ({ root, app, watcher, resolver }) => { return res } + recordCssImportChain(result.dependencies, filePath) + if (result.errors.length) { console.error(`[vite] error applying css transforms: `) result.errors.forEach(console.error) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 53abf07aa0a752..e33072b9b2bbee 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -28,7 +28,11 @@ import { transform } from '../esbuildService' import { InternalResolver } from '../resolver' import { seenUrls } from './serverPluginServeStatic' import { codegenCss } from './serverPluginCss' -import { compileCss, rewriteCssUrls } from '../utils/cssUtils' +import { + compileCss, + recordCssImportChain, + rewriteCssUrls +} from '../utils/cssUtils' import { parse } from '../utils/babelParse' import MagicString from 'magic-string' import { resolveImport } from './serverPluginModuleRewrite' @@ -609,9 +613,10 @@ async function compileSFCStyle( const start = Date.now() const { generateCodeFrame } = resolveCompiler(root) + const resource = filePath + `?type=style&index=${index}` const result = (await compileCss(root, publicPath, { source: style.content, - filename: filePath + `?type=style&index=${index}`, + filename: resource, id: ``, // will be computed in compileCss scoped: style.scoped != null, vars: style.vars != null, @@ -620,6 +625,8 @@ async function compileSFCStyle( preprocessOptions })) as SFCStyleCompileResults + recordCssImportChain(result.dependencies, resource) + if (result.errors.length) { console.error(chalk.red(`\n[vite] SFC style compilation error: `)) result.errors.forEach((e: any) => { diff --git a/src/node/utils/cssUtils.ts b/src/node/utils/cssUtils.ts index 715f104d0e55ef..48d468363bec58 100644 --- a/src/node/utils/cssUtils.ts +++ b/src/node/utils/cssUtils.ts @@ -85,7 +85,7 @@ export async function compileCss( plugins: postcssPlugins } = await resolvePostcssOptions(root, isBuild) - const res = await compileStyleAsync({ + return await compileStyleAsync({ source, filename, id: `data-v-${id}`, @@ -106,15 +106,6 @@ export async function compileCss( postcssOptions, postcssPlugins }) - - res.dependencies.forEach((dependency) => { - if (cssImportMap.has(dependency)) { - cssImportMap.get(dependency)!.add(filename) - } else { - cssImportMap.set(dependency, new Set([filename])) - } - }) - return res } // postcss-load-config doesn't expose Result type @@ -156,7 +147,11 @@ export async function resolvePostcssOptions(root: string, isBuild: boolean) { } } -export const cssImportMap = new Map< +export const cssImporterMap = new Map< + string /*filePath*/, + Set +>() +export const cssImporteeMap = new Map< string /*filePath*/, Set >() @@ -165,13 +160,39 @@ export function getCssImportBoundaries( filePath: string, boundaries = new Set() ) { - if (!cssImportMap.has(filePath)) { + if (!cssImporterMap.has(filePath)) { return boundaries } - const importers = cssImportMap.get(filePath)! + const importers = cssImporterMap.get(filePath)! for (const importer of importers) { boundaries.add(importer) getCssImportBoundaries(importer, boundaries) } return boundaries } + +export function recordCssImportChain(dependencies: string[], filePath: string) { + const preImportees = cssImporteeMap.get(filePath) + const currentImportees = new Set(dependencies) + // if import code change, should removed unused previous importee + if (preImportees) { + for (const preImportee of preImportees) { + if (!currentImportees.has(preImportee)) { + const importers = cssImporterMap.get(preImportee) + if (importers) { + importers.delete(filePath) + } + } + } + } + + currentImportees.forEach((dependency) => { + if (cssImporterMap.has(dependency)) { + cssImporterMap.get(dependency)!.add(filePath) + } else { + cssImporterMap.set(dependency, new Set([filePath])) + } + }) + + cssImporteeMap.set(filePath, currentImportees) +}