Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/style-preprocessor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const DefaultLessVersion = '4.3.0'

export const importLessFromCdn = async (
version: string = DefaultLessVersion,
) => {
return new Promise((resolve, reject) => {
if (!document?.body) {
reject(new Error('Document body not found'))
}
const el = document.createElement('script')
el.src = `https://cdn.jsdelivr.net/npm/less@${version}/dist/less.min.js`
el.onload = () => {
if ((window as any)?.less && (window as any)?.less.render) {
resolve(void 0)
} else {
reject(new Error('Import less from cdn failed'))
}
}
el.onerror = (err) => {
reject(err)
}
document.body.appendChild(el)
})
}
43 changes: 35 additions & 8 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
import { type Transform, transform } from 'sucrase'
import hashId from 'hash-sum'
import { getSourceMap, toVisualizer, trimAnalyzedBindings } from './sourcemap'
import { importLessFromCdn } from './style-preprocessor'

export const COMP_IDENTIFIER = `__sfc__`

Expand Down Expand Up @@ -78,7 +79,9 @@ export async function compileFile(
return errors
}

const styleLangs = descriptor.styles.map((s) => s.lang).filter(Boolean)
const styleLangs = descriptor.styles
.map((s) => s.lang)
.filter(Boolean) as string[]
const templateLang = descriptor.template?.lang
if (styleLangs.length && templateLang) {
return [
Expand All @@ -88,11 +91,20 @@ export async function compileFile(
`for <template> are currently not supported.`,
]
} else if (styleLangs.length) {
return [
`lang="${styleLangs.join(
',',
)}" pre-processors for <style> are currently not supported.`,
]
const hasLess = styleLangs.includes('less')
if (hasLess) {
await importLessFromCdn().catch(() => {
return [
`lang="less" pre-processors for <style> are currently not supported.`,
]
})
}
const restTasks = styleLangs.filter((lang) => lang !== 'less')
if (restTasks.length) {
return [
`lang="${restTasks.join(',')}" pre-processors for <style> are currently not supported.`,
]
}
} else if (templateLang) {
return [
`lang="${templateLang}" pre-processors for ` +
Expand Down Expand Up @@ -137,7 +149,15 @@ export async function compileFile(
let clientScript: string
let bindings: BindingMetadata | undefined
try {
const res = await doCompileScript(store, descriptor, id, false, isTS, isJSX, isCE)
const res = await doCompileScript(
store,
descriptor,
id,
false,
isTS,
isJSX,
isCE,
)
clientScript = res.code
bindings = res.bindings
clientScriptMap = res.map
Expand All @@ -159,7 +179,7 @@ export async function compileFile(
true,
isTS,
isJSX,
isCE
isCE,
)
ssrScript = ssrScriptResult.code
ssrCode += ssrScript
Expand Down Expand Up @@ -239,6 +259,13 @@ export async function compileFile(
id,
scoped: style.scoped,
modules: !!style.module,
...(style?.lang && { preprocessLang: style.lang as any }),
preprocessCustomRequire: (lang: string) => {
if (lang === 'less') {
return (window as any)?.less || null
}
return null
},
})
if (styleResult.errors.length) {
// postcss uses pathToFileURL which isn't polyfilled in the browser
Expand Down