@koumoul/vjsf 2.9.1 → 2.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/VJsfNoDeps.js CHANGED
@@ -18,7 +18,8 @@ import Validatable from './mixins/Validatable'
18
18
  import Dependent from './mixins/Dependent'
19
19
  const expr = require('property-expr')
20
20
 
21
- const debugFlag = global.navigator && global.navigator.cookieEnabled && global.localStorage && global.localStorage.debug
21
+ const debugExpr = require('debug')('vjsf:expr')
22
+ debugExpr.log = console.log.bind(console)
22
23
 
23
24
  const mountingIncs = {}
24
25
 
@@ -61,7 +62,6 @@ export default {
61
62
  return this.fullKey === 'root' ? (this.options || {}) : this.optionsRoot
62
63
  },
63
64
  fullOptions() {
64
- this.debug('compute fullOptions')
65
65
  const _global = (typeof window !== 'undefined' && window) || (typeof global !== 'undefined' && global) || {}
66
66
  const fullOptions = Object.assign({}, defaultOptions, this.options || {}, this.resolvedSchema['x-options'] || {})
67
67
 
@@ -125,7 +125,6 @@ export default {
125
125
  },
126
126
  resolvedSchema() {
127
127
  if (this.modelKey === 'root') {
128
- this.debug('compute resolvedSchema')
129
128
  const options = this.options || {}
130
129
  const locale = options.locale || options.defaultLocale || 'en'
131
130
  const defaultLocale = options.defaultLocale || 'en'
@@ -138,7 +137,6 @@ export default {
138
137
  }
139
138
  },
140
139
  htmlDescription() {
141
- this.debug('compute htmlDescription')
142
140
  return this.fullOptions.markdown(this.fullSchema && this.fullSchema.description)
143
141
  },
144
142
  fullKey() {
@@ -157,7 +155,6 @@ export default {
157
155
  return this.fullSchema['x-tag']
158
156
  },
159
157
  rules() {
160
- this.debug('compute rules')
161
158
  if (!this.fullSchema) return
162
159
  return getRules(this.schema, this.fullSchema, this.fullOptions, this.required, this.isOneOfSelect)
163
160
  },
@@ -174,7 +171,6 @@ export default {
174
171
  return this.fullSchema['x-display'] && this.fullSchema['x-display'].startsWith('custom-') ? this.fullSchema['x-display'] : this.fullKey
175
172
  },
176
173
  slotParams() {
177
- this.debug('compute slotParams')
178
174
  if (!this.fullSchema) return
179
175
  return {
180
176
  value: this.value,
@@ -199,7 +195,6 @@ export default {
199
195
  },
200
196
  // props common to many vuetify fields
201
197
  commonFieldProps() {
202
- this.debug('compute commonFieldProps')
203
198
  if (!this.fullSchema) return
204
199
  const value = this.separator && typeof this.value === 'string' ? this.value.split(this.separator) : this.value
205
200
  return {
@@ -255,8 +250,6 @@ export default {
255
250
  throw new Error('detected infinite mounting loop: ' + this.fullKey)
256
251
  } */
257
252
 
258
- this.debug('mounted', mountingIncs[this.fullKey])
259
-
260
253
  // optimize the watcher used to reprocess fullSchema so that we trigger less re-render of components
261
254
  let watcher = 'resolvedSchema'
262
255
  if (this.resolvedSchema.dependencies || this.resolvedSchema.if) {
@@ -266,9 +259,7 @@ export default {
266
259
  const fullSchema = schemaUtils.prepareFullSchema(this.resolvedSchema, this.value, this.fullOptions)
267
260
  // kinda hackish but prevents triggering large rendering chains when nothing meaningful changes
268
261
  if (deepEqual(fullSchema, this.fullSchema)) {
269
- this.debug('fullSchema no change detected')
270
262
  } else {
271
- this.debug('fullSchema changed')
272
263
  this.fullSchema = fullSchema
273
264
  }
274
265
  }, {
@@ -282,7 +273,6 @@ export default {
282
273
  /* if (this.renderInc === 100) {
283
274
  throw new Error('detected infinite rendering loop: ' + this.fullKey)
284
275
  } */
285
- this.debug('render', this.renderInc)
286
276
 
287
277
  // hide const ? Or make a readonly field ?
288
278
  if (!this.fullSchema || this.fullSchema.const !== undefined || this.display === 'hidden' || (this.fullSchema.readOnly && this.fullOptions.hideReadOnly)) {
@@ -331,9 +321,6 @@ export default {
331
321
  return h('v-col', { props: colProps, class: this.propertyClass, style: this.fullSchema['x-style'] || '' }, children)
332
322
  },
333
323
  methods: {
334
- debug(msg, param) {
335
- if (debugFlag === '*' || debugFlag === this.fullKey) console.log(`[${this.fullKey}] ${msg}`, param || '')
336
- },
337
324
  cached(key, params, fn) {
338
325
  this._vjsf_cache = this._vjsf_cache || {}
339
326
  if (!this._vjsf_cache[key] || !deepEqual(this._vjsf_cache[key].params, params)) {
@@ -346,30 +333,35 @@ export default {
346
333
  },
347
334
  // used by all functionalities that require looking into the data or the context (x-if, fromData, etc)
348
335
  getFromExpr(exp) {
349
- const expData = {
350
- modelRoot: this.modelRoot,
351
- root: this.modelRoot,
352
- model: this.value,
353
- value: this.value,
354
- context: this.options.context
355
- }
336
+ const expData = this.getExprNode()
337
+ expData.modelRoot = this.modelRoot
338
+ expData.root = this.modelRoot
339
+ expData.model = this.value
340
+ expData.context = this.options.context
341
+
356
342
  this._vjsf_getters = this._vjsf_getters || {}
357
343
 
358
344
  if (this.initialOptions.evalMethod === 'newFunction') {
345
+ debugExpr(`evaluate expression "${exp}" with newFunction method`, expData)
359
346
  // use a powerful meta-programming approach with "new Function", not safe if the schema is user-submitted
360
347
  // eslint-disable-next-line no-new-func
361
348
  this._vjsf_getters[exp] = this._vjsf_getters[exp] || new Function(...Object.keys(expData), `return ${exp}`)
362
- return this._vjsf_getters[exp](...Object.values(expData))
349
+ const result = this._vjsf_getters[exp](...Object.values(expData))
350
+ debugExpr(`result`, result)
351
+ return result
363
352
  } else {
364
353
  exp = this.prefixExpr(exp)
354
+ debugExpr(`evaluate expression "${exp}" with propertyExpr method`, expData)
365
355
  // otherwise a safer but not as powerful deep getter method
366
356
  this._vjsf_getters[exp] = this._vjsf_getters[exp] || expr.getter(exp, true)
367
- return this._vjsf_getters[exp](expData)
357
+ const result = this._vjsf_getters[exp](expData)
358
+ debugExpr(`result`, result)
359
+ return result
368
360
  }
369
361
  },
370
362
  // used by getFromExpr to support simpler expressions that look into the root model by default
371
363
  prefixExpr(key) {
372
- if (key.startsWith('context.') || key.startsWith('model.') || key.startsWith('value.') || key.startsWith('modelRoot.') || key.startsWith('root.')) return key
364
+ if (key.startsWith('context.') || key.startsWith('model.') || key.startsWith('value.') || key.startsWith('modelRoot.') || key.startsWith('root.') || key.startsWith('parent.')) return key
373
365
  // no specific prefix found, we use modelRoot for retro-compatibility
374
366
  if (this.modelRoot) return 'root.' + key
375
367
  return 'model.' + key
@@ -396,7 +388,6 @@ export default {
396
388
  },
397
389
  input(value, initial = false, fastForward = true) {
398
390
  if (Array.isArray(value) && this.separator) value = value.join(this.separator)
399
- // this.debug('input', JSON.stringify([this.value, value]))
400
391
  if (value === null || value === undefined || (value === '' && this.fullSchema.default !== '')) {
401
392
  if (this.fullSchema.nullable) {
402
393
  if (this.value !== null) {
@@ -440,7 +431,6 @@ export default {
440
431
  return null
441
432
  },
442
433
  fixProperties(value) {
443
- this.debug('fixProperties')
444
434
  if (this.fullSchema.type !== 'object' || !value) return value
445
435
 
446
436
  const nonSchematized = (!this.fullSchema.properties || !this.fullSchema.properties.length) && (!Object.keys(this.subModels).length || !!this.fullSchema['x-fromData'] || !!this.fullSchema['x-fromUrl'])
@@ -472,7 +462,6 @@ export default {
472
462
  return value
473
463
  },
474
464
  initFromSchema() {
475
- this.debug('initFromSchema')
476
465
  // initiallyDefined will by used in Validatable.js to perform initial validation or not
477
466
  this.initiallyDefined = this.value !== undefined && this.value !== null
478
467
  // we cannot consider empty objects and empty arrays as "defined" as they might have been initialized by vjsf itself
@@ -12,11 +12,9 @@ export default {
12
12
  },
13
13
  computed: {
14
14
  isEditableArray() {
15
- this.debug('compute isEditableArray')
16
15
  if (this.resolvedSchema.type === 'array' && this.resolvedSchema.items && this.resolvedSchema.items.type === 'object') return true
17
16
  },
18
17
  readonlyItemSchema() {
19
- this.debug('compute readonlyItemSchema')
20
18
  if (!this.fullSchema || !this.fullSchema.items) return
21
19
 
22
20
  const schema = copy(this.fullSchema.items)
@@ -247,7 +245,6 @@ export default {
247
245
  } else {
248
246
  itemChild = this.renderArrayItemRO(h, item, i)
249
247
  itemKey = this.cached(`item-key-${i}`, { item }, () => {
250
- this.debug('new RO item key', i)
251
248
  return `${i}-${new Date().getTime()}`
252
249
  })
253
250
  if (!this.fullOptions.disableSorting) {
@@ -13,7 +13,6 @@ export default {
13
13
  },
14
14
  computed: {
15
15
  isObjectContainer() {
16
- this.debug('compute isObjectContainer')
17
16
  if (!this.fullSchema) return
18
17
  if (this.fullSchema.type !== 'object' && !Array.isArray(this.fullSchema.items)) return false
19
18
  if (this.isSelectProp) return false
@@ -21,12 +20,10 @@ export default {
21
20
  return true
22
21
  },
23
22
  subSchemas() {
24
- this.debug('compute subSchemas')
25
23
  if (!this.fullSchema) return
26
24
  return this.fullSchema.oneOf || this.fullSchema.anyOf
27
25
  },
28
26
  subSchemasConstProp() {
29
- this.debug('compute subSchemasConstProp')
30
27
  if (!this.subSchemas) return
31
28
  const props = this.subSchemas[0].properties
32
29
  const key = Object.keys(props).find(p => !!props[p].const)
@@ -34,13 +31,11 @@ export default {
34
31
  return { ...props[key], key, htmlDescription: this.fullOptions.memMarkdown(props[key].description) }
35
32
  },
36
33
  subSchemasRequired() {
37
- this.debug('compute subSchemasRequired')
38
34
  if (!this.subSchemas || !this.subSchemasConstProp) return false
39
35
  if (this.fullSchema.oneOf) return true
40
36
  if (this.fullSchema.anyOf && this.fullSchema.required && this.fullSchema.required.find(r => r === this.oneOfConstProp.key)) return true
41
37
  },
42
38
  subSchemasRules() {
43
- this.debug('compute subSchemasRules')
44
39
  if (!this.fullSchema) return
45
40
  const rules = []
46
41
  if (this.subSchemasRequired) rules.push((val) => (val !== undefined && val !== null && val !== '') || this.fullOptions.messages.required)
@@ -49,7 +44,6 @@ export default {
49
44
  },
50
45
  watch: {
51
46
  currentOneOf(newVal, oldVal) {
52
- this.debug('watched currentOneOf')
53
47
  // use this boolean to force removing then re-creating the object property
54
48
  // based on the currentOneOf sub schema. If we don't the component is reused and reactivity creates some difficult bugs.
55
49
  this.showCurrentOneOf = false
@@ -67,7 +61,6 @@ export default {
67
61
  },
68
62
  subModels: {
69
63
  handler() {
70
- this.debug('watched subModels')
71
64
  this.input(this.fixProperties(this.value), false, false)
72
65
  },
73
66
  deep: true
@@ -9,7 +9,8 @@ export default {
9
9
  form: {
10
10
  register: this.register,
11
11
  unregister: this.unregister,
12
- fastForwardEvent: this.fastForwardEvent
12
+ fastForwardEvent: this.fastForwardEvent,
13
+ getExprNode: this.getExprNode
13
14
  }
14
15
  }
15
16
  },
@@ -29,20 +30,16 @@ export default {
29
30
  },
30
31
  computed: {
31
32
  childrenInputs() {
32
- this.debug('compute childrenInputs')
33
33
  return this.inputs.reduce((a, input, i) => { a[input.modelKey || i] = input; return a }, {})
34
34
  },
35
35
  hasError() {
36
- this.debug('compute hasError')
37
36
  return !!this.inputs.find(input => input.hasError) || !!this.localRuleError
38
37
  },
39
38
  hasValidatedError() {
40
- this.debug('compute hasValidatedError')
41
39
  return !!this.inputs.find(input => input.hasValidatedError || (input.hasError && (input.validated || input.shouldValidate))) ||
42
40
  (this.localRuleError && (this.validated || this.shouldValidate))
43
41
  },
44
42
  childrenWithValidatedErrors() {
45
- this.debug('compute childrenWithValidatedErrors')
46
43
  return Object.keys(this.childrenInputs).filter(key => !!this.childrenInputs[key].hasValidatedError)
47
44
  },
48
45
  localRuleError() {
@@ -59,7 +56,6 @@ export default {
59
56
  // nextTick prevents some hard to debug infinite loops
60
57
  this.$nextTick(() => {
61
58
  if (!deepEqual(this.childrenWithValidatedErrors, this.dedupChildrenWithValidatedErrors)) {
62
- this.debug('set dedupChildrenWithValidatedErrors', JSON.stringify(this.childrenWithValidatedErrors))
63
59
  this.dedupChildrenWithValidatedErrors = this.childrenWithValidatedErrors
64
60
  }
65
61
  })
@@ -73,12 +69,10 @@ export default {
73
69
  },
74
70
  methods: {
75
71
  register(input) {
76
- this.debug('register', input.modelKey)
77
72
  if (this.validated) input.validate(true)
78
73
  this.inputs.push(input)
79
74
  },
80
75
  unregister(input) {
81
- this.debug('unregister', input.modelKey)
82
76
  this.inputs = this.inputs.filter(i => i._uid !== input._uid)
83
77
  },
84
78
  validate(force) {
@@ -87,7 +81,6 @@ export default {
87
81
  valid: input.validate(force),
88
82
  key: input.modelKey || i
89
83
  }))
90
- this.debug('validate children inputs', results)
91
84
  return !results.find(r => !r.valid)
92
85
  },
93
86
  reset() {
@@ -111,6 +104,15 @@ export default {
111
104
  // emit an event to the top of the vjsf instances tree exactly as it is
112
105
  if (this.fullKey === 'root') this.$emit(eventName, data)
113
106
  else this.form.fastForwardEvent(eventName, data)
107
+ },
108
+ getExprNode() {
109
+ const node = {
110
+ value: this.value,
111
+ key: this.modelKey,
112
+ fullKey: this.fullKey
113
+ }
114
+ if (this.form && this.form.getExprNode) node.parent = this.form.getExprNode()
115
+ return node
114
116
  }
115
117
  }
116
118
  }
@@ -130,10 +130,10 @@ export const localizedMessages = {
130
130
  required: 'Esta información es requerida',
131
131
  noData: 'No se encontraron valores coincidentes',
132
132
  search: 'Buscar...',
133
- minimum: 'El valor debe ser mayor o igual que {mínimo}',
134
- exclusiveMinimum: 'El valor debe ser mayor que {minimum}',
133
+ minimum: 'El valor debe ser mayor o igual que {minimum}',
134
+ exclusiveMinimum: 'El valor debe ser mayor que {exclusiveMinimum}',
135
135
  maximum: 'El valor debe ser menor o igual a {maximum}',
136
- exclusiveMaximum: 'El valor debe ser inferior a {maximum}',
136
+ exclusiveMaximum: 'El valor debe ser inferior a {exclusiveMaximum}',
137
137
  minLength: '{minLength} caracteres mínimo',
138
138
  maxLength: '{maxLength} caractères máximo',
139
139
  minItems: 'Al menos {minItems} articulos',
@@ -145,10 +145,10 @@ export const localizedMessages = {
145
145
  required: 'Diese Informationen sind erforderlich',
146
146
  noData: 'Keine passenden Artikel',
147
147
  search: 'Suche...',
148
- minimum: 'Der Wert muss größer oder gleich {Minimum} sein',
148
+ minimum: 'Der Wert muss größer oder gleich {minimum} sein',
149
149
  exclusiveMinimum: 'Der Wert muss größer als {exclusiveMinimum} sein',
150
- maximum: 'Der Wert muss kleiner oder gleich {Maximum} sein',
151
- exclusiveMaximum: 'Der Wert muss kleiner als {maximum} sein',
150
+ maximum: 'Der Wert muss kleiner oder gleich {maximum} sein',
151
+ exclusiveMaximum: 'Der Wert muss kleiner als {exclusiveMaximum} sein',
152
152
  minLength: 'Mindestens {minLength} Zeichen',
153
153
  maxLength: 'Maximal {maxLength} Zeichen',
154
154
  minItems: 'Mindestens {minItems} Elemente',
@@ -178,7 +178,7 @@ export const localizedMessages = {
178
178
  minimum: 'Değer {minimum} dan büyük olmalı',
179
179
  exclusiveMinimum: 'Değer {exclusiveMinimum} dan büyük olmalı',
180
180
  maximum: 'Değer, {maximum} değerinden küçük veya ona eşit olmalıdır',
181
- exclusiveMaximum: 'Değer {maximum} dan küçük olmalı',
181
+ exclusiveMaximum: 'Değer {exclusiveMaximum} dan küçük olmalı',
182
182
  minLength: '{minLength} asgari karakter sayısı',
183
183
  maxLength: '{maxLength} azami karakter sayısı',
184
184
  minItems: 'En az seçenek sayısı {minItems}',
@@ -193,7 +193,7 @@ export const localizedMessages = {
193
193
  minimum: 'De waarde moet groter zijn dan of gelijk zijn aan {minimum}',
194
194
  exclusiveMinimum: 'Waarde moet meer zijn dan {exclusiveMinimum}',
195
195
  maximum: 'De waarde moet lager zijn dan of gelijk zijn aan {maximum}',
196
- exclusiveMaximum: 'Waarde moet minder zijn dan {maximum}',
196
+ exclusiveMaximum: 'Waarde moet minder zijn dan {exclusiveMaximum}',
197
197
  minLength: 'Minimaal {minLength} tekens',
198
198
  maxLength: 'Maximaal {maxLength} tekens',
199
199
  minItems: 'Minimaal {minItems} antwoorden',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koumoul/vjsf",
3
- "version": "2.9.1",
3
+ "version": "2.10.3",
4
4
  "description": "Generate forms for the vuetify UI library (vuejs) based on annotated JSON schemas.",
5
5
  "main": "dist/main.js",
6
6
  "scripts": {
@@ -46,38 +46,36 @@
46
46
  },
47
47
  "homepage": "https://github.com/koumoul-dev/vuetify-jsonschema-form#readme",
48
48
  "dependencies": {
49
- "@mdi/js": "^5.5.55",
50
- "ajv": "^8.6.2",
49
+ "@mdi/js": "^6.5.95",
50
+ "ajv": "^8.9.0",
51
51
  "ajv-formats": "^2.1.1",
52
- "ajv-i18n": "^4.1.0",
53
- "debounce": "^1.2.0",
52
+ "ajv-i18n": "^4.2.0",
53
+ "debounce": "^1.2.1",
54
+ "debug": "^4.3.3",
54
55
  "fast-copy": "^2.1.1",
55
- "fast-equals": "^2.0.0",
56
- "markdown-it": "^8.4.2",
57
- "match-all": "^1.2.5",
58
- "object-hash": "^2.1.1",
59
- "property-expr": "^2.0.4",
56
+ "fast-equals": "^2.0.4",
57
+ "markdown-it": "^12.3.2",
58
+ "match-all": "^1.2.6",
59
+ "object-hash": "^2.2.0",
60
+ "property-expr": "^2.0.5",
60
61
  "vuedraggable": "^2.24.3"
61
62
  },
62
63
  "devDependencies": {
63
- "@babel/cli": "^7.5.5",
64
- "@babel/core": "^7.5.5",
65
- "@babel/preset-env": "^7.5.5",
64
+ "@babel/core": "^7.16.12",
65
+ "@babel/preset-env": "^7.16.11",
66
66
  "@koumoul/data-fair-search-widget": "^0.3.0",
67
67
  "@koumoul/gh-pages-multi": "^0.6.0",
68
- "@mdi/font": "^3.8.95",
68
+ "@mdi/font": "^6.5.95",
69
69
  "@nuxtjs/axios": "^5.13.6",
70
70
  "@nuxtjs/vuetify": "^1.12.3",
71
71
  "@toast-ui/vue-editor": "^2.5.1",
72
- "@vue/test-utils": "^1.0.3",
73
- "axios": "^0.21.1",
72
+ "@vue/test-utils": "^1.3.0",
73
+ "axios": "^0.25.0",
74
74
  "babel-core": "^7.0.0-bridge.0",
75
- "babel-eslint": "^10.0.2",
76
- "babel-jest": "^26.1.0",
77
- "babel-loader": "^8.0.6",
78
- "babel-polyfill": "^6.26.0",
75
+ "babel-eslint": "^10.1.0",
76
+ "babel-loader": "^8.2.3",
79
77
  "brace": "^0.11.1",
80
- "easymde": "^2.14.0",
78
+ "easymde": "^2.16.1",
81
79
  "eslint": "^6.1.0",
82
80
  "eslint-config-standard": "^13.0.1",
83
81
  "eslint-plugin-import": "^2.18.2",
@@ -85,26 +83,23 @@
85
83
  "eslint-plugin-node": "^9.1.0",
86
84
  "eslint-plugin-promise": "^4.2.1",
87
85
  "eslint-plugin-standard": "^4.0.0",
88
- "eslint-plugin-vue": "^5.2.3",
89
- "fuse.js": "^3.4.6",
90
- "highlight.js": "^10.4.1",
91
- "hjson": "^3.1.2",
86
+ "eslint-plugin-vue": "^7.20.0",
87
+ "highlight.js": "^11.4.0",
92
88
  "jest": "^26.1.0",
93
89
  "jest-serializer-vue": "^2.0.2",
94
- "mini-css-extract-plugin": "^0.8.0",
95
- "nuxt": "^2.15.3",
90
+ "mini-css-extract-plugin": "^1.6.2",
91
+ "nuxt": "^2.15.8",
96
92
  "random-words": "^1.1.0",
97
- "sanitize-html": "^2.3.0",
93
+ "sanitize-html": "^2.6.1",
98
94
  "stringify-object": "^3.3.0",
99
95
  "tiptap-vuetify": "^2.24.0",
100
96
  "v-mask": "^2.3.0",
101
97
  "vue-axios": "^2.1.5",
102
98
  "vue-cropperjs": "^4.2.0",
103
- "vue-jest": "^3.0.5",
104
- "vue-template-compiler": "^2.6.11",
105
- "vuetify": "^2.5.2",
106
- "webpack": "^4.39.0",
107
- "webpack-cli": "^3.3.6",
108
- "yaml": "^1.7.1"
99
+ "vue-jest": "^3.0.7",
100
+ "vue-template-compiler": "^2.6.14",
101
+ "vuetify": "^2.6.2",
102
+ "webpack-cli": "^4.9.1",
103
+ "yaml": "^1.10.2"
109
104
  }
110
105
  }
package/webpack.config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const path = require('path')
2
- const VueLoaderPlugin = require('vue-loader/lib/plugin')
2
+ const { VueLoaderPlugin } = require('vue-loader')
3
3
  const MiniCssExtractPlugin = require('mini-css-extract-plugin')
4
4
 
5
5
  const base = {
@@ -8,22 +8,16 @@ const base = {
8
8
  rules: [{
9
9
  test: /\.js$/,
10
10
  exclude: /(node_modules)/,
11
- loader: 'babel-loader',
12
- options: {
13
- presets: ['@babel/preset-env']
14
- }
11
+ use: 'babel-loader'
15
12
  }, {
16
13
  test: /\.vue$/,
17
- loader: 'vue-loader'
14
+ use: 'vue-loader'
18
15
  }, {
19
16
  test: /\.css$/,
20
- loader: [MiniCssExtractPlugin.loader, 'css-loader']
21
- }, {
22
- test: /\.less$/,
23
- loader: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
17
+ use: [MiniCssExtractPlugin.loader, 'css-loader']
24
18
  }, {
25
19
  test: /\.(svg|eot|woff|ttf|woff2)$/,
26
- loader: ['file-loader']
20
+ use: 'file-loader'
27
21
  }]
28
22
  },
29
23
  plugins: [