From 692a43a14e3dc3685acce99c9a0ea56b8a7dfa71 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sat, 8 Aug 2020 11:07:57 +0800 Subject: [PATCH] feat: support css alias close #650 --- playground/alias/TestAlias.vue | 9 ++++-- playground/alias/aliased-dir/aliased.css | 3 ++ src/node/build/buildPluginCss.ts | 25 +++++++++------ src/node/build/index.ts | 9 ++++-- src/node/server/serverPluginCss.ts | 2 +- src/node/server/serverPluginVue.ts | 4 ++- src/node/utils/cssUtils.ts | 39 +++++++++++++++++++++--- test/test.js | 3 ++ 8 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 playground/alias/aliased-dir/aliased.css diff --git a/playground/alias/TestAlias.vue b/playground/alias/TestAlias.vue index dac3663318149a..9bbbb3d930c542 100644 --- a/playground/alias/TestAlias.vue +++ b/playground/alias/TestAlias.vue @@ -1,7 +1,7 @@ @@ -21,3 +21,8 @@ export default { }) } + + diff --git a/playground/alias/aliased-dir/aliased.css b/playground/alias/aliased-dir/aliased.css new file mode 100644 index 00000000000000..1d04fb79f06684 --- /dev/null +++ b/playground/alias/aliased-dir/aliased.css @@ -0,0 +1,3 @@ +.alias-css { + color: red; +} diff --git a/src/node/build/buildPluginCss.ts b/src/node/build/buildPluginCss.ts index 27175d4d070a76..aec219a7e37fe0 100644 --- a/src/node/build/buildPluginCss.ts +++ b/src/node/build/buildPluginCss.ts @@ -17,6 +17,7 @@ import { } from '@vue/compiler-sfc' import chalk from 'chalk' import { CssPreprocessOptions } from '../config' +import { InternalResolver } from '../resolver' const debug = require('debug')('vite:build:css') @@ -34,16 +35,19 @@ interface BuildCssOption { modulesOptions?: SFCAsyncStyleCompileOptions['modulesOptions'] } -export const createBuildCssPlugin = ({ - root, - publicBase, - assetsDir, - minify = false, - inlineLimit = 0, - cssCodeSplit = true, - preprocessOptions, - modulesOptions = {} -}: BuildCssOption): Plugin => { +export const createBuildCssPlugin = ( + resolver: InternalResolver, + { + root, + publicBase, + assetsDir, + minify = false, + inlineLimit = 0, + cssCodeSplit = true, + preprocessOptions, + modulesOptions = {} + }: BuildCssOption +): Plugin => { const styles: Map = new Map() const assets = new Map() let staticCss = '' @@ -63,6 +67,7 @@ export const createBuildCssPlugin = ({ const result = isVueStyle ? css : await compileCss( + resolver, root, id, { diff --git a/src/node/build/index.ts b/src/node/build/index.ts index 272deebd3e6138..7f9c11464a51ab 100644 --- a/src/node/build/index.ts +++ b/src/node/build/index.ts @@ -151,7 +151,9 @@ export async function createBaseRollupPlugins( // vite:esbuild enableEsbuild ? await createEsbuildPlugin(options.jsx) : null, // vue - enableRollupPluginVue ? await createVuePlugin(root, options) : null, + enableRollupPluginVue + ? await createVuePlugin(resolver, root, options) + : null, require('@rollup/plugin-json')({ preferConst: true, indent: ' ', @@ -181,6 +183,7 @@ export async function createBaseRollupPlugins( } async function createVuePlugin( + resolver: InternalResolver, root: string, { vueCustomBlockTransforms = {}, @@ -195,7 +198,7 @@ async function createVuePlugin( const { options: postcssOptions, plugins: postcssPlugins - } = await resolvePostcssOptions(root, true) + } = await resolvePostcssOptions(resolver, root, true) if (typeof vueTransformAssetUrls === 'object') { vueTransformAssetUrls = { @@ -378,7 +381,7 @@ export async function build(options: BuildConfig): Promise { sourcemap ), // vite:css - createBuildCssPlugin({ + createBuildCssPlugin(resolver, { root, publicBase: publicBasePath, assetsDir, diff --git a/src/node/server/serverPluginCss.ts b/src/node/server/serverPluginCss.ts index 90244b8d6bd098..dd12f3800ab77f 100644 --- a/src/node/server/serverPluginCss.ts +++ b/src/node/server/serverPluginCss.ts @@ -139,7 +139,7 @@ export const cssPlugin: ServerPlugin = ({ root, app, watcher, resolver }) => { const filePath = resolver.requestToFile(ctx.path) const preprocessLang = ctx.path.replace(cssPreprocessLangRE, '$2') - const result = await compileCss(root, ctx.path, { + const result = await compileCss(resolver, root, ctx.path, { id: '', source: css, filename: filePath, diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 8832893f647e3a..a2ab442c446471 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -152,6 +152,7 @@ export const vuePlugin: ServerPlugin = ({ } const id = hash_sum(publicPath) const result = await compileSFCStyle( + resolver, root, styleBlock, index, @@ -601,6 +602,7 @@ function compileSFCTemplate( } async function compileSFCStyle( + resolver: InternalResolver, root: string, style: SFCStyleBlock, index: number, @@ -619,7 +621,7 @@ async function compileSFCStyle( const { generateCodeFrame } = resolveCompiler(root) const resource = filePath + `?type=style&index=${index}` - const result = (await compileCss(root, publicPath, { + const result = (await compileCss(resolver, root, publicPath, { source: style.content, filename: resource, id: ``, // will be computed in compileCss diff --git a/src/node/utils/cssUtils.ts b/src/node/utils/cssUtils.ts index 63192f74caa58d..cfb0a9046d7ed3 100644 --- a/src/node/utils/cssUtils.ts +++ b/src/node/utils/cssUtils.ts @@ -2,13 +2,14 @@ import path from 'path' import postcssrc from 'postcss-load-config' import chalk from 'chalk' import { asyncReplace } from './transformUtils' -import { isExternalUrl, resolveFrom } from './pathUtils' +import { isExternalUrl, resolveFrom, bareImportRE } from './pathUtils' import { resolveCompiler } from './resolveVue' import hash_sum from 'hash-sum' import { SFCAsyncStyleCompileOptions, SFCStyleCompileResults } from '@vue/compiler-sfc' +import { InternalResolver } from '../resolver' export const urlRE = /url\(\s*('[^']+'|"[^"]+"|[^'")]+)\s*\)/ export const cssPreprocessLangRE = /(.+)\.(less|sass|scss|styl|stylus|postcss)$/ @@ -52,6 +53,7 @@ export function rewriteCssUrls( } export async function compileCss( + resolver: InternalResolver, root: string, publicPath: string, { @@ -84,7 +86,7 @@ export async function compileCss( const { options: postcssOptions, plugins: postcssPlugins - } = await resolvePostcssOptions(root, isBuild) + } = await resolvePostcssOptions(resolver, root, isBuild) if (preprocessLang) { preprocessOptions = preprocessOptions[preprocessLang] || preprocessOptions @@ -94,6 +96,21 @@ export async function compileCss( case 'sass': preprocessOptions = { includePaths: ['node_modules'], + importer: [ + (id: string) => { + if (id.startsWith('file://')) { + id = id.replace('file://', '') + } + if (isExternalUrl(id)) { + return { file: id } + } + id = resolver.alias(id) || id + if (id.startsWith('.') || bareImportRE.test(id)) { + return { file: id } + } + return { file: resolver.requestToFile(id) } + } + ], ...preprocessOptions } break @@ -153,11 +170,25 @@ async function loadPostcssConfig( } } -export async function resolvePostcssOptions(root: string, isBuild: boolean) { +export async function resolvePostcssOptions( + resolver: InternalResolver, + root: string, + isBuild: boolean +) { const config = await loadPostcssConfig(root) const options = config && config.options const plugins = config ? config.plugins : [] - plugins.unshift(require('postcss-import')()) + plugins.unshift( + require('postcss-import')({ + resolve: (id: string) => { + id = resolver.alias(id) || id + if (id.startsWith('.') || bareImportRE.test(id)) { + return id + } + return resolver.requestToFile(id) + } + }) + ) if (isBuild) { plugins.push(require('postcss-discard-comments')({ removeAll: true })) } diff --git a/test/test.js b/test/test.js index fd079d3d833a0d..3ce5e294213ec2 100644 --- a/test/test.js +++ b/test/test.js @@ -613,6 +613,9 @@ describe('vite', () => { 'directory aliased internal import outside hmr works' ) } + // css alias + expect(await getComputedColor('.alias-css')).toBe('rgb(255, 0, 0)') + expect(await getComputedColor('.alias-scss')).toBe('rgb(255, 0, 0)') }) test('transforms', async () => {