Comments (14)
I thought of another option, 5:
- Whitelist
window
anddocument
globals, as well as all browser globals that begin with an uppercase letter. Examples:Blob
,DataView
, andHTMLInputElement
. Since they're upper case and usually pretty verbose, they're a lot less likely to be used as variable names in node than the lowercase browser globals. Lower case browser globals likelength
,open
,top
would need to be used aswindow.length
,window.open
,window.top
.
Here's the full list of globals that we could keep whitelisted. Most don't seem like they would frequently cause problems in node.
[ 'Audio',
'AudioProcessingEvent',
'BeforeUnloadEvent',
'Blob',
'CanvasGradient',
'CanvasPattern',
'CanvasRenderingContext2D',
'CloseEvent',
'Comment',
'CompositionEvent',
'CSS',
'CustomEvent',
'DataView',
'Debug',
'Document',
'DocumentFragment',
'DOMParser',
'DragEvent',
'Element',
'ElementTimeControl',
'ErrorEvent',
'Event',
'FileReader',
'FocusEvent',
'FormData',
'GamepadEvent',
'HashChangeEvent',
'HTMLAnchorElement',
'HTMLBaseElement',
'HTMLBlockquoteElement',
'HTMLBodyElement',
'HTMLBRElement',
'HTMLButtonElement',
'HTMLCanvasElement',
'HTMLDirectoryElement',
'HTMLDivElement',
'HTMLDListElement',
'HTMLElement',
'HTMLFieldSetElement',
'HTMLFontElement',
'HTMLFormElement',
'HTMLFrameElement',
'HTMLFrameSetElement',
'HTMLHeadElement',
'HTMLHeadingElement',
'HTMLHRElement',
'HTMLHtmlElement',
'HTMLIFrameElement',
'HTMLImageElement',
'HTMLInputElement',
'HTMLIsIndexElement',
'HTMLLabelElement',
'HTMLLayerElement',
'HTMLLegendElement',
'HTMLLIElement',
'HTMLLinkElement',
'HTMLMapElement',
'HTMLMenuElement',
'HTMLMetaElement',
'HTMLModElement',
'HTMLObjectElement',
'HTMLOListElement',
'HTMLOptGroupElement',
'HTMLOptionElement',
'HTMLParagraphElement',
'HTMLParamElement',
'HTMLPreElement',
'HTMLQuoteElement',
'HTMLScriptElement',
'HTMLSelectElement',
'HTMLStyleElement',
'HTMLTableCaptionElement',
'HTMLTableCellElement',
'HTMLTableColElement',
'HTMLTableElement',
'HTMLTableRowElement',
'HTMLTableSectionElement',
'HTMLTextAreaElement',
'HTMLTitleElement',
'HTMLUListElement',
'HTMLVideoElement',
'IDBCursor',
'IDBCursorWithValue',
'IDBDatabase',
'IDBEnvironment',
'IDBFactory',
'IDBIndex',
'IDBKeyRange',
'IDBObjectStore',
'IDBOpenDBRequest',
'IDBRequest',
'IDBTransaction',
'IDBVersionChangeEvent',
'Image',
'InputEvent',
'Intl',
'KeyboardEvent',
'MessageChannel',
'MessageEvent',
'MessagePort',
'MouseEvent',
'MutationObserver',
'Node',
'NodeFilter',
'NodeList',
'Notification',
'OfflineAudioCompletionEvent',
'Option',
'PageTransitionEvent',
'PopStateEvent',
'ProgressEvent',
'Range',
'SharedWorker',
'StorageEvent',
'SVGAElement',
'SVGAltGlyphDefElement',
'SVGAltGlyphElement',
'SVGAltGlyphItemElement',
'SVGAngle',
'SVGAnimateColorElement',
'SVGAnimatedAngle',
'SVGAnimatedBoolean',
'SVGAnimatedEnumeration',
'SVGAnimatedInteger',
'SVGAnimatedLength',
'SVGAnimatedLengthList',
'SVGAnimatedNumber',
'SVGAnimatedNumberList',
'SVGAnimatedPathData',
'SVGAnimatedPoints',
'SVGAnimatedPreserveAspectRatio',
'SVGAnimatedRect',
'SVGAnimatedString',
'SVGAnimatedTransformList',
'SVGAnimateElement',
'SVGAnimateMotionElement',
'SVGAnimateTransformElement',
'SVGAnimationElement',
'SVGCircleElement',
'SVGClipPathElement',
'SVGColor',
'SVGColorProfileElement',
'SVGColorProfileRule',
'SVGComponentTransferFunctionElement',
'SVGCSSRule',
'SVGCursorElement',
'SVGDefsElement',
'SVGDescElement',
'SVGDocument',
'SVGElement',
'SVGElementInstance',
'SVGElementInstanceList',
'SVGEllipseElement',
'SVGEvent',
'SVGExternalResourcesRequired',
'SVGFEBlendElement',
'SVGFEColorMatrixElement',
'SVGFEComponentTransferElement',
'SVGFECompositeElement',
'SVGFEConvolveMatrixElement',
'SVGFEDiffuseLightingElement',
'SVGFEDisplacementMapElement',
'SVGFEDistantLightElement',
'SVGFEFloodElement',
'SVGFEFuncAElement',
'SVGFEFuncBElement',
'SVGFEFuncGElement',
'SVGFEFuncRElement',
'SVGFEGaussianBlurElement',
'SVGFEImageElement',
'SVGFEMergeElement',
'SVGFEMergeNodeElement',
'SVGFEMorphologyElement',
'SVGFEOffsetElement',
'SVGFEPointLightElement',
'SVGFESpecularLightingElement',
'SVGFESpotLightElement',
'SVGFETileElement',
'SVGFETurbulenceElement',
'SVGFilterElement',
'SVGFilterPrimitiveStandardAttributes',
'SVGFitToViewBox',
'SVGFontElement',
'SVGFontFaceElement',
'SVGFontFaceFormatElement',
'SVGFontFaceNameElement',
'SVGFontFaceSrcElement',
'SVGFontFaceUriElement',
'SVGForeignObjectElement',
'SVGGElement',
'SVGGlyphElement',
'SVGGlyphRefElement',
'SVGGradientElement',
'SVGHKernElement',
'SVGICCColor',
'SVGImageElement',
'SVGLangSpace',
'SVGLength',
'SVGLengthList',
'SVGLinearGradientElement',
'SVGLineElement',
'SVGLocatable',
'SVGMarkerElement',
'SVGMaskElement',
'SVGMatrix',
'SVGMetadataElement',
'SVGMissingGlyphElement',
'SVGMPathElement',
'SVGNumber',
'SVGNumberList',
'SVGPaint',
'SVGPathElement',
'SVGPathSeg',
'SVGPathSegArcAbs',
'SVGPathSegArcRel',
'SVGPathSegClosePath',
'SVGPathSegCurvetoCubicAbs',
'SVGPathSegCurvetoCubicRel',
'SVGPathSegCurvetoCubicSmoothAbs',
'SVGPathSegCurvetoCubicSmoothRel',
'SVGPathSegCurvetoQuadraticAbs',
'SVGPathSegCurvetoQuadraticRel',
'SVGPathSegCurvetoQuadraticSmoothAbs',
'SVGPathSegCurvetoQuadraticSmoothRel',
'SVGPathSegLinetoAbs',
'SVGPathSegLinetoHorizontalAbs',
'SVGPathSegLinetoHorizontalRel',
'SVGPathSegLinetoRel',
'SVGPathSegLinetoVerticalAbs',
'SVGPathSegLinetoVerticalRel',
'SVGPathSegList',
'SVGPathSegMovetoAbs',
'SVGPathSegMovetoRel',
'SVGPatternElement',
'SVGPoint',
'SVGPointList',
'SVGPolygonElement',
'SVGPolylineElement',
'SVGPreserveAspectRatio',
'SVGRadialGradientElement',
'SVGRect',
'SVGRectElement',
'SVGRenderingIntent',
'SVGScriptElement',
'SVGSetElement',
'SVGStopElement',
'SVGStringList',
'SVGStylable',
'SVGStyleElement',
'SVGSVGElement',
'SVGSwitchElement',
'SVGSymbolElement',
'SVGTests',
'SVGTextContentElement',
'SVGTextElement',
'SVGTextPathElement',
'SVGTextPositioningElement',
'SVGTitleElement',
'SVGTransform',
'SVGTransformable',
'SVGTransformList',
'SVGTRefElement',
'SVGTSpanElement',
'SVGUnitTypes',
'SVGURIReference',
'SVGUseElement',
'SVGViewElement',
'SVGViewSpec',
'SVGVKernElement',
'SVGZoomAndPan',
'Text',
'TextDecoder',
'TextEncoder',
'TimeEvent',
'TouchEvent',
'UIEvent',
'URL',
'WebGLActiveInfo',
'WebGLBuffer',
'WebGLContextEvent',
'WebGLFramebuffer',
'WebGLProgram',
'WebGLRenderbuffer',
'WebGLRenderingContext',
'WebGLShader',
'WebGLShaderPrecisionFormat',
'WebGLTexture',
'WebGLUniformLocation',
'WebSocket',
'WheelEvent',
'Window',
'Worker',
'XDomainRequest',
'XMLHttpRequest',
'XMLSerializer',
'XPathEvaluator',
'XPathException',
'XPathExpression',
'XPathNamespace',
'XPathNSResolver',
'XPathResult' ]
These variables, on the other hand, would need to be accessed on window
, like window.btoa
:
[ 'addEventListener',
'alert',
'applicationCache',
'atob',
'blur',
'btoa',
'cancelAnimationFrame',
'clearInterval',
'clearTimeout',
'close',
'closed',
'confirm',
'console',
'crypto',
'defaultStatus',
'devicePixelRatio',
'dispatchEvent',
'document',
'event',
'find',
'focus',
'frameElement',
'frames',
'getComputedStyle',
'getSelection',
'history',
'indexedDB',
'innerHeight',
'innerWidth',
'length',
'localStorage',
'location',
'matchMedia',
'moveBy',
'moveTo',
'name',
'navigator',
'onbeforeunload',
'onblur',
'onerror',
'onfocus',
'onload',
'onresize',
'onunload',
'open',
'openDatabase',
'opener',
'opera',
'outerHeight',
'outerWidth',
'pageXOffset',
'pageYOffset',
'parent',
'postMessage',
'print',
'prompt',
'removeEventListener',
'requestAnimationFrame',
'resizeBy',
'resizeTo',
'screen',
'screenX',
'screenY',
'scroll',
'scrollbars',
'scrollBy',
'scrollTo',
'scrollX',
'scrollY',
'self',
'sessionStorage',
'setInterval',
'setTimeout',
'showModalDialog',
'status',
'stop',
'top',
'window' ]
from standard.
๐ io.js / node won't ever have a global window
object (jsdom
window is assigned explicitely) whereas the browser can have extra globals because of browserify
. Being able to turn off browser
to prevent issues like the one you just linked seems reasonable.
from standard.
Another good reason to split these modes apart: as I just discovered, because crypto
is a global in the browser, using it without defining it first will cause standard to fail to notice that you haven't imported crypto
in your Node module.
from standard.
Possible resolutions to this issue:
- Leave things as they are. @othiym23 - you can tell eslint that
opener
is writable with a/*global opener:true */
comment at the top of the relevant file. Using/*global opener */
marksopener
as read-only; usetrue
to mark it writable. Not an ideal solution because it makes no sense to a node.js user why they should have to add this comment. - Keep the current default behavior, but add
--node
and--browser
flags to restrict the assumed globals to only one environment's globals. Not ideal because we really, really want to avoid adding options. Like, that's sort of the point ofstandard
. - Allow use of any browser global (like we already do), but mark them all as writable. This way, you can do
var crypto = require('crypto')
andvar opener = require('opener')
without errors in node. All the browser globals are defined here. This would eliminate all errors and annoyances, but not ideal because it's overly permissive: as @othiym23 mentioned, nowstandard
won't error when any of the browser globals (likeopen
,close
,crypto
,screen
,scroll
,stop
,top
) are accidentally used in node without being defined first. - Disallow use of browser globals except for
window
anddocument
, as a compromise. These aren't really globals in node, so this is overly permissive, but at least it's just limited to TWO globals that we don't check. Then, force all browser code to reference browser globals as properties onwindow
, e.g.window.XMLHttpRequest
,window.open
,window.crypto
, etc. Anddocument
would just work:document.querySelector
, etc. Not ideal because now browser code becomes wordier, and we're still not checking for improper use of these two variables in node (not a huge deal). Also, ifstandard
is used with non-browserify browser code, it will still incorrectly assume that node globals likerequire
andBuffer
are defined. But I don't know how much we should care about non-browserify users.
Any other ideas?
from standard.
My preference is for 2, although I strongly agree with the goal of keeping configurability and modes to an absolute minimum. My argument in favor is that this is probably the biggest split going through the standard
user community โ many users are going to be writing code that is meant to work in both the browser and on the server, and smaller groups are going to be working on stuff that's meant for one or the other. The default behavior should stay the same as it is now, to support those users, but having a way to say, "yes, this is code that is only meant to run on the server" or "yes, this is code that is only meant to run in the browser" โ that can be changed later โ would be really helpful for those of us, like me, who are working with third-party libraries that make assumptions about the environment in which they're going to be used.
Just as a quick note, this would allow browserify users to get warnings for forgetting to shim their node globals in their browser code as well โย no process
or Buffer
required? Whoops!
from standard.
I think 4 is a nice middle ground. It is a bit annoying to not being able to use open
as a variable name in node right now etc. Personally I prefix all global variables with window.
in the browser anyways.
from standard.
I'm vehemently against 2
. User-friendly software should not have modes. 3
could cause problems. Although I already prefix all of my browser global variables with window
, many don't - so I think 4
will discourage a lot of people from using standard
. I realize that this is probably not an eslint
option, but an ideal solution seems to be that if a variable is set with the result of a require
statement, we could set it as writeable
(eslint) as it would seem to me that the intent is pretty clear. This actually may not be that difficult, however it would add more processing time. The way that you'd do it is use something like recast
(which in turn uses esprima
), scan the source file for require
statements that are set to browser globals, prepend the comment /*global opener:true */
. If that's not viable, my vote would be to just stick with #1 (do nothing) for the time being.
The ultimate goal here is to try to encourage standard
usage as much as possible, and 1
seems like a minor annoyance compared to the rest.
from standard.
@jprichardson perhaps writing a custom eslint rule that replaces no-undef with this special treatment would not affect processing time as much?
from standard.
Btw, I'm running option 4 on a local branch โย and I really like it so far โย the tests all pass with just a few additions of window.
or global.
in browser code and we don't need to add modes.
from standard.
I just published 3.0.0-alpha
with option 4. Please give it a try and share your feedback! It resolves @othiym23's original issue without introducing new options. The only exception is that window
and document
are always assumed to exist, even in node. Small issue, IMO.
npm install [email protected] -g
from standard.
Wow, eslint just made a change to properly support CommonJS module scope, i.e. using a variable name that is the same as a global is now allowed! eslint now understands that the local variable shadows the global in node (which we allow), and the "redefining a read-only variable" error goes away!
This is basically approach 3.
from standard.
I'm getting 'CustomEvent' is not defined. Will this be added to the whitelist?
Using "standard": "^9.0.2",
from standard.
from standard.
I just done this:
"standard": {
"globals": [
"CustomEvent",
"Event"
]
}
from standard.
Related Issues (20)
- Formatting code will make it unreadable
- Expanding Rostislav and I's contribution, into core
- TS-Standart Changed My Code and Throwing Error
- Create a tutorial to use Standard together with Husky
- Eslint v9 support HOT 2
- Add a lock file HOT 3
- Could you please paste the result of the `npm ls eslint` command? HOT 1
- Remove the lock-threads workflow
- Comments bring issues/PRs onto the project board HOT 1
- tittle
- space-unary-ops errors on `new Class()` syntax HOT 4
- Maintenance & Governance of standard HOT 47
- Format using a formatter instead of ESLint formatting rules HOT 15
- inline link with @ in Super to have link inline or below not above HOT 1
- Tags isn't exported with Export .md or HTML HOT 1
- Ctrl+Shift+E to open/close tag page isn't working HOT 2
- `standard.lintFiles()` doesn't use `process.cwd()` HOT 5
- RFC: eslint-config-standard-with-typescript to depart from standard HOT 19
- Rule suggestion: no-constant-binary-expression
- Linting in precommit hooks says File not found
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from standard.