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)
+}