UNPKG

3.19 kBJavaScriptView Raw
1const fs = require('fs')
2const cloneDeep = require('lodash.clonedeep')
3const { getRcPath } = require('./util/rcPath')
4const { exit } = require('@vue/cli-shared-utils/lib/exit')
5const { error } = require('@vue/cli-shared-utils/lib/logger')
6const { createSchema, validate } = require('@vue/cli-shared-utils/lib/validate')
7
8const rcPath = exports.rcPath = getRcPath('.vuerc')
9
10const presetSchema = createSchema(joi => joi.object().keys({
11 vueVersion: joi.string().only(['2', '3']),
12 bare: joi.boolean(),
13 useConfigFiles: joi.boolean(),
14 // TODO: Use warn for router and vuex once @hapi/joi v16 releases
15 router: joi.boolean(),
16 routerHistoryMode: joi.boolean(),
17 vuex: joi.boolean(),
18 cssPreprocessor: joi.string().only(['sass', 'dart-sass', 'node-sass', 'less', 'stylus']),
19 plugins: joi.object().required(),
20 configs: joi.object()
21}))
22
23const schema = createSchema(joi => joi.object().keys({
24 latestVersion: joi.string().regex(/^\d+\.\d+\.\d+(-(alpha|beta|rc)\.\d+)?$/),
25 lastChecked: joi.date().timestamp(),
26 packageManager: joi.string().only(['yarn', 'npm', 'pnpm']),
27 useTaobaoRegistry: joi.boolean(),
28 presets: joi.object().pattern(/^/, presetSchema)
29}))
30
31exports.validatePreset = preset => validate(preset, presetSchema, msg => {
32 error(`invalid preset options: ${msg}`)
33})
34
35exports.defaultPreset = {
36 useConfigFiles: false,
37 cssPreprocessor: undefined,
38 plugins: {
39 '@vue/cli-plugin-babel': {},
40 '@vue/cli-plugin-eslint': {
41 config: 'base',
42 lintOn: ['save']
43 }
44 }
45}
46
47exports.defaults = {
48 lastChecked: undefined,
49 latestVersion: undefined,
50
51 packageManager: undefined,
52 useTaobaoRegistry: undefined,
53 presets: {
54 'default': Object.assign({ vueVersion: '2' }, exports.defaultPreset),
55 '__default_vue_3__': Object.assign({ vueVersion: '3' }, exports.defaultPreset)
56 }
57}
58
59let cachedOptions
60
61exports.loadOptions = () => {
62 if (cachedOptions) {
63 return cachedOptions
64 }
65 if (fs.existsSync(rcPath)) {
66 try {
67 cachedOptions = JSON.parse(fs.readFileSync(rcPath, 'utf-8'))
68 } catch (e) {
69 error(
70 `Error loading saved preferences: ` +
71 `~/.vuerc may be corrupted or have syntax errors. ` +
72 `Please fix/delete it and re-run vue-cli in manual mode.\n` +
73 `(${e.message})`
74 )
75 exit(1)
76 }
77 validate(cachedOptions, schema, () => {
78 error(
79 `~/.vuerc may be outdated. ` +
80 `Please delete it and re-run vue-cli in manual mode.`
81 )
82 })
83 return cachedOptions
84 } else {
85 return {}
86 }
87}
88
89exports.saveOptions = toSave => {
90 const options = Object.assign(cloneDeep(exports.loadOptions()), toSave)
91 for (const key in options) {
92 if (!(key in exports.defaults)) {
93 delete options[key]
94 }
95 }
96 cachedOptions = options
97 try {
98 fs.writeFileSync(rcPath, JSON.stringify(options, null, 2))
99 return true
100 } catch (e) {
101 error(
102 `Error saving preferences: ` +
103 `make sure you have write access to ${rcPath}.\n` +
104 `(${e.message})`
105 )
106 }
107}
108
109exports.savePreset = (name, preset) => {
110 const presets = cloneDeep(exports.loadOptions().presets || {})
111 presets[name] = preset
112 return exports.saveOptions({ presets })
113}