Skip to content

Commit 8711636

Browse files
author
Guillaume Chau
committed
feat(ui): JS config support
1 parent 5b5d754 commit 8711636

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

docs/plugin-dev-ui.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,22 @@ api.describeConfig({
104104
})
105105
```
106106

107-
Then you can specify which files will be read when loading the configuration and then written to (JS files aren't supported yet):
107+
Then you can specify which files will be read when loading the configuration and then written to:
108108

109109
```js
110110
api.describeConfig({
111111
/* ... */
112112
// All possible files for this config
113113
files: {
114114
json: ['.eslintrc', '.eslintrc.json'],
115+
js: ['.eslintrc.js'],
115116
// Will read from `package.json`
116117
package: 'eslintConfig'
117118
},
118119
})
119120
```
120121

121-
Supported types: `json`, `yaml`, `package`.
122+
Supported types: `json`, `yaml`, `js`, `package`.
122123

123124
Use the `onRead` hook to return a list of prompts to be displayed for the configuration:
124125

@@ -164,7 +165,7 @@ Arguments:
164165

165166
- `prompts`: current prompts runtime objects
166167
- `answers`: answers data from the user inputs
167-
- `data`: initial data read from the file
168+
- `data`: read-only initial data read from the file
168169
- `file`: descriptor of the found file (`{ type: 'json', path: '...' }`)
169170
- `api`: onWrite API
170171

packages/@vue/cli-ui/src/graphql-api/connectors/configurations.js

+24-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const folders = require('./folders')
99
const prompts = require('./prompts')
1010
// Utils
1111
const { get, set, remove } = require('../../util/object')
12+
const { loadModule } = require('@vue/cli/lib/util/module')
13+
const extendJSConfig = require('@vue/cli/lib/util/extendJSConfig')
1214

1315
const fileTypes = ['js', 'json', 'yaml']
1416
let current = {}
@@ -56,24 +58,24 @@ function readData (config, context) {
5658
if (file.type === 'package') {
5759
const pkg = folders.readPackage(cwd.get(), context)
5860
return pkg[config.files.package]
61+
} else if (file.type === 'js') {
62+
return loadModule(file.path, cwd.get(), true)
5963
} else {
6064
const rawContent = fs.readFileSync(file.path, { encoding: 'utf8' })
6165
if (file.type === 'json') {
6266
return JSON.parse(rawContent)
6367
} else if (file.type === 'yaml') {
6468
return yaml.safeLoad(rawContent)
65-
} else if (file.type === 'js') {
66-
// TODO
67-
console.warn('JS config read not implemented')
6869
}
6970
}
7071
}
7172
return {}
7273
}
7374

74-
function writeData ({ config, data }, context) {
75+
function writeData ({ config, data, changedFields }, context) {
7576
const file = findFile(config, context)
7677
if (file) {
78+
if (process.env.NODE_ENV !== 'production') console.log('write', config.id, data, changedFields)
7779
let rawContent
7880
if (file.type === 'package') {
7981
const pkg = folders.readPackage(cwd.get(), context)
@@ -85,8 +87,12 @@ function writeData ({ config, data }, context) {
8587
} else if (file.type === 'yaml') {
8688
rawContent = yaml.safeDump(data)
8789
} else if (file.type === 'js') {
88-
// TODO
89-
console.warn('JS config write not implemented')
90+
const changedData = changedFields.reduce((obj, field) => {
91+
obj[field] = data[field]
92+
return obj
93+
}, {})
94+
const source = fs.readFileSync(file.path, { encoding: 'utf8' })
95+
rawContent = extendJSConfig(changedData, source)
9096
}
9197
}
9298
fs.writeFileSync(file.path, rawContent, { encoding: 'utf8' })
@@ -97,6 +103,7 @@ async function getPrompts (id, context) {
97103
const config = findOne(id, context)
98104
if (config) {
99105
const data = readData(config, context)
106+
if (process.env.NODE_ENV !== 'production') console.log('read', config.id, data)
100107
current = {
101108
config,
102109
data
@@ -121,17 +128,26 @@ async function save (id, context) {
121128
if (current.config === config) {
122129
const answers = prompts.getAnswers()
123130
let data = clone(current.data)
131+
const changedFields = []
124132
await config.onWrite({
125133
prompts: prompts.list(),
126134
answers,
127-
data,
135+
data: current.data,
128136
file: config.file,
129137
api: {
130138
assignData: newData => {
139+
changedFields.push(...Object.keys(newData))
131140
Object.assign(data, newData)
132141
},
133142
setData: newData => {
134143
Object.keys(newData).forEach(key => {
144+
let field = key
145+
const dotIndex = key.indexOf('.')
146+
if (dotIndex !== -1) {
147+
field = key.substr(0, dotIndex)
148+
}
149+
changedFields.push(field)
150+
135151
const value = newData[key]
136152
if (typeof value === 'undefined') {
137153
remove(data, key)
@@ -155,7 +171,7 @@ async function save (id, context) {
155171
}
156172
}
157173
})
158-
writeData({ config, data }, context)
174+
writeData({ config, data, changedFields }, context)
159175
current = {}
160176
}
161177
}

0 commit comments

Comments
 (0)