We discussed hashbang proposal in our last WebFrontEnd TC meeting, and we have a concern about current "only allow hashbang in the start of script/module" behavior.
(For those who can read chinese, the original document is here: https://github.com/75team/tc39/blob/master/issues/201907-hashbang-stage3.md )
Risk
There are many preprocessors, server-side include, code transformers, 3rd party services, etc. in real world which will prepend/append something to javascript source code, including but not limited to:
- Adding copyrights and license at start
- Providing server information for debugging by prepending comments
- Function wrapping (eg. convert CommonJS to AMD/UMD)
- Simple concat of source files
- Not intentionally, but for a variety of reasons adding the newline character accidently
After the conversion, #! will not be at start anymore and cause SyntaxError.
The risk here is that the original authors of the scripts or the developer using the scripts may not foresee that the script will be converted, even if they are aware of this possibility in theory, they often forget this in practice and cannot pay attention to it in time. And if someone add hashbang to a script, It is highly unlikely that this change will be considered as a breaking change and release a major version solely for a hashbang addition. In many cases, the local test env will not include the conversion steps. So it's hard for the users to notice the change and its consequences, the worst result is the SyntaxError caused by the conversion will cause failure in production.
On the other hand, conversion facilities and components are likely to be deployed and maintained by independent infrastructure teams or operations teams, and it is almost impossible to expect all of these teams to be aware of the risks posed by hashbang. Even if they are aware of this risk, they may not be able to respond in time due to various reasons, or simply attribute this to the edge case, or consider this to be the responsibility of the developers. In the best case, if the infrastructure team or the operation teams wants to actively avoid this problem, all the conversion facilities and components involved must be specially treated for hashbang, which may be unrealistic or the implementation cost may exceed expectation.
In the short term, this risk is not significant and we may not get reports because conversions of scripts are typically used for scripts in web pages, and all current usage of #! are limited to CLI entry scripts. But in the long run, there may be some scripts which apply to both the CLI and the browser environment, which may suffer from the introduction of hashbang. On the other hand, since the frequency of actual consequences due to this risk may be low (ie, considered as an edge case), it may cause the problem to be ignored intentionally and unintentionally. Considering the scale of the entire ecosystem and industry, the cost of this risk in the future may be greater than we think.
(There is also a concern of developer experience similar to #12 (comment) )
Similar precedents
@charset "xxx" in CSS should be put at start of stylesheet. But this case have a big difference to hashbang.
Normally, @charset "xxx" not at start will only invalidate the charset declaration, it does not necessarily cause the entire CSS parsing failure. Because UTF-16 encoding can't rely on @charset, only ASCII-compatible encodings (UTF-8, ISO-8859-x, Shift-JIS, GBK, etc.) can be valid for @charset, incorrect decoding of ASCII-compatible encodings only results in local mistakes (normally only cause bad property values, it's very rare selectors could contains non-ascii chars).
Another similar case is the DOCTYPE declaration. In the old IE browsers, if there is anything before the DOCTYPE, including comments and XML declarations, the quirk mode will be triggered (ie the DOCTYPE declaration is invalid). However, in this case, it also does not cause the parsing failure, and the new browsers does not have this problem at all.
Rationale
From a historical perspective, prepending/appending comments, line breaks, whitespace to HTML/CSS/JS never cause a fatal parsing failure. Furthermore, prepending comments, line breaks, whitespace never change the parsing results and semantics of a JS script. Many of the previously mentioned examples of conversions potentially rely on this. So we believe, in some degree, this should be considered as a requirement for web compatibility too.
Possible solutions
In our meetings and further investigations in our community , a big voice is hashbang should not be put into ECMAScript spec and this proposal should be withdraw. Many think hashbang should be deal with by CLI (just keep current status) so that the programmers will be taught that it's only the feature of CLI and hashbang should only be used in entry files of CLI (normally only files under node_modules/package/bin or node_modules/package/cli directory in a package) and no one will expect normal JS files could have hashbang.
If this proposal was still stage 2, we may advocate to withdraw this proposal. But we TC39 delegates of 360 understand this proposal already achieve stage 3 and browsers already land it, and Node.js already remove their old implementation and move to V8 implementation via language layer, so we will not advocate withdraw it in current status.
After some discussion, we suggest treat #! as comments. More specifically, we think it could use the similar grammar as --> (SingleLineHTMLCloseComment).
HTMLComment was introduced to JS for compatible to very old pattern of
<script><!--
alert('hello world!')
//--></script>
The interesting fact is we not only allow <!-- in the start of scripts (like current #!), but treat <!-- behave like // and also treat --> behave like // if --> in the start of line (ignore all leading comments/whitespace). We feel the situation of #! is very like -->.
We hope the champions of this proposal could consider our feedback carefully and bring it to further meetings if necessary, thank you!
We discussed hashbang proposal in our last WebFrontEnd TC meeting, and we have a concern about current "only allow hashbang in the start of script/module" behavior.
(For those who can read chinese, the original document is here: https://github.com/75team/tc39/blob/master/issues/201907-hashbang-stage3.md )
Risk
There are many preprocessors, server-side include, code transformers, 3rd party services, etc. in real world which will prepend/append something to javascript source code, including but not limited to:
After the conversion,
#!will not be at start anymore and cause SyntaxError.The risk here is that the original authors of the scripts or the developer using the scripts may not foresee that the script will be converted, even if they are aware of this possibility in theory, they often forget this in practice and cannot pay attention to it in time. And if someone add hashbang to a script, It is highly unlikely that this change will be considered as a breaking change and release a major version solely for a hashbang addition. In many cases, the local test env will not include the conversion steps. So it's hard for the users to notice the change and its consequences, the worst result is the SyntaxError caused by the conversion will cause failure in production.
On the other hand, conversion facilities and components are likely to be deployed and maintained by independent infrastructure teams or operations teams, and it is almost impossible to expect all of these teams to be aware of the risks posed by hashbang. Even if they are aware of this risk, they may not be able to respond in time due to various reasons, or simply attribute this to the edge case, or consider this to be the responsibility of the developers. In the best case, if the infrastructure team or the operation teams wants to actively avoid this problem, all the conversion facilities and components involved must be specially treated for hashbang, which may be unrealistic or the implementation cost may exceed expectation.
In the short term, this risk is not significant and we may not get reports because conversions of scripts are typically used for scripts in web pages, and all current usage of
#!are limited to CLI entry scripts. But in the long run, there may be some scripts which apply to both the CLI and the browser environment, which may suffer from the introduction of hashbang. On the other hand, since the frequency of actual consequences due to this risk may be low (ie, considered as an edge case), it may cause the problem to be ignored intentionally and unintentionally. Considering the scale of the entire ecosystem and industry, the cost of this risk in the future may be greater than we think.(There is also a concern of developer experience similar to #12 (comment) )
Similar precedents
@charset "xxx"in CSS should be put at start of stylesheet. But this case have a big difference to hashbang.Normally,
@charset "xxx"not at start will only invalidate the charset declaration, it does not necessarily cause the entire CSS parsing failure. Because UTF-16 encoding can't rely on@charset, only ASCII-compatible encodings (UTF-8, ISO-8859-x, Shift-JIS, GBK, etc.) can be valid for@charset, incorrect decoding of ASCII-compatible encodings only results in local mistakes (normally only cause bad property values, it's very rare selectors could contains non-ascii chars).Another similar case is the DOCTYPE declaration. In the old IE browsers, if there is anything before the DOCTYPE, including comments and XML declarations, the quirk mode will be triggered (ie the DOCTYPE declaration is invalid). However, in this case, it also does not cause the parsing failure, and the new browsers does not have this problem at all.
Rationale
From a historical perspective, prepending/appending comments, line breaks, whitespace to HTML/CSS/JS never cause a fatal parsing failure. Furthermore, prepending comments, line breaks, whitespace never change the parsing results and semantics of a JS script. Many of the previously mentioned examples of conversions potentially rely on this. So we believe, in some degree, this should be considered as a requirement for web compatibility too.
Possible solutions
In our meetings and further investigations in our community , a big voice is hashbang should not be put into ECMAScript spec and this proposal should be withdraw. Many think hashbang should be deal with by CLI (just keep current status) so that the programmers will be taught that it's only the feature of CLI and hashbang should only be used in entry files of CLI (normally only files under
node_modules/package/binornode_modules/package/clidirectory in a package) and no one will expect normal JS files could have hashbang.If this proposal was still stage 2, we may advocate to withdraw this proposal. But we TC39 delegates of 360 understand this proposal already achieve stage 3 and browsers already land it, and Node.js already remove their old implementation and move to V8 implementation via language layer, so we will not advocate withdraw it in current status.
After some discussion, we suggest treat
#!as comments. More specifically, we think it could use the similar grammar as-->(SingleLineHTMLCloseComment).HTMLComment was introduced to JS for compatible to very old pattern of
The interesting fact is we not only allow
<!--in the start of scripts (like current#!), but treat<!--behave like//and also treat-->behave like//if-->in the start of line (ignore all leading comments/whitespace). We feel the situation of#!is very like-->.We hope the champions of this proposal could consider our feedback carefully and bring it to further meetings if necessary, thank you!