Skip to content

Commit 780298c

Browse files
authored
Merge pull request #67 from ember-best-practices/fix-no-global-jquery
[Bugfix] - Fixes #47 - const { $ } = Ember; still triggers no-global-jquery
2 parents b6fd460 + 557a0a9 commit 780298c

File tree

3 files changed

+105
-36
lines changed

3 files changed

+105
-36
lines changed

guides/rules/no-global-jquery.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# No Global jQuery
22

3-
**TL;DR** Do not use global `$` or `jQuery`. Use `Ember.$` instead.
3+
**TL;DR** Do not use global `$` or `jQuery`.
44

55
In general, we want application code to reference the version of jQuery that's been directly pinned
66
to the version of Ember used. This helps avoid version conflicts, and ensures that code inside modules

lib/rules/no-global-jquery.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
*/
44
'use strict';
55

6+
const { getEmberImportBinding } = require('../utils/imports');
7+
const { collectObjectPatternBindings } = require('../utils/destructed-binding');
8+
9+
const MESSAGE = 'Do not use global `$` or `jQuery`.';
610
const ALIASES = ['$', 'jQuery'];
711

812
/**
@@ -14,8 +18,6 @@ function isGlobalJquery(node) {
1418
return node.callee && ALIASES.includes(node.callee.name);
1519
}
1620

17-
const MESSAGE = 'Do not use global `$` or `jQuery`. Use `Ember.$` instead. Please see the following guide for more information: https://github.com/ember-best-practices/eslint-plugin-ember-best-practices/blob/master/guides/rules/no-global-jquery.md';
18-
1921
module.exports = {
2022
docs: {
2123
description: 'Disallow the use of global `$`',
@@ -26,9 +28,28 @@ module.exports = {
2628
message: MESSAGE
2729
},
2830
create(context) {
31+
let emberImportBinding;
32+
let destructuredAssignment = null;
33+
34+
function isDestructured(node) {
35+
return node && node.callee && node.callee.name === destructuredAssignment;
36+
}
37+
2938
return {
39+
ImportDefaultSpecifier(node) {
40+
emberImportBinding = getEmberImportBinding(node);
41+
},
42+
43+
ObjectPattern(node) {
44+
if (emberImportBinding) {
45+
destructuredAssignment = collectObjectPatternBindings(node, {
46+
[emberImportBinding]: ['$']
47+
}).pop();
48+
}
49+
},
50+
3051
CallExpression(node) {
31-
if (isGlobalJquery(node)) {
52+
if (!isDestructured(node) && isGlobalJquery(node)) {
3253
context.report(node, MESSAGE);
3354
}
3455
}

tests/lib/rules/no-global-jquery.js

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ const rule = require('../../../lib/rules/no-global-jquery');
22
const MESSAGE = rule.meta.message;
33
const RuleTester = require('eslint').RuleTester;
44
const ruleTester = new RuleTester();
5+
const parserOptions = {
6+
ecmaVersion: 6,
7+
sourceType: 'module'
8+
};
59

610
ruleTester.run('no-global-jquery', rule, {
711
valid: [
@@ -12,10 +16,7 @@ ruleTester.run('no-global-jquery', rule, {
1216
this.v1 = Ember.$('.v1');
1317
},
1418
});`,
15-
parserOptions: {
16-
ecmaVersion: 6,
17-
sourceType: 'module'
18-
}
19+
parserOptions
1920
},
2021
{
2122
code: `
@@ -24,10 +25,7 @@ ruleTester.run('no-global-jquery', rule, {
2425
this.v2 = this.$();
2526
},
2627
});`,
27-
parserOptions: {
28-
ecmaVersion: 6,
29-
sourceType: 'module'
30-
}
28+
parserOptions
3129
},
3230
{
3331
code: `
@@ -38,10 +36,7 @@ ruleTester.run('no-global-jquery', rule, {
3836
}
3937
}
4038
});`,
41-
parserOptions: {
42-
ecmaVersion: 6,
43-
sourceType: 'module'
44-
}
39+
parserOptions
4540
},
4641
{
4742
code: `
@@ -52,10 +47,75 @@ ruleTester.run('no-global-jquery', rule, {
5247
}
5348
}
5449
});`,
55-
parserOptions: {
56-
ecmaVersion: 6,
57-
sourceType: 'module'
58-
}
50+
parserOptions
51+
},
52+
{
53+
code: `
54+
import Ember from 'ember';
55+
56+
const { $ } = Ember;
57+
58+
export default Ember.Component({
59+
init() {
60+
this.el = $('.test');
61+
}
62+
});`,
63+
parserOptions,
64+
errors: [{
65+
message: MESSAGE
66+
}]
67+
},
68+
{
69+
code: `
70+
import Ember from 'ember';
71+
72+
const { $ } = Ember;
73+
74+
export default Ember.Component({
75+
actions: {
76+
valid() {
77+
this.inv1 = $('.invalid1');
78+
}
79+
}
80+
});`,
81+
parserOptions,
82+
errors: [{
83+
message: MESSAGE
84+
}]
85+
},
86+
{
87+
code: `
88+
import Ember from 'ember';
89+
90+
const { $: foo } = Ember;
91+
92+
export default Ember.Component({
93+
init() {
94+
this.el = foo('.test');
95+
}
96+
});`,
97+
parserOptions,
98+
errors: [{
99+
message: MESSAGE
100+
}]
101+
},
102+
{
103+
code: `
104+
import Ember from 'ember';
105+
106+
const { $: foo } = Ember;
107+
108+
export default Ember.Component({
109+
actions: {
110+
valid() {
111+
this.inv1 = foo('.invalid1');
112+
}
113+
}
114+
});`,
115+
parserOptions,
116+
errors: [{
117+
message: MESSAGE
118+
}]
59119
}
60120
],
61121
invalid: [
@@ -66,10 +126,7 @@ ruleTester.run('no-global-jquery', rule, {
66126
this.el = $('.test');
67127
}
68128
});`,
69-
parserOptions: {
70-
ecmaVersion: 6,
71-
sourceType: 'module'
72-
},
129+
parserOptions,
73130
errors: [{
74131
message: MESSAGE
75132
}]
@@ -83,10 +140,7 @@ ruleTester.run('no-global-jquery', rule, {
83140
}
84141
}
85142
});`,
86-
parserOptions: {
87-
ecmaVersion: 6,
88-
sourceType: 'module'
89-
},
143+
parserOptions,
90144
errors: [{
91145
message: MESSAGE
92146
}]
@@ -98,10 +152,7 @@ ruleTester.run('no-global-jquery', rule, {
98152
this.el = jQuery('.test');
99153
}
100154
});`,
101-
parserOptions: {
102-
ecmaVersion: 6,
103-
sourceType: 'module'
104-
},
155+
parserOptions,
105156
errors: [{
106157
message: MESSAGE
107158
}]
@@ -115,10 +166,7 @@ ruleTester.run('no-global-jquery', rule, {
115166
}
116167
}
117168
});`,
118-
parserOptions: {
119-
ecmaVersion: 6,
120-
sourceType: 'module'
121-
},
169+
parserOptions,
122170
errors: [{
123171
message: MESSAGE
124172
}]

0 commit comments

Comments
 (0)