Skip to content

Commit

Permalink
refactor: use query to mark css imports
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Dec 18, 2020
1 parent bd7c846 commit 4f7de31
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 58 deletions.
4 changes: 2 additions & 2 deletions packages/playground/sfcs/PreProcessors.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ p.pug-less
</template>

<style lang="scss">
$color: magenta;
$color: red;
.pug {
color: $color;
}
</style>

<style lang="less" scoped>
@preprocess-custom-color: green;
@preprocess-custom-color: blue;
.pug-less {
color: @preprocess-custom-color;
Expand Down
41 changes: 11 additions & 30 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createDebugger, isExternalUrl, asyncReplace } from '../utils'
import path from 'path'
import fs, { promises as fsp } from 'fs'
import { Plugin } from '../plugin'
import { ResolvedConfig } from '../config'
import postcssrc from 'postcss-load-config'
Expand Down Expand Up @@ -30,17 +29,14 @@ export interface CSSModulesOptions {
localsConvention?: 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly'
}

export const cssPreprocessLangRE = /\.(css|less|sass|scss|styl|stylus|postcss)($|\?)/
const cssLangRE = /\.(css|less|sass|scss|styl|stylus|postcss)($|\?)/
const cssImportRE = /[\?&]import($|&)/

export const isCSSRequest = (request: string) =>
cssPreprocessLangRE.test(request)
cssLangRE.test(request) && !cssImportRE.test(request)

export const isCSSProxy = (id: string) => isCSSRequest(id.slice(0, -3))

export const unwrapCSSProxy = (id: string) => {
const unwrapped = id.slice(0, -3)
return isCSSRequest(unwrapped) ? unwrapped : id
}
export const isCSSProxy = (request: string) =>
cssLangRE.test(request) && cssImportRE.test(request)

const cssModulesCache = new Map<string, Record<string, string>>()

Expand All @@ -54,21 +50,11 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
server = _server
},

// server only - this loads *.css.js requests which are a result
// of import rewriting in ./rewrite.ts
async load(id) {
if (isCSSRequest((id = id.slice(0, -3))) && fs.existsSync(id)) {
return fsp.readFile(id, 'utf-8')
}
},

async transform(raw, id) {
const isRawRequest = isCSSRequest(id)
const isProxyRequest = isCSSProxy(id)

if (!isProxyRequest && !isRawRequest) {
if (!cssLangRE.test(id)) {
return
}
const isProxyRequest = cssImportRE.test(id)

let { code: css, modules, deps } = await compileCSS(id, raw, config)
if (modules) {
Expand Down Expand Up @@ -127,13 +113,10 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
return {
name: 'vite:css-post',
transform(css, id) {
const isRawRequest = isCSSRequest(id)
const isProxyRequest = isCSSProxy(id)

if (!isProxyRequest && !isRawRequest) {
if (!cssLangRE.test(id)) {
return
}

const isProxyRequest = cssImportRE.test(id)
const modules = cssModulesCache.get(id)
const modulesCode = modules && dataToEsm(modules, { namedExports: true })

Expand Down Expand Up @@ -172,16 +155,14 @@ async function compileCSS(
modules?: Record<string, string>
deps?: Set<string>
}> {
id = unwrapCSSProxy(id)
const { modules: modulesOptions, preprocessorOptions } = config.css || {}
const isModule =
modulesOptions !== false &&
id.replace(cssPreprocessLangRE, '').endsWith('.module')
modulesOptions !== false && id.replace(cssLangRE, '').endsWith('.module')
// although at serve time it can work without processing, we do need to
// crawl them in order to register watch dependencies.
const needInlineImport = code.includes('@import')
const postcssConfig = await loadPostcssConfig(config.root)
const lang = id.match(cssPreprocessLangRE)?.[1]
const lang = id.match(cssLangRE)?.[1]

// 1. plain css that needs no processing
if (lang === 'css' && !postcssConfig && !isModule && !needInlineImport) {
Expand Down
9 changes: 3 additions & 6 deletions packages/vite/src/node/plugins/importsAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,12 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
url = FILE_PREFIX + slash(resolved.id)
}

// resolve CSS imports into js (so it differentiates from actual
// CSS references from <link>)
// mark CSS imports with ?import query
if (isCSSRequest(resolved.id)) {
const [, query] = url.split('?')
if (query !== 'raw') {
url += '.js'
}
url = injectQuery(url, 'import')
}

// mark asset imports with ?asset query
if (config.assetsInclude(cleanUrl(resolved.id))) {
url = injectQuery(url, `asset`)
}
Expand Down
18 changes: 5 additions & 13 deletions packages/vite/src/node/plugins/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { createDebugger } from '../utils'
import { Plugin } from '..'
import chalk from 'chalk'
import { FILE_PREFIX } from '../constants'
import { isCSSProxy } from './css'

export const FAILED_RESOLVE = `__vite_failed_resolve__`

Expand All @@ -21,13 +20,6 @@ export function resolvePlugin(root: string, allowUrls = true): Plugin {
return {
name: 'vite:resolve',
resolveId(id, importer) {
const isCSSProxyId = isCSSProxy(id)
if (isCSSProxyId) {
id = id.slice(0, -3)
}
const restoreCSSProxy = (res: string) =>
isCSSProxyId ? res + '.js' : res

let res
if (allowUrls && id.startsWith(FILE_PREFIX)) {
// explicit fs paths that starts with /@fs/*
Expand All @@ -39,7 +31,7 @@ export function resolvePlugin(root: string, allowUrls = true): Plugin {
isDebug && debug(`[@fs] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
// always return here even if res doesn't exist since /@fs/ is explicit
// if the file doesn't exist it should be a 404
return restoreCSSProxy(res || fsPath)
return res || fsPath
}

// URL
Expand All @@ -48,7 +40,7 @@ export function resolvePlugin(root: string, allowUrls = true): Plugin {
const fsPath = path.resolve(root, id.slice(1))
if ((res = tryFsResolve(fsPath))) {
isDebug && debug(`[url] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
return restoreCSSProxy(res)
return res
}
}

Expand All @@ -57,22 +49,22 @@ export function resolvePlugin(root: string, allowUrls = true): Plugin {
const fsPath = path.resolve(path.dirname(importer), id)
if ((res = tryFsResolve(fsPath))) {
isDebug && debug(`[relative] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
return restoreCSSProxy(res)
return res
}
}

// absolute fs paths
if (path.isAbsolute(id) && (res = tryFsResolve(id))) {
isDebug && debug(`[fs] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
return restoreCSSProxy(res)
return res
}

// bare package imports, perform node resolve
if (
/^[\w@]/.test(id) &&
(res = tryNodeResolve(id, importer ? path.dirname(importer) : root))
) {
return restoreCSSProxy(res)
return res
}

isDebug && debug(`[fallthrough] ${chalk.dim(id)}`)
Expand Down
8 changes: 3 additions & 5 deletions packages/vite/src/node/server/moduleGraph.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { extname } from 'path'
import { FAILED_RESOLVE } from '../plugins/resolve'
import { isCSSRequest, unwrapCSSProxy } from '../plugins/css'
import { isCSSRequest } from '../plugins/css'
import { cleanUrl, removeTimestampQuery } from '../utils'
import { TransformResult } from './transformRequest'
import { PluginContainer } from './pluginContainer'
Expand Down Expand Up @@ -116,7 +116,7 @@ export class ModuleGraph {
this.urlToModuleMap.set(url, mod)
mod.id = resolvedId
this.idToModuleMap.set(resolvedId, mod)
const file = (mod.file = unwrapCSSProxy(cleanUrl(resolvedId)))
const file = (mod.file = cleanUrl(resolvedId))
let fileMappedMdoules = this.fileToModulesMap.get(file)
if (!fileMappedMdoules) {
fileMappedMdoules = new Set()
Expand Down Expand Up @@ -157,9 +157,7 @@ export class ModuleGraph {
url = removeTimestampQuery(url)
const resolvedId = (await this.container.resolveId(url)).id
if (resolvedId === FAILED_RESOLVE) {
throw Error(
`Failed to resolve url: ${unwrapCSSProxy(url)}\nDoes the file exist?`
)
throw Error(`Failed to resolve url: ${url}\nDoes the file exist?`)
}
const ext = extname(cleanUrl(resolvedId))
const [pathname, query] = url.split('?')
Expand Down
1 change: 1 addition & 0 deletions packages/vite/src/node/server/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export function send(
return res.end()
}

if (type === 'css') debugger
res.setHeader('Content-Type', alias[type] || type)
res.setHeader('Cache-Control', 'no-cache')
res.setHeader('Etag', etag)
Expand Down
3 changes: 1 addition & 2 deletions packages/vite/src/node/server/transformRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import fs from 'fs'
import getEtag from 'etag'
import { SourceDescription, SourceMap } from 'rollup'
import { ViteDevServer } from '..'
import { unwrapCSSProxy } from '../plugins/css'
import chalk from 'chalk'
import {
createDebugger,
Expand Down Expand Up @@ -39,7 +38,7 @@ export async function transformRequest(

// resolve
const id = (await container.resolveId(url)).id
const file = unwrapCSSProxy(cleanUrl(id))
const file = cleanUrl(id)

let code = null
let map: SourceDescription['map'] = null
Expand Down

0 comments on commit 4f7de31

Please sign in to comment.