refactor: make shiki load all its deps upfront (#22114)

* refactor: make shiki load all its deps upfront

* finish some shiki adjustments

* fix type check

* rollback shiki upgrade

* add convert comment and simplify lang variable name

* use a switch statement
This commit is contained in:
Barthélémy Ledoux
2022-06-30 14:13:37 -05:00
committed by GitHub
parent 5573fe50b0
commit c67b75020d
2 changed files with 39 additions and 27 deletions

View File

@@ -52,13 +52,13 @@ shikiWrapperClasses computed property.
props.class,
]"
@click="copyOnClick ? () => copyCode() : () => {}"
@click="copyOnClick ? () => copyCode() : () => { }"
v-html="highlightedCode"
/>
<pre
v-else
class="border rounded font-normal border-gray-100 py-8px text-14px leading-24px overflow-scroll"
:class="[props.class, lineNumbers ? 'pl-56px' : 'pl-8px' ]"
:class="[props.class, lineNumbers ? 'pl-56px' : 'pl-8px']"
>{{ trimmedCode }}</pre>
<CopyButton
v-if="copyButton"
@@ -73,20 +73,29 @@ shikiWrapperClasses computed property.
</template>
<script lang="ts">
import type { Highlighter } from 'shiki'
import { getHighlighter, setOnigasmWASM, setCDN } from 'shiki'
import type { Highlighter, ILanguageRegistration } from 'shiki'
import { getHighlighter, setOnigasmWASM } from 'shiki'
import onigasm from 'onigasm/lib/onigasm.wasm?url'
import shikiCyTheme from '../public/shiki/themes/cypress.theme.json'
const langJSONFilesArray = import.meta.globEager('../public/shiki/languages/*.tmLanguage.json')
// Convert to the format shiki needs for language customization.
// @see https://github.com/shikijs/shiki/blob/main/docs/languages.md
const langs: ILanguageRegistration[] = Object.values(langJSONFilesArray).map((grammar: any) => {
return {
grammar,
id: grammar.name,
scopeName: grammar.scopeName,
}
})
setOnigasmWASM(onigasm)
setCDN(`${import.meta.env.BASE_URL}shiki/`)
let highlighter: Highlighter
export const langsSupported = ['typescript', 'javascript', 'ts', 'js', 'css', 'jsx', 'tsx', 'json', 'yaml', 'html'] as const
export type CyLangType = 'typescript' | 'javascript' | 'ts' | 'js' | 'css' | 'jsx' | 'tsx' | 'json' | 'yaml' | 'html' | 'plaintext' | 'txt' | 'text' | 'vue' | string
let langs = langsSupported.concat([])
export type CyLangType = typeof langsSupported[number] | 'plaintext' | 'txt'| 'text'
export const langsSupported = langs.map((lang: ILanguageRegistration) => lang.id)
export async function initHighlighter () {
if (highlighter) {
@@ -94,7 +103,7 @@ export async function initHighlighter () {
}
highlighter = await getHighlighter({
themes: ['cypress.theme'],
theme: shikiCyTheme as any,
langs,
})
}
@@ -142,12 +151,21 @@ const props = withDefaults(defineProps<{
})
const resolvedLang = computed(() => {
if (props.lang === 'javascript' || props.lang === 'js' || props.lang === 'jsx') return 'jsx'
if (props.lang === 'typescript' || props.lang === 'ts' || props.lang === 'tsx') return 'tsx'
// if the language is not recognized use plaintext
return props.lang && (langsSupported as readonly string[]).includes(props.lang) ? props.lang : 'plaintext'
switch (props.lang) {
case 'javascript':
case 'js':
case 'jsx':
return 'jsx'
case 'typescript':
case 'ts':
case 'tsx':
return 'tsx'
default:
return props.lang && langsSupported.includes(props.lang)
? props.lang
// if the language is not recognized use plaintext
: 'plaintext'
}
})
const trimmedCode = computed(() => props.skipTrim ? props.code : props.code.trim())
@@ -181,7 +199,6 @@ avoid colliding with styles elsewhere in the document.
-->
<style lang="scss" scoped>
$offset: 1.1em;
.inline:deep(.shiki) {
@@ -199,12 +216,14 @@ $offset: 1.1em;
&.line-numbers:deep(.shiki) {
@apply py-8px;
code {
counter-reset: step;
counter-increment: step calc(v-bind('props.initialLine') - 1);
// Keep bg-gray-50 synced with the box-shadows.
.line::before, .line:first-child::before {
.line::before,
.line:first-child::before {
@apply bg-gray-50 text-right mr-16px min-w-40px px-8px text-gray-500 inline-block sticky;
left: 0px !important;
content: counter(step);

View File

@@ -80,8 +80,7 @@ import Button from '@cy/components/Button.vue'
// eslint-disable-next-line no-duplicate-imports
import Badge from '@cy/components/Badge.vue'
import { useI18n } from '@cy/i18n'
import ShikiHighlight, { langsSupported } from '@cy/components/ShikiHighlight.vue'
import type { CyLangType } from '@cy/components/ShikiHighlight.vue'
import ShikiHighlight from '@cy/components/ShikiHighlight.vue'
import ListRowHeader from '@cy/components/ListRowHeader.vue'
import Collapsible from '@cy/components/Collapsible.vue'
import AddedIcon from '~icons/cy/file-changes-added_x24.svg'
@@ -102,13 +101,7 @@ const props = defineProps<{
const language = computed(() => {
// The fileExtension from FileParts is prepended with a period;
// we must strip the period to validate against our supported languages.
let extension = props.fileExtension.replace(/^\./, '')
if (extension && (langsSupported as readonly string[]).includes(extension)) {
return extension as CyLangType
}
return 'plaintext'
return props.fileExtension.replace(/^\./, '')
})
const statusInfo: ComputedRef<StatusInfo> = computed(() => {