Skip to content

Commit

Permalink
refactor: apply postcss-import in compileCss + remove precprocessor @…
Browse files Browse the repository at this point in the history
…import tests
  • Loading branch information
yyx990803 committed May 29, 2020
1 parent 623c0ef commit e111c60
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 156 deletions.
6 changes: 3 additions & 3 deletions playground/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<TestPostCss />
<TestScopedCss />
<TestCssModules />
<TestCssImportBoundary/>
<TestCssAtImport/>
<TestPreprocessors />
<TestAssets />
<TestSrcImport />
Expand Down Expand Up @@ -43,7 +43,7 @@ import TestJsx from './TestJsx.vue'
import TestAlias from './TestAlias.vue'
import TestTransform from './TestTransform.vue'
import TestRewriteOptimized from "./rewrite-optimized/TestRewriteOptimized.vue";
import TestCssImportBoundary from './css-@import/testCssImportBoundary.vue'
import TestCssAtImport from './css-@import/TestCssAtImport.vue'
export default {
data: () => ({
Expand All @@ -58,7 +58,7 @@ export default {
TestScopedCss,
TestCssModules,
TestPreprocessors,
TestCssImportBoundary,
TestCssAtImport,
TestSrcImport,
TestAssets,
TestJsonImport,
Expand Down
19 changes: 19 additions & 0 deletions playground/css-@import/TestCssAtImport.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<h2>CSS @import</h2>
<div class="sfc-style-at-import">
&lt;style @import &gt; this should be red
</div>
<div class="script-at-import">
&lt;script @import &gt; this should be green
</div>
</template>

<style scoped>
@import './testCssAtImportFromStyle.css';
</style>

<script>
import './testCssAtImportFromScript.css'
export default {}
</script>
3 changes: 3 additions & 0 deletions playground/css-@import/imported.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.script-at-import {
color: green;
}
1 change: 1 addition & 0 deletions playground/css-@import/testCssAtImportFromScript.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import './imported.css'
3 changes: 3 additions & 0 deletions playground/css-@import/testCssAtImportFromStyle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.sfc-style-at-import {
color: red;
}
3 changes: 0 additions & 3 deletions playground/css-@import/testCssImportBoundary.css

This file was deleted.

5 changes: 0 additions & 5 deletions playground/css-@import/testCssImportBoundary.module.scss

This file was deleted.

1 change: 0 additions & 1 deletion playground/css-@import/testCssImportBoundary.scss

This file was deleted.

31 changes: 0 additions & 31 deletions playground/css-@import/testCssImportBoundary.vue

This file was deleted.

11 changes: 2 additions & 9 deletions src/node/build/buildPluginCss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import {
urlRE,
compileCss,
cssPreprocessLangRE,
rewriteCssUrls,
parseCssImport
rewriteCssUrls
} from '../utils/cssUtils'
import { SFCStyleCompileResults } from '@vue/compiler-sfc'

Expand All @@ -32,16 +31,10 @@ export const createBuildCssPlugin = (
name: 'vite:css',
async transform(css: string, id: string) {
if (id.endsWith('.css') || cssPreprocessLangRE.test(id)) {
const res = await parseCssImport(css, id)
if (typeof res === 'string') {
css = res
} else {
css = res.css
}
const result = await compileCss(root, id, {
id: '',
source: css,
filename: path.basename(id),
filename: id,
scoped: false,
modules: id.endsWith('.module.css'),
preprocessLang: id.replace(cssPreprocessLangRE, '$2') as any
Expand Down
16 changes: 2 additions & 14 deletions src/node/server/serverPluginCss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
cssImportMap,
cssPreprocessLangRE,
getCssImportBoundaries,
parseCssImport,
recordCssImportPlain,
rewriteCssUrls
} from '../utils/cssUtils'
import qs from 'querystring'
Expand Down Expand Up @@ -78,7 +76,7 @@ export const cssPlugin: ServerPlugin = ({ root, app, watcher, resolver }) => {
return
}
// handle HMR for module.css
// it cannot process with normal css, the class which in module.css maybe removed
// it cannot be handled as normal css because the js exports may change
if (filePath.endsWith('.module.css')) {
moduleCssUpdate(filePath)
return
Expand Down Expand Up @@ -130,17 +128,7 @@ export const cssPlugin: ServerPlugin = ({ root, app, watcher, resolver }) => {
}

async function processCss(root: string, ctx: Context) {
let css = (await readBody(ctx.body))!
// should parser import before compile
const res = await parseCssImport(css, resolver.requestToFile(ctx.path))

if (typeof res === 'string') {
css = res
} else {
css = res.css
recordCssImportPlain(res.messages)
}

const css = (await readBody(ctx.body))!
const result = await compileCss(root, ctx.path, {
id: '',
source: css,
Expand Down
24 changes: 3 additions & 21 deletions src/node/server/serverPluginVue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,7 @@ import { Context } from 'koa'
import { transform } from '../esbuildService'
import { InternalResolver } from '../resolver'
import { seenUrls } from './serverPluginServeStatic'
import {
codegenCss,
compileCss,
parseCssImport,
recordCssImportPlain,
rewriteCssUrls
} from '../utils/cssUtils'
import { codegenCss, compileCss, rewriteCssUrls } from '../utils/cssUtils'
import { parse } from '../utils/babelParse'
import MagicString from 'magic-string'
import { resolveImport } from './serverPluginModuleRewrite'
Expand Down Expand Up @@ -520,21 +514,9 @@ async function compileSFCStyle(
const start = Date.now()

const { generateCodeFrame } = resolveCompiler(root)

let css = style.content
// should parser css import before compile
const res = await parseCssImport(css, `${filePath}?type=style&index=${index}`)

if (typeof res === 'string') {
css = res
} else {
css = res.css
recordCssImportPlain(res.messages)
}

const result = (await compileCss(root, publicPath, {
source: css,
filename: filePath,
source: style.content,
filename: filePath + `?type=style&index=${index}`,
id: ``, // will be computed in compileCss
scoped: style.scoped != null,
modules: style.module != null,
Expand Down
73 changes: 37 additions & 36 deletions src/node/utils/cssUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {
SFCStyleCompileResults
} from '@vue/compiler-sfc'
import { hmrClientPublicPath } from '../server/serverPluginHmr'
import postcss, { Result, ResultMessage } from 'postcss'
import cssImport from 'postcss-import'

export const urlRE = /(url\(\s*['"]?)([^"')]+)(["']?\s*\))/
export const cssPreprocessLangRE = /(.+).(less|sass|scss|styl|stylus)$/

Expand Down Expand Up @@ -55,15 +54,24 @@ export async function compileCss(
}: SFCAsyncStyleCompileOptions
): Promise<SFCStyleCompileResults | string> {
const id = hash_sum(publicPath)
const postcssConfig = await loadPostcssConfig(root)
let postcssConfig = await loadPostcssConfig(root)
const { compileStyleAsync } = resolveCompiler(root)

if (publicPath.endsWith('.css') && !modules && !postcssConfig) {
if (
publicPath.endsWith('.css') &&
!modules &&
!postcssConfig &&
!source.includes('@import')
) {
// no need to invoke compile for plain css if no postcss config is present
return source
}

return await compileStyleAsync({
const postcssOptions = postcssConfig && postcssConfig.options
const postcssPlugins = postcssConfig ? postcssConfig.plugins : []
postcssPlugins.push(require('postcss-import')())

const res = await compileStyleAsync({
source,
filename,
id: `data-v-${id}`,
Expand All @@ -72,18 +80,32 @@ export async function compileCss(
modulesOptions: {
generateScopedName: `[local]_${id}`
},

preprocessLang: preprocessLang,
preprocessCustomRequire: (id: string) => require(resolveFrom(root, id)),
...(postcssConfig
? {
postcssOptions: postcssConfig.options,
postcssPlugins: postcssConfig.plugins
}
: {}),
preprocessOptions: {
includePaths: ['node_modules']
}
},

postcssOptions,
postcssPlugins
})

// record css import dependencies
if (res.rawResult) {
res.rawResult.messages.forEach((msg) => {
let { type, file, parent } = msg
if (type === 'dependency') {
if (cssImportMap.has(file)) {
cssImportMap.get(file)!.add(parent)
} else {
cssImportMap.set(file, new Set([parent]))
}
}
})
}

return res
}

export function codegenCss(
Expand Down Expand Up @@ -133,34 +155,13 @@ export const cssImportMap = new Map<
Set<string /*filePath*/>
>()

export async function parseCssImport(
css: string,
filePath: string
): Promise<string | Result> {
if (!css.includes('@import')) {
return css
}
return await postcss().use(cssImport()).process(css, { from: filePath })
}

export function recordCssImportPlain(messages: ResultMessage[]) {
messages.forEach((msg) => {
let { type, file, parent } = msg
if (type === 'dependency') {
if (cssImportMap.has(file)) {
cssImportMap.get(file)!.add(parent)
} else {
cssImportMap.set(file, new Set([parent]))
}
}
})
}

export function getCssImportBoundaries(
filePath: string,
boundaries = new Set<string>()
) {
if (!cssImportMap.has(filePath)) return boundaries
if (!cssImportMap.has(filePath)) {
return boundaries
}
const importers = cssImportMap.get(filePath)!
for (const importer of importers) {
boundaries.add(importer)
Expand Down
56 changes: 23 additions & 33 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,39 +184,6 @@ describe('vite', () => {
})
}

test('SFC normal css w/ @import', async () => {
const el = await page.$('.style-at-import')
expect(await getComputedColor(el)).toBe('rgb(255, 0, 0)')
if (!isBuild) {
await updateFile('css-@import/testCssImportBoundary.css', (content) =>
content.replace('red', 'rgb(0, 0, 0)')
)
await expectByPolling(() => getComputedColor(el), 'rgb(0, 0, 0)')
}
})

test('SFC preprocessor w/ @import', async () => {
const el = await page.$('.style-at-import-scss')
expect(await getComputedColor(el)).toBe('rgb(255, 0, 0)')
if (!isBuild) {
await updateFile('css-@import/testCssImportBoundary.scss', (content) =>
content.replace('red', 'rgb(0, 0, 0)')
)
await expectByPolling(() => getComputedColor(el), 'rgb(0, 0, 0)')
}
})

// test('SFC <style module> w/ @import', async () => {
// const el = await page.$('#css-modules-at-import-sfc')
// expect(await getComputedColor(el)).toBe('rgb(255, 0, 0)')
// if (!isBuild) {
// await updateFile('css-@import/testCssImportBoundary.scss', (content) =>
// content.replace('red', 'rgb(0, 0, 0)')
// )
// await expectByPolling(() => getComputedColor(el), 'rgb(0, 0, 0)')
// }
// })

test('CSS import w/ PostCSS', async () => {
const el = await page.$('.postcss-from-css')
expect(await getComputedColor(el)).toBe('rgb(255, 0, 0)')
Expand Down Expand Up @@ -267,6 +234,29 @@ describe('vite', () => {
}
})

test('CSS @import', async () => {
const el = await page.$('.script-at-import')
expect(await getComputedColor(el)).toBe('rgb(0, 128, 0)')
if (!isBuild) {
await updateFile('css-@import/imported.css', (content) =>
content.replace('green', 'rgb(0, 0, 0)')
)
await expectByPolling(() => getComputedColor(el), 'rgb(0, 0, 0)')
}
})

test('SFC <style> w/ @import', async () => {
const el = await page.$('.sfc-style-at-import')
expect(await getComputedColor(el)).toBe('rgb(255, 0, 0)')
if (!isBuild) {
await updateFile(
'css-@import/testCssAtImportFromStyle.css',
(content) => content.replace('red', 'rgb(0, 0, 0)')
)
await expectByPolling(() => getComputedColor(el), 'rgb(0, 0, 0)')
}
})

test('import *.module.css', async () => {
const el = await page.$('.css-modules-import')
expect(await getComputedColor(el)).toBe('rgb(255, 140, 0)')
Expand Down

0 comments on commit e111c60

Please sign in to comment.