In recent months, JSHint has been receiving requests to support proposed
decorators, and class
. The JSHint team has turned down each request, even after the
release of ES2015. This has
not been easy; as open source project maintainers, nothing gives us more
pleasure than to write code in benefit of our users. We've tried to explain our
motivations in an ad-hoc way, but it's always come off as a bit haphazard. We'd
like to take some time to more thoroughly describe our thought process.
The long and short of it is: JSHint will require all language extension proposals to be at "Stage 2" of TC-39's standardization process before parsing and linting them.
First off, it's difficult for the project maintainers. This is not really a defensible motivation; we only offer it in the interest of full disclosure. Over the years, JSHint has grown from JSLint thanks to the efforts of hundreds of contributors. This has been key to its success, but it has also contributed to a fair amount of technical debt. Extending the parser requires a fair amount of study, and even then, it isn't always clear how to do this cleanly.
The project has tried to be progressive about new syntax in the past
, and this has often contributed to technical debt. For instance,
JSHint continues to
moz option for Mozilla-specific
and the current
esnext option includes non-standard array comprehensions. (By
the way: now that ES2015 is released, that name describes a non-existent
A plugin system is one possible way to address this, but that will require a large effort involving careful design, spanning refactoring, and a long-term commitment to implementation details.
More importantly, it's hazardous for developers. Inconsistencies within toolchains will gate developers on the lowest common denominator. Imagine the day that your transpiler supports draft 17 but JSHint has moved to draft 18. Even if you're not struggling with coordination issues between parsers, the release cycle for a "progressive" parser would leave most application developers behind. Projects would frequently rely on outdated release channels that no longer received bug fixes or new features.
JSHint was born out of a reluctance to make decisions on behalf of the user, so while we think the above considerations should be made clear to JSHint's users, we haven't made this decision based on them.
Finally, it's unhealthy for the language. TC39 does not operate from an
ivory tower. They recognize practical considerations of patterns in existing
code. Look no further than Annex
for proof of that. Sometimes, that is a good thing. The Promises/A+
spec offered a clear way forward when Promises
were first considered for inclusion in ES2015. Sometimes, this is a bad thing.
It's the reason why we expect
The proliferation of production code can have a solidifying
on new features. To the extent that JSHint is a channel through which new
Stage 2 seems specifically designed for our position in the ecosystem.
It's not too early. Features in this stage have a formal definition (so we have a consistent and complete set of instructions to build from). These features are also relatively stable, so JSHint has a chance to keep up with the latest draft modifications.
It's also not too late. The design process can still benefit from the experience of developers applying a given pattern to their code. The process document defines "incremental" changes expected for Stage 2 proposals, and only recommends "experimental" implementations. You might say, "these features seem stable enough", but the truth is, JSHint was dealing with non-trivial modifications to ES2015 from the moment we implemented them until as late as May of this year . So it's worth noting that JSHint is still taking some risk here.
We think there's tremendous value in experimentation at earlier stages in the process. We also feel that research should be conducted in non-production settings in order to avoid the more fundamental problems discussed above. Early-stage experiments have less to gain from automated code analysis both because of their limited scope and because their syntax is already verified by a "transpiler". In these contexts, linting has much more limited relevance.
Here's the practical effect of all that talk:
esnextoption; it will instead support
mozoption, and it will be the only setting that enables array comprehension parsing.
esversion: 7option until that specification is finalized by ECMA.
experimentalconfiguration namespace. These features will be clearly documented as subject to breaking changes between major releases.
This policy means denying first-class support for non-standard and early
proposal features. JSHint will continue to support
ignore directives as a
coarse-grained mechanism for operating on non-standard and early-proposal
features, but we know other linting tools go much farther than
that. We're motivated by our
responsibility to developers but also to the open source ecosystem and to the
standards process itself. We hope JSHint's usership continues to enjoy the tool
because they share these same values.
esnext) error: `import * as foo from 'bar'