Skip to content

Commit

Permalink
refactor(plugin-vue): ensure style processing in custom elements mode
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jul 23, 2021
1 parent 1ba31c4 commit 8b232a7
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 41 deletions.
3 changes: 3 additions & 0 deletions packages/plugin-vue/src/handleHotUpdate.ts
Expand Up @@ -95,6 +95,9 @@ export async function handleHotUpdate({
)
if (mod) {
affectedModules.add(mod)
if (mod.url.includes('&inline')) {
affectedModules.add(mainModule)
}
} else {
// new style block - force reload
affectedModules.add(mainModule)
Expand Down
7 changes: 4 additions & 3 deletions packages/plugin-vue/src/index.ts
Expand Up @@ -45,9 +45,10 @@ export interface Options {
style?: Partial<SFCStyleCompileOptions>

/**
* Transform Vue SFCs into custom elements (requires Vue >= 3.2.0)
* - `true` -> all `*.vue` imports are converted into custom elements
* - `string | RegExp` -> matched files are converted into custom elements
* Transform Vue SFCs into custom elements.
* **requires Vue >= 3.2.0 & Vite >= 2.4.4**
* - `true`: all `*.vue` imports are converted into custom elements
* - `string | RegExp`: matched files are converted into custom elements
*
* @default /\.ce\.vue$/
*/
Expand Down
79 changes: 41 additions & 38 deletions packages/plugin-vue/src/main.ts
Expand Up @@ -14,7 +14,6 @@ import { transformTemplateInMain } from './template'
import { isOnlyTemplateChanged, isEqualBlock } from './handleHotUpdate'
import { RawSourceMap, SourceMapConsumer, SourceMapGenerator } from 'source-map'
import { createRollupError } from './utils/error'
import { transformStyle } from './style'

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export async function transformMain(
Expand Down Expand Up @@ -94,9 +93,11 @@ export async function transformMain(
}

// styles
const stylesCode = asCustomElement
? await genCustomElementStyleCode(descriptor, options, pluginContext)
: await genStyleCode(descriptor, pluginContext)
const stylesCode = await genStyleCode(
descriptor,
pluginContext,
asCustomElement
)

// custom blocks
const customBlocksCode = await genCustomBlockCode(descriptor, pluginContext)
Expand Down Expand Up @@ -298,7 +299,8 @@ async function genScriptCode(

async function genStyleCode(
descriptor: SFCDescriptor,
pluginContext: PluginContext
pluginContext: PluginContext,
asCustomElement: boolean
) {
let stylesCode = ``
let hasCSSModules = false
Expand All @@ -313,23 +315,55 @@ async function genStyleCode(
// that the module needs to export the modules json
const attrsQuery = attrsToQuery(style.attrs, 'css')
const srcQuery = style.src ? `&src` : ``
const query = `?vue&type=style&index=${i}${srcQuery}`
const directQuery = asCustomElement ? `&inline` : ``
const query = `?vue&type=style&index=${i}${srcQuery}${directQuery}`
const styleRequest = src + query + attrsQuery
if (style.module) {
if (asCustomElement) {
throw new Error(
`<style module> is not supported in custom elements mode.`
)
}
if (!hasCSSModules) {
stylesCode += `\nconst cssModules = _sfc_main.__cssModules = {}`
hasCSSModules = true
}
stylesCode += genCSSModulesCode(i, styleRequest, style.module)
} else {
stylesCode += `\nimport ${JSON.stringify(styleRequest)}`
if (asCustomElement) {
stylesCode += `\nimport _style_${i} from ${JSON.stringify(
styleRequest
)}`
} else {
stylesCode += `\nimport ${JSON.stringify(styleRequest)}`
}
}
// TODO SSR critical CSS collection
}
if (asCustomElement) {
stylesCode += `\n_sfc_main.styles = [${descriptor.styles
.map((_, i) => `_style_${i}`)
.join(',')}]`
}
}
return stylesCode
}

function genCSSModulesCode(
index: number,
request: string,
moduleName: string | boolean
): string {
const styleVar = `style${index}`
const exposedName = typeof moduleName === 'string' ? moduleName : '$style'
// inject `.module` before extension so vite handles it as css module
const moduleRequest = request.replace(/\.(\w+)$/, '.module.$1')
return (
`\nimport ${styleVar} from ${JSON.stringify(moduleRequest)}` +
`\ncssModules["${exposedName}"] = ${styleVar}`
)
}

async function genCustomBlockCode(
descriptor: SFCDescriptor,
pluginContext: PluginContext
Expand All @@ -351,21 +385,6 @@ async function genCustomBlockCode(
return code
}

function genCSSModulesCode(
index: number,
request: string,
moduleName: string | boolean
): string {
const styleVar = `style${index}`
const exposedName = typeof moduleName === 'string' ? moduleName : '$style'
// inject `.module` before extension so vite handles it as css module
const moduleRequest = request.replace(/\.(\w+)$/, '.module.$1')
return (
`\nimport ${styleVar} from ${JSON.stringify(moduleRequest)}` +
`\ncssModules["${exposedName}"] = ${styleVar}`
)
}

/**
* For blocks with src imports, it is important to link the imported file
* with its owner SFC descriptor so that we can get the information about
Expand Down Expand Up @@ -411,19 +430,3 @@ function attrsToQuery(
}
return query
}

async function genCustomElementStyleCode(
descriptor: SFCDescriptor,
options: ResolvedOptions,
pluginContext: TransformPluginContext
) {
const styles = (
await Promise.all(
descriptor.styles.map((style, index) =>
transformStyle(style.content, descriptor, index, options, pluginContext)
)
)
).map((res) => JSON.stringify(res!.code))

return `_sfc_main.styles = [${styles.join(',')}]`
}

0 comments on commit 8b232a7

Please sign in to comment.