Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 1436642

Browse files
committedDec 10, 2018
feat: add no-timing-in-fetch-data
1 parent f4f750a commit 1436642

File tree

5 files changed

+218
-2
lines changed

5 files changed

+218
-2
lines changed
 

‎docs/rules/no-timing-in-fetch-data.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# nuxt/no-timing-in-fetch-data
2+
3+
> disallow `setTimeout/setInterval` in `asyncData/fetch`
4+
5+
- :gear: This rule is included in `"plugin:nuxt/recommended"`.
6+
7+
## Rule Details
8+
9+
This rule is for preventing using `setTimeout/setInterval` in `asyncData/fetch` since it may lead to memory leak
10+
11+
Examples of **incorrect** code for this rule:
12+
13+
```js
14+
15+
export default {
16+
async asyncData() {
17+
let foo = 'baz'
18+
},
19+
fetch() {
20+
let foo = 'baz'
21+
}
22+
}
23+
24+
```
25+
26+
Examples of **correct** code for this rule:
27+
28+
```js
29+
30+
export default {
31+
asyncData() {
32+
let foo = 'bar'
33+
setTimeout(() => {
34+
foo = 'baz'
35+
}, 0)
36+
},
37+
fetch() {
38+
let foo = 'bar'
39+
setInterval(() => {
40+
foo = 'baz'
41+
}, 0)
42+
}
43+
}
44+
45+
```
46+
47+
## :mag: Implementation
48+
49+
- [Rule source](https://github.com/nuxt/eslint-plugin-nuxt/blob/master/lib/rules/no-timing-in-fetch-data.js)
50+
- [Test source](https://github.com/nuxt/eslint-plugin-nuxt/blob/master/lib/rules/__test__/no-timing-in-fetch-data.test.js)

‎lib/configs/ssr.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module.exports = {
22
extends: require.resolve('./base.js'),
33
rules: {
4-
'nuxt/no-globals-in-created': 'warn'
4+
'nuxt/no-globals-in-created': 'warn',
5+
'nuxt/no-timing-in-fetch-data': 'warn'
56
}
67
}

‎lib/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ module.exports = {
44
'no-this-in-fetch': require('./rules/no-this-in-fetch')
55
},
66
configs: {
7-
'base': require('./configs/base')
7+
'base': require('./configs/base'),
8+
'ssr': require('./configs/ssr')
89
},
910
processors: {
1011
'.vue': require('./processors')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* @fileoverview disallow `setTimeout/setInterval` in `asyncData/fetch`
3+
* @author Xin Du <clark.duxin@gmail.com>
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
var rule = require('../no-timing-in-fetch-data')
12+
13+
var RuleTester = require('eslint').RuleTester
14+
15+
const parserOptions = {
16+
ecmaVersion: 2018,
17+
sourceType: 'module'
18+
}
19+
20+
// ------------------------------------------------------------------------------
21+
// Tests
22+
// ------------------------------------------------------------------------------
23+
24+
var ruleTester = new RuleTester()
25+
ruleTester.run('no-timing-in-fetch-data', rule, {
26+
27+
valid: [
28+
{
29+
filename: 'test.vue',
30+
code: `
31+
export default {
32+
async asyncData() {
33+
let foo = 'baz'
34+
},
35+
fetch() {
36+
let foo = 'baz'
37+
}
38+
}
39+
`,
40+
parserOptions
41+
}
42+
],
43+
44+
invalid: [
45+
{
46+
filename: 'test.vue',
47+
code: `
48+
export default {
49+
asyncData() {
50+
let foo = 'bar'
51+
setTimeout(() => {
52+
foo = 'baz'
53+
}, 0)
54+
},
55+
fetch() {
56+
let foo = 'bar'
57+
setInterval(() => {
58+
foo = 'baz'
59+
}, 0)
60+
}
61+
}
62+
`,
63+
errors: [{
64+
message: 'Unexpected setTimeout in asyncData.',
65+
type: 'CallExpression'
66+
}, {
67+
message: 'Unexpected setInterval in fetch.',
68+
type: 'CallExpression'
69+
}],
70+
parserOptions
71+
},
72+
{
73+
filename: 'test.vue',
74+
code: `
75+
export default {
76+
asyncData() {
77+
let timer = setInterval
78+
},
79+
fetch() {
80+
let timer = setTimeout
81+
}
82+
}
83+
`,
84+
errors: [{
85+
message: 'Unexpected setInterval in asyncData.',
86+
type: 'VariableDeclarator'
87+
}, {
88+
message: 'Unexpected setTimeout in fetch.',
89+
type: 'VariableDeclarator'
90+
}],
91+
parserOptions
92+
}
93+
]
94+
})

‎lib/rules/no-timing-in-fetch-data.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @fileoverview disallow `setTimeout/setInterval` in `asyncData/fetch`
3+
* @author Xin Du <clark.duxin@gmail.com>
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
9+
// ------------------------------------------------------------------------------
10+
// Rule Definition
11+
// ------------------------------------------------------------------------------
12+
13+
module.exports = {
14+
meta: {
15+
docs: {
16+
description: 'disallow `setTimeout/setInterval` in `asyncData/fetch`',
17+
category: 'ssr'
18+
},
19+
messages: {
20+
noTiming: 'Unexpected {{name}} in {{funcName}}.'
21+
}
22+
},
23+
24+
create: function (context) {
25+
const forbiddenNodes = []
26+
const options = context.options[0] || {}
27+
28+
const HOOKS = new Set(
29+
['fetch', 'asyncData'].concat(options.methods || [])
30+
)
31+
const TIMING = ['setTimeout', 'setInterval']
32+
33+
function isTiming (name) {
34+
return TIMING.includes(name)
35+
}
36+
37+
return {
38+
CallExpression: function (node) {
39+
if (!node.callee) return
40+
41+
const name = node.callee.name
42+
43+
if (isTiming(name)) {
44+
forbiddenNodes.push({ name, node })
45+
}
46+
},
47+
VariableDeclarator (node) {
48+
if (!node.init) return
49+
50+
const name = node.init.name
51+
52+
if (isTiming(name)) {
53+
forbiddenNodes.push({ name, node })
54+
}
55+
},
56+
...utils.executeOnVue(context, obj => {
57+
for (const { funcName, name, node } of utils.getFunctionWithChild(obj, HOOKS, forbiddenNodes)) {
58+
context.report({
59+
node,
60+
messageId: 'noTiming',
61+
data: {
62+
name,
63+
funcName
64+
}
65+
})
66+
}
67+
})
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)
This repository has been archived.