-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add no node env ssr rule (#130)
* chore: add rule to disallow process.env.NODE_ENV * docs: update no-node-env-in-ssr.md * chore: add no-node-env-in-ssr to README * chore: prettier * test: add no-node-env-in-ssr * Update lib/rules/no-node-env-in-ssr.js Co-authored-by: Dale Bustad <dale@divmain.com> * fix: add rule-helper for no-node-env * fix: add object guard * test: add more tests * fix: typo --------- Co-authored-by: Dale Bustad <dale@divmain.com>
- Loading branch information
Showing
7 changed files
with
395 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Disallow use of `process.env.NODE_ENV` during SSR (`lwc/no-node-env-in-ssr`) | ||
|
||
Using process.env.NODE_ENV during server-side rendering in JavaScript is not recommended because it can introduce unexpected behavior and bugs in your application. This environment variable is typically used for conditional logic related to development or production builds, which is more relevant on the client side. | ||
|
||
## Rule Details | ||
|
||
Example of **incorrect** code for this rule: | ||
|
||
```js | ||
import { LightningElement } from 'lwc'; | ||
|
||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.log('Foo:connectedCallback'); | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
import { LightningElement } from 'lwc'; | ||
|
||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
if (!import.meta.env.SSR && process.env.NODE_ENV !== 'production') { | ||
console.log('Foo:connectedCallback'); | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) 2023, salesforce.com, inc. | ||
* All rights reserved. | ||
* SPDX-License-Identifier: MIT | ||
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT | ||
*/ | ||
'use strict'; | ||
|
||
const { noNodeEnvInSSR } = require('../rule-helpers'); | ||
const { docUrl } = require('../util/doc-url'); | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
url: docUrl('no-node-env-in-ssr'), | ||
category: 'LWC', | ||
description: 'disallow access of process.env.NODE_ENV in SSR', | ||
}, | ||
schema: [], | ||
messages: { | ||
nodeEnvFound: 'process.env.NODE_ENV is unsupported in SSR.', | ||
}, | ||
}, | ||
create: (context) => { | ||
return noNodeEnvInSSR(context); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
/* | ||
* Copyright (c) 2018, salesforce.com, inc. | ||
* All rights reserved. | ||
* SPDX-License-Identifier: MIT | ||
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT | ||
*/ | ||
'use strict'; | ||
const { RuleTester } = require('eslint'); | ||
|
||
const { ESLINT_TEST_CONFIG } = require('../shared'); | ||
const rule = require('../../../lib/rules/no-node-env-in-ssr'); | ||
|
||
const tester = new RuleTester(ESLINT_TEST_CONFIG); | ||
|
||
tester.run('no-node-env-in-ssr', rule, { | ||
valid: [ | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
// we can't use process.env.NODE_ENV here | ||
} | ||
renderedCallback() { | ||
if (process.env.NODE_ENV === 'development') { | ||
console.log('test'); | ||
} | ||
} | ||
bar() { | ||
if (process.env.NODE_ENV === 'development') { | ||
console.log('test'); | ||
} | ||
} | ||
} | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
// we can't use process.env.NODE_ENV here | ||
} | ||
renderedCallback() { | ||
this.bar(); | ||
} | ||
bar() { | ||
if (process.env.NODE_ENV === 'development') { | ||
console.log('test'); | ||
} | ||
} | ||
} | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
// we can't use process.env.NODE_ENV here | ||
} | ||
bar() { | ||
doSomething(process.emv.NODE_ENV); | ||
} | ||
} | ||
`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
if (process.env.NODE_ENV === 'development') { | ||
console.log('test'); | ||
} | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
this.foo(); | ||
} | ||
foo() { | ||
if (process.env.NODE_ENV === 'development') { | ||
console.log('test'); | ||
} | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
doSomethingWith(process.env.NODE_ENV); | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
this.foo(); | ||
} | ||
renderedCallback() { | ||
this.foo(); | ||
} | ||
foo() { | ||
doSomethingWith(process.env.NODE_ENV); | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
this.foo(); | ||
} | ||
renderedCallback() { | ||
this.foo(); | ||
} | ||
foo() { | ||
doSomethingWith(process.env.NODE_ENV); | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
connectedCallback() { | ||
this.foo(); | ||
} | ||
renderedCallback() { | ||
this.foo(); | ||
} | ||
foo() { | ||
doSomethingWith(process.env.NODE_ENV); | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
constructor() { | ||
if (process.env.NODE_ENV === 'development') { | ||
console.log('test'); | ||
} | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
constructor() { | ||
this.foo(); | ||
} | ||
foo() { | ||
doSomethingWith(process.env.NODE_ENV); | ||
} | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
import { LightningElement } from 'lwc'; | ||
import tmplA from './a.html'; | ||
export default class Foo extends LightningElement { | ||
foo = process.env.NODE_ENV; | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'nodeEnvFound', | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
Oops, something went wrong.