Skip to content

Commit cb2d4fc

Browse files
authored
Replace documentation example with vue-eslint-editor (#153)
* Replace documentation example with `vue-eslint-editor` * fix script * update * fix * Add since version
1 parent 689f1b9 commit cb2d4fc

31 files changed

+2904
-1739
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
<template>
2+
<div class="eslint-code-container">
3+
<eslint-editor
4+
ref="editor"
5+
:linter="linter"
6+
:config="config"
7+
v-model="code"
8+
:style="{ height }"
9+
class="eslint-code-block"
10+
:filename="resplvedFilename"
11+
:language="language"
12+
dark
13+
:format="format"
14+
:fix="fix"
15+
/>
16+
</div>
17+
</template>
18+
19+
<script>
20+
import './setup'
21+
import EslintEditor from 'vue-eslint-editor'
22+
import { rules } from '../../../'
23+
import { setTimeouts } from '../../../dist/utils/default-timeouts'
24+
import { setFileContents } from '../shim/fs/fake-fs'
25+
26+
setTimeouts({ CACHE_LOADER: -1, MTIME_MS_CHECK: -1 })
27+
export default {
28+
name: 'ESLintCodeBlock',
29+
components: { EslintEditor },
30+
inject: {
31+
$resourceGroup: {
32+
from: '$resourceGroup',
33+
default: null
34+
}
35+
},
36+
37+
props: {
38+
fix: {
39+
type: Boolean,
40+
default: false
41+
},
42+
rules: {
43+
type: Object,
44+
default() {
45+
return {}
46+
}
47+
},
48+
filename: {
49+
type: String
50+
},
51+
language: {
52+
type: String,
53+
default: 'html'
54+
},
55+
localeKey: {
56+
type: String,
57+
default: 'file'
58+
},
59+
messageSyntaxVersion: {
60+
type: String,
61+
default: '^9'
62+
}
63+
},
64+
65+
data() {
66+
return {
67+
linter: null,
68+
format: {
69+
insertSpaces: true,
70+
tabSize: 2
71+
},
72+
code: ''
73+
}
74+
},
75+
76+
watch: {
77+
code(newCode) {
78+
if (this.$resourceGroup) {
79+
this.$resourceGroup.set(this.resplvedFilename, newCode)
80+
}
81+
}
82+
},
83+
84+
computed: {
85+
isResource() {
86+
return this.language === 'json' || this.language === 'yaml'
87+
},
88+
resplvedFilename() {
89+
return (
90+
this.filename ||
91+
(this.language === 'json'
92+
? 'example.json'
93+
: this.language === 'yaml'
94+
? 'example.yaml'
95+
: this.language === 'javascript'
96+
? 'example.js'
97+
: 'example.vue')
98+
)
99+
},
100+
config() {
101+
return {
102+
globals: {
103+
console: false,
104+
// ES2015 globals
105+
ArrayBuffer: false,
106+
DataView: false,
107+
Float32Array: false,
108+
Float64Array: false,
109+
Int16Array: false,
110+
Int32Array: false,
111+
Int8Array: false,
112+
Map: false,
113+
Promise: false,
114+
Proxy: false,
115+
Reflect: false,
116+
Set: false,
117+
Symbol: false,
118+
Uint16Array: false,
119+
Uint32Array: false,
120+
Uint8Array: false,
121+
Uint8ClampedArray: false,
122+
WeakMap: false,
123+
WeakSet: false,
124+
// ES2017 globals
125+
Atomics: false,
126+
SharedArrayBuffer: false
127+
},
128+
rules: this.rules,
129+
parser:
130+
this.language === 'json'
131+
? 'jsonc-eslint-parser'
132+
: this.language === 'yaml'
133+
? 'yaml-eslint-parser'
134+
: 'vue-eslint-parser',
135+
parserOptions: {
136+
ecmaVersion: 2020,
137+
sourceType: 'module',
138+
ecmaFeatures: {
139+
jsx: true
140+
}
141+
},
142+
settings: {
143+
'vue-i18n': {
144+
localeDir: (this.$resourceGroup
145+
? this.$resourceGroup
146+
.getFiles()
147+
.filter(file => /\.(?:json5?|ya?ml)$/i.test(file))
148+
: this.isResource
149+
? [this.resplvedFilename]
150+
: []
151+
).map(pattern => ({ pattern, localeKey: this.localeKey })),
152+
messageSyntaxVersion: this.messageSyntaxVersion
153+
}
154+
}
155+
}
156+
},
157+
158+
height() {
159+
const lines = this.code.split('\n').length
160+
return `${Math.max(120, 19 * lines)}px`
161+
}
162+
},
163+
164+
methods: {
165+
computeCodeFromSlot(nodes) {
166+
if (!Array.isArray(nodes)) {
167+
return ''
168+
}
169+
return nodes
170+
.map(node => node.text || this.computeCodeFromSlot(node.children))
171+
.join('')
172+
},
173+
verifyHook() {
174+
setFileContents(
175+
this.$resourceGroup ? this.$resourceGroup.getFileContents() : {}
176+
)
177+
},
178+
lint() {
179+
this.$refs.editor.lint()
180+
}
181+
},
182+
183+
async mounted() {
184+
if (this.$resourceGroup) {
185+
this.$resourceGroup.addEditor(this)
186+
}
187+
this.code = `${this.computeCodeFromSlot(this.$slots.default).trim()}\n`
188+
this.$refs.editor.$watch('monaco', monaco => {
189+
monaco.languages.register({ id: 'yaml' })
190+
monaco.languages.setMonarchTokensProvider(
191+
'yaml',
192+
require('monaco-editor/esm/vs/basic-languages/yaml/yaml').language
193+
)
194+
})
195+
// Load linter.
196+
const [
197+
{ default: Linter },
198+
{ default: coreRules },
199+
vueESLintParser,
200+
jsoncESLintParser,
201+
yamlESLintParser
202+
] = await Promise.all([
203+
import('eslint4b/dist/linter'),
204+
import('eslint4b/dist/core-rules'),
205+
import('espree').then(() => import('vue-eslint-parser')),
206+
import('espree').then(() => import('jsonc-eslint-parser')),
207+
import('yaml-eslint-parser')
208+
])
209+
210+
const linter = (this.linter = new Linter({ cwd: '/path' }))
211+
212+
linter.defineRules(coreRules)
213+
for (const ruleId of Object.keys(rules)) {
214+
linter.defineRule(`@intlify/vue-i18n/${ruleId}`, rules[ruleId])
215+
}
216+
linter.defineParser('vue-eslint-parser', vueESLintParser)
217+
linter.defineParser('jsonc-eslint-parser', jsoncESLintParser)
218+
linter.defineParser('yaml-eslint-parser', yamlESLintParser)
219+
220+
const verifyHook = this.verifyHook
221+
222+
const verify = linter.verify
223+
linter.verify = function (...args) {
224+
verifyHook()
225+
return verify.apply(this, args)
226+
}
227+
const verifyAndFix = linter.verifyAndFix
228+
linter.verifyAndFix = function (...args) {
229+
verifyHook()
230+
return verifyAndFix.apply(this, args)
231+
}
232+
}
233+
}
234+
</script>
235+
236+
<style>
237+
.eslint-code-container {
238+
border-radius: 6px;
239+
padding: 1.25rem 0;
240+
margin: 1em 0;
241+
background-color: #1e1e1e;
242+
}
243+
244+
.eslint-code-block {
245+
width: 100%;
246+
}
247+
248+
.eslint-editor-actions {
249+
bottom: -0.9rem;
250+
}
251+
</style>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<template>
2+
<div>
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<script>
8+
import Vue from 'vue'
9+
export default {
10+
provide() {
11+
let waitSeq = 0
12+
const data = Vue.observable({ fileContents: {} })
13+
const editors = new Set()
14+
return {
15+
$resourceGroup: {
16+
async set(fileName, code) {
17+
Vue.set(data.fileContents, fileName, code)
18+
19+
const timeSeq = ++waitSeq
20+
await Vue.nextTick()
21+
if (timeSeq !== waitSeq) {
22+
return
23+
}
24+
25+
for (const editor of editors) {
26+
editor.lint()
27+
}
28+
},
29+
getFileContents() {
30+
return data.fileContents
31+
},
32+
getFiles() {
33+
return Object.keys(data.fileContents)
34+
},
35+
addEditor(editor) {
36+
editors.add(editor)
37+
}
38+
}
39+
}
40+
}
41+
}
42+
</script>

docs/.vuepress/components/setup.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
if (typeof window !== 'undefined') {
2+
window.process = {
3+
cwd() {
4+
return ''
5+
}
6+
}
7+
}

docs/.vuepress/config.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,28 @@
55
'use strict'
66

77
require('ts-node').register()
8+
const path = require('path')
89
const { withCategories } = require('../../scripts/lib/rules')
9-
require('../../scripts/update-docs-headers')
10+
require('../../scripts/update-rule-docs')
1011
require('../../scripts/update-docs-index')
1112

1213
module.exports = {
14+
configureWebpack(_config, _isServer) {
15+
return {
16+
resolve: {
17+
alias: {
18+
module: require.resolve('./shim/module'),
19+
glob: require.resolve('./shim/glob'),
20+
eslint: path.resolve(__dirname, './shim/eslint'),
21+
fs: require.resolve('./shim/fs'),
22+
[path.resolve(
23+
__dirname,
24+
'../../dist/utils/glob-utils'
25+
)]: require.resolve('./shim/eslint-plugin-vue-i18n/utils/glob-utils')
26+
}
27+
}
28+
}
29+
},
1330
base: '/',
1431
title: 'eslint-plugin-vue-i18n',
1532
description: 'ESLint plugin for Vue I18n',
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { getFiles } from '../../fs/fake-fs'
2+
export function listFilesToProcess() {
3+
return getFiles()
4+
.filter(filename => /\.(?:vue|js)$/i.test(filename))
5+
.map(filename => ({ filename, ignored: false }))
6+
}

docs/.vuepress/shim/eslint/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { SourceCode } from '../../../../node_modules/eslint/lib/source-code'
2+
export { SourceCode }
3+
export class CLIEngine {
4+
addPlugin() {}
5+
getConfigForFile() {
6+
return {
7+
parser: 'vue-eslint-parser',
8+
parserOptions: {
9+
sourceType: 'module'
10+
}
11+
}
12+
}
13+
}

docs/.vuepress/shim/fs/fake-fs.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export function statSync(filename) {
2+
return {
3+
mtimeMs: Date.now()
4+
}
5+
}
6+
7+
let files = {}
8+
9+
export function existsSync(filename) {
10+
return Boolean(files[filename]) || filename === '.'
11+
}
12+
export function readFileSync(filename) {
13+
return files[filename] || ''
14+
}
15+
16+
// utility
17+
export function setFileContents(filesMap) {
18+
files = filesMap
19+
}
20+
export function getFiles() {
21+
return Object.keys(files)
22+
}

docs/.vuepress/shim/fs/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const fakeFS = require('./fake-fs')
2+
fakeFS.default = fakeFS
3+
4+
module.exports = fakeFS

docs/.vuepress/shim/glob.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
sync(p) {
3+
return [p]
4+
}
5+
}

docs/.vuepress/shim/module.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
createRequire: () => () => null
3+
}

0 commit comments

Comments
 (0)