33 <eslint-editor
44 :linter =" linter"
55 :config =" config"
6- :code =" code"
6+ v-model =" code"
77 :style =" { height }"
88 class =" eslint-code-block"
99 :filename =" filename"
@@ -43,23 +43,50 @@ export default {
4343 language: {
4444 type: String ,
4545 default: ' html'
46+ },
47+ /**
48+ * If enabled, `@typescript-eslint/parser` will be used.
49+ * This must be enabled when used for `ts` code blocks.
50+ */
51+ typescript: {
52+ type: Boolean ,
53+ default: false
4654 }
4755 },
4856
4957 data () {
58+ const code = this .computeCodeFromSlot ()
59+ // The height is determined in the initial processing.
60+ // This is because later code changes do not change the height.
61+ const lines = code .split (' \n ' ).length
62+ const height = ` ${ Math .max (120 , 19 * lines)} px`
5063 return {
64+ code,
65+ height,
5166 linter: null ,
5267 preprocess: processors[' .vue' ].preprocess ,
5368 postprocess: processors[' .vue' ].postprocess ,
5469 format: {
5570 insertSpaces: true ,
5671 tabSize: 2
57- }
72+ },
73+ tsEslintParser: null
5874 }
5975 },
6076
6177 computed: {
6278 config () {
79+ let parser = null // Use default parser (`espree`)
80+ if (this .typescript ) {
81+ // Use `@typescript-eslint/parser`.
82+ parser = this .tsEslintParser
83+ } else if (this .langTs ) {
84+ // Use `@typescript-eslint/parser` only when `<script lang="ts">` or `<script lang="typescript">`.
85+ parser = {
86+ ts: this .tsEslintParser ,
87+ typescript: this .tsEslintParser
88+ }
89+ }
6390 return {
6491 globals: {
6592 console: false ,
@@ -90,6 +117,7 @@ export default {
90117 rules: this .rules ,
91118 parser: ' vue-eslint-parser' ,
92119 parserOptions: {
120+ parser,
93121 ecmaVersion: ' latest' ,
94122 sourceType: ' module' ,
95123 ecmaFeatures: {
@@ -99,24 +127,37 @@ export default {
99127 }
100128 },
101129
102- code () {
103- return ` ${ this .computeCodeFromSlot (this .$slots .default ).trim ()} \n `
104- },
130+ /**
131+ * Checks whether code may be using lang="ts" or lang="typescript".
132+ * @returns {boolean} If `true`, may be using lang="ts" or lang="typescript".
133+ */
134+ langTs () {
135+ return / lang\s * =\s * (?:"ts"| ts| 'ts'| "typescript"| typescript| 'typescript')/ u .test (
136+ this .code
137+ )
138+ }
139+ },
105140
106- height () {
107- const lines = this .code .split (' \n ' ).length
108- return ` ${ Math .max (120 , 19 * lines)} px`
141+ watch: {
142+ typescript (value ) {
143+ if (value) {
144+ this .loadTypescriptESLint ()
145+ }
146+ },
147+ langTs (value ) {
148+ if (value) {
149+ this .loadTypescriptESLint ()
150+ }
109151 }
110152 },
111153
112154 methods: {
113- computeCodeFromSlot (nodes ) {
114- if (! Array .isArray (nodes)) {
115- return ' '
116- }
117- return nodes
118- .map ((node ) => node .text || this .computeCodeFromSlot (node .children ))
119- .join (' ' )
155+ computeCodeFromSlot () {
156+ return ` ${ computeCodeFromSlot (this .$slots .default ).trim ()} \n `
157+ },
158+
159+ async loadTypescriptESLint () {
160+ this .tsEslintParser = await import (' @typescript-eslint/parser' )
120161 }
121162 },
122163
@@ -126,6 +167,9 @@ export default {
126167 import (' eslint/lib/linter' ),
127168 import (' espree' ).then (() => import (' vue-eslint-parser' ))
128169 ])
170+ if (this .langTs || this .typescript ) {
171+ await this .loadTypescriptESLint ()
172+ }
129173
130174 const linter = (this .linter = new Linter ())
131175
@@ -136,6 +180,15 @@ export default {
136180 linter .defineParser (' vue-eslint-parser' , { parseForESLint })
137181 }
138182}
183+
184+ function computeCodeFromSlot (nodes ) {
185+ if (! Array .isArray (nodes)) {
186+ return ' '
187+ }
188+ return nodes
189+ .map ((node ) => node .text || computeCodeFromSlot (node .children ))
190+ .join (' ' )
191+ }
139192 </script >
140193
141194<style >
0 commit comments