Option to assume strict mode (for nodejs) #924

Closed
coolaj86 opened this Issue Mar 13, 2013 · 32 comments
@coolaj86

Now that nodejs is es5 compliant it can be run in strict mode by default without including (function () { "use strict"; /* code here */ }());.

Will you add an option implicitstrict so that it's not required to have the boilerplate code?

@valueof
JSHint member

There's globalstrict option to allow file-level "use strict";. Plus, if you enable node option it will implicitly enable file level strict mode directives.

@valueof valueof closed this Mar 13, 2013
@coolaj86

Cool! I didn't notice that in the docs. My bad.

@coolaj86

@antonkovalyov Actually, that option isn't what I'm talking about.

Node can now run node --use_strict myapp.js and it's not required to have "use strict"; anymore. Every module required throughout the whole stack will automatically run in strict mode.

Does that make sense?

I was also operating under the assumption that strict: true turns on other options implicitly. If that's not the case, then my point is invalid. But if it is the case, an implicitstrict: true would be nice to have the promptings of strict mode without actually having to type it at the top of each file.

@valueof valueof reopened this Mar 13, 2013
@Raynos

+1 for implicitStrict I want my linter to validate strict mode compliance but am too lazy to type "use strict";

@coolaj86

That's a good point too. It would be generally useful to have all of the linting of use strict without having to type it for every environment since in general more people use jshint than use use strict.

@mdevils

+1 for this issue.

@michaelmior

I don't quite follow how globalstrict doesn't get the job done. If you enable that option, all files are treated as if they contain "use strict";

If I create a file which contains

var x;
delete x; // invalid variable deletion

With { "globalstrict": true } in .jshintrc I get

test.js: line 2, col 9, Variables should not be deleted.

1 error

And running with node --use_strict.js (node v0.10.4) I get

/private/tmp/x/test.js:2
delete x;
       ^
SyntaxError: Delete of an unqualified identifier in strict mode.
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

I think there's something I'm missing about your use case.

@coolaj86

I was under the impression that globalstrict only allowed "use strict" to be declared at the file-level (instead of function-level), but didn't implicitly declare strict mode.

If globalstrict implicitly declares strict mode, then that's what I wanted.

But it would make sense to have a separate option that allows strict mode at the file level, to avoid confusion.

@michaelmior

@antonkovalyov Are you okay with changing the behavior of globalstrict to allow file-level "use strict"; and then adding a second option to make it implicit. The concern here is that globalstrict would no longer imply "use strict"; and would cause code to silently fail validation under old settings.

@valueof
JSHint member

@michaelmior I'd rather deprecate globalstrict and make strict a multivalue option (like unused and others):

strict:

  • false: no strict mode checks
  • true / "func": require "use strict" pragma in functions, disallow in global scope.
  • "global": require "use strict" pragma either in global scope or in function scope.
  • "implied": assume global strict-mode without requiring any pragma.
@coolaj86

+1

sounds like a logical solution to me

@domenic

I don't like the idea of JSHint validating this strange non-JavaScript language which has the semantics of strict mode without the pragma. Such code is not ES5 conformant or at all portable, and shouldn't be encouraged. The spec very clear: source files with the pragma are strict, and those without are not.

@Raynos

@domenic this is a practical option, not an ideal option.

The usage here is to have a static tool do what it does best, static analysis without effecting my run time code in production. Mainly because one can't turn on strict mode as it requires removing all arguments.callee code but one does want the static strict mode validation on a file by file basis.

Turning strict mode on for a single file and loading that in JS environment means you have to fix all your arguments code.

Validating a file as if it is in strict mode means you just have to edit your file to comply with the warnings your static tool gives you.

This basically empowers the developer with modular tooling without having to fix his entire codebase.

@manngo

I’m not sure that globalstrict is doing what the description implies.

I though that globalstrict was to allow a global "use strict" pragma, not to enforce it. In any case, the version I am using seems to complain about missing "use strict" statements from within functions, regardless of whether there is one at the beginning of the script.

@coolaj86

Yeah, I can confirm.

@eahutchins

@domenic this is useful for checking scripts which are lazy-loaded in an environment where strict mode is enabled globally.

I took a shot at adding this with #1279.

@tomjakubowski

I'm using Sprockets with a custom processor to add a strict-mode IIFE around each source file script. So a file like this:

// a.js
window.console.log('a');

is turned into:

(function (window) {
  'use strict';
  // a.js
  window.console.log('a');
})(this);

If I want to run JSHint on any of my unprocessed source files, I cannot presently do so while also in strict mode. An option which permits an 'implicit strict mode' would serve this and similar use cases well.

EDIT: edited to simplify the example

@mokkabonna

Is this feature still considered? Not with the assumestrict, but with a multi value option of globalstrict? I would love to have an implied globalstrict. My build process takes care of concating and wrapping in self executing function with use strict. But during edit time I want the files to validate without having to have each file contain "use strict";

@valueof
JSHint member

Sure, a multi-value option for strict:true|global|implicit. I'm not working actively on it but patches are welcomed.

@alexilyaev

@antonkovalyov I have a question, if I want to disallow usage of "use strict"; globally in JS (client side) files, but allow them in Node.js files, how do I do that with strict, globalstrict and node settings?
Currently doesn't work cause when you enable node: true, it suppresses globalstrict: false.

Actually, now that I read about it, it's confusing if it's an issue at all or not.
Considering text like this one:

You can if you wanted turn on strict mode everywhere by declaring it in global scope but weird
things might happen if you are using 3rd party libraries that don’t expect Strict Mode to be on so I
would keep to declaring it inside your functions for now.

Ref: http://alexjmackey.wordpress.com/2014/02/22/developing-a-webgl-game-part-2-keeping-javascript-organized/

But then actually testing global "use strict"; doesn't act that way:
http://stackoverflow.com/questions/6483768/would-this-enable-use-strict-globally

Is it safe to just put node: true at the top of all of my JS files?

Edit: Found the reason (under How do you use it?):
http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/

With that in mind, my first question still stands.

@valueof
JSHint member

You don't need to do anything. Just use strict:true for client side JavaScript and strict:true node:true for your server side code.

@alexilyaev

Oh, you mean a different .jshintrc file in the client side folder?
Since it's all in the same repository.
...
I've added this to the public folder as a .jshintrc file and it works well by overriding the root settings:

{
    "node": false
}

And the root .jshintrc file has "strict": true, "node": true, "globalstrict": false.

Thanks! :-)

@alexilyaev

@antonkovalyov Actually, today I found out that having another .jshintrc file down the directories tree will make JSHint ignore the root file. So all my settings didn't work when I edited files in the public folder.

So to point my issue again, I want to disallow "use strict"; globally on client side files (but force strict": true), and allow them globally on Node.js files.

But I wouldn't want to have 2 separate .jshintrc files, as all files are JavaScript, and that would be the only difference.

Any other suggestions?

@michaelmior

Seems like the ideal behaviour would be to allow .jshintrc in subfolders to override settings, but keep whatever is defined upstream. Of course this would be a breaking change, so their could be some option to enable inheritance if that's a concern, but that should probably be a separate issue.

@christianbundy

What's the status of this? I'm unable to use JSHint with @Meteor until this is fixed – what do I need to do to get a patch accepted?

@valueof
JSHint member

@christianbundy Write a patch first and then we can discuss it.

@englercj

Nearly two years since this was opened, is this actually implemented?

@englercj englercj referenced this issue in pixijs/pixi.js Feb 4, 2015
Closed

'use strict'; #1412

@adriengibrat

It's not yet implemented, a patch was refused because it was mixed with other unrelated stuffs.

Please, it would be nice to implement what @valueof had in mind: strict multivalue option

@nicolo-ribaudo nicolo-ribaudo added a commit to nicolo-ribaudo/jshint that referenced this issue Jun 16, 2015
@nicolo-ribaudo nicolo-ribaudo [[FEAT]] Option to assume strict mode
Why?
1) Some JavaScript compilers (e.g. Babel) add the "use strict" directive, so
   it isn't needed that it is present in the code.
2) In node.js you can use the --use_strict flag, which runs the code using
   strict mode.

The `strict` option has now five possible values:
- true / func - there must be a `"use strict";` directive at function level
- global      - there must be a `"use strict";` directive at global level
- implied     - JSHint checks the code as if there is the `"use strict";`
  directive
- false       - disable warnings about strict mode

The `globalstrict` option is now deprecated, it should be used `strict: global`

Close #924
631d845
@lukeapage lukeapage added a commit that closed this issue Jun 27, 2015
@nicolo-ribaudo nicolo-ribaudo [[FEAT]] Option to assume strict mode
Why?
1) Some JavaScript compilers (e.g. Babel) add the "use strict" directive, so
   it isn't needed that it is present in the code.
2) In node.js you can use the --use_strict flag, which runs the code using
   strict mode.

The `strict` option has now five possible values:
- true / func - there must be a `"use strict";` directive at function level
- global      - there must be a `"use strict";` directive at global level
- implied     - JSHint checks the code as if there is the `"use strict";`
  directive
- false       - disable warnings about strict mode

The `globalstrict` option is now deprecated, it should be used `strict: global`

Close #924
8de8247
@lukeapage lukeapage closed this in 8de8247 Jun 27, 2015
@jugglinmike jugglinmike added a commit to jugglinmike/jshint that referenced this issue Jun 28, 2015
@nicolo-ribaudo nicolo-ribaudo [[FEAT]] Option to assume strict mode
Why?
1) Some JavaScript compilers (e.g. Babel) add the "use strict" directive, so
   it isn't needed that it is present in the code.
2) In node.js you can use the --use_strict flag, which runs the code using
   strict mode.

The `strict` option has now five possible values:
- true / func - there must be a `"use strict";` directive at function level
- global      - there must be a `"use strict";` directive at global level
- implied     - JSHint checks the code as if there is the `"use strict";`
  directive
- false       - disable warnings about strict mode

The `globalstrict` option is now deprecated, it should be used `strict: global`

Close #924
7f9d3b5
@englercj

Any word on when we will have a release with this in it? I've been waiting for it for a while, and it looks like it landed in master.

@lukeapage
JSHint member

@jugglinmike can tell you, I think one is due soon.

@mucaho mucaho referenced this issue in craftyjs/Crafty Aug 18, 2015
Open

Enforce specific style guide #951

@mik01aj

This gets very annoying with Babel, as it puts 'use strict'; in front of everything and explicit 'use strict' declarations are not necesssary anymore.

And the fix actually landed on master on Jun 27, 2015. @lukeapage, could we have a new 2.8.1 (or 2.9.0 release? The latest 2.8.0 is from May.

@lukeapage
JSHint member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment