75team / tc39

360 Ecma-TC39 工作组
89 stars 4 forks source link

【反馈收集】Hashbang 提案的问题 #2

Open hax opened 5 years ago

hax commented 5 years ago

报告见 https://github.com/75team/tc39/blob/master/issues/201907-hashbang-stage3.md

由于本提案已经达到 stage 3,已经有两个浏览器(chrome 和 ff)实现,我们需要尽快给出反馈。

请求反馈内容包括:

  1. 你是否赞同报告中对 hashbang 潜在风险的分析?(如果你甚至已经有生产环境的实例,请加以描述。)
  2. 如果赞同的话,你认为这个风险有多高?
  3. 你倾向于哪种解决方案?(除了报告中的,也可提出你认为可行的其他解决方案。)
  4. 你是否认为应该 block 这个提案?反对程度有多高?
  5. 其他你想讨论的内容。
XGHeaven commented 5 years ago

我的想法是没必要引入 hashbang 语法。

  1. hasbang 是 linux 的行为,主要是作为 cli 的时候,可以不用手动选择解释器,node a.js => ./a.js,这样可以很方便 cli 的使用。而在浏览器或者纯 js 环境,这个东西毫无意义。
  2. 如果只是想让一个 .js 文件既能用 cli 又能当做 module,也就是说想要同时支持 ./a.jsconst a = require('./a.js')。我觉得这个需求本身就是一个伪需求。将其拆分成两个文件,一个 cli 一个 module,会更加合理。
xtx1130 commented 5 years ago

赞同楼上的第一点,不赞同第二点。我可以用require.main === module来做出是否为node直接访问的判断,为何还要拆分出两个文件。

hax commented 5 years ago

@xtx1130 我想 @XGHeaven 的意思可能是说在所有环境支持 hashbang 的动机可以通过拆分出可共用的部分来解决。

反过来说,单文件中判断当前是什么环境(是否是node)有很多方法,但是只要是单文件,就面临支持 hashbang 的问题,因为 hashbang 在现在的 js 标准中是语法错误,只不过 node.js 做了扩展才支持,但是在其他环境中是不行的。因此不拆分成两个文件(其中一个单纯用作 node.js 的入口文件),是不能同时满足两个需求(第一,可以在linux下直接执行之;第二,可以在多个环境中使用)的目标的。

XGHeaven commented 5 years ago

@xtx1130 是可以通过这样来判断,但是为什么要让一个文件同时兼具两种完全不相干的能力呢?首先不符合单一职责原则(虽然这个原则是用于类设计上的,但是也是可以拿来借鉴的)。 而且业界真的这样做的很少,你可以看下各大 cli 包,基本都是 cli 和 module 分成两个文件。

@hax 如果一定要加的话,那就干脆把 # 也当做一个注释符号不就可以了么?之所以 hashbang 能在 linux 工作,一个很大的原因我是觉得 # 本身就是一个注释符号。换句话说,如果 bash 的注释是 // 那么 hashbang 没准就变成了 //! 了呢。我觉得还是要透过现象看本质吧,我更加支持把 # 当做新的注释符号,而不是特化处理 hashbang 这个语法。

xtx1130 commented 5 years ago

@XGHeaven 现在大部分CLI的架构基本都是类似@oclif/command ,单独开一个run方法然后在./bin目录下运行。但是在做Single-command CLI的时候,个人观点觉得还是require.main === module用的顺手,毕竟造自行车和造汽车没必要用相同的架构。

XGHeaven commented 5 years ago

@xtx1130 首先你这个需求是没问题的,我本地写个单文件 cli,也能被别人引用当做 module。这个在本地是完全没问题的,但是这个功能有必要移植到浏览器端或者其他环境么?

所以我觉得这个提案是为了在多环境跑而不用考虑 hashbang 导致的问题。而且现在的提案你也听贺老讲了,局限性很大。感觉这个提案只考虑了本地 server 端的情况,而浏览器却基本没怎么考虑。

简单来说我们需要 hashbang 这个功能,但是这个功能是由 js 语言层面来做还是说 node 单独处理。这是个值得商榷的地方。 所以我才会说让 .js 又当 cli 又当 module 其实这个是不合理的,这样做无法跨环境的,比如浏览器环境就没有 cli 需要的 fs 模块,而本地又没有浏览器环境的 dom。cli 是一个很依赖环境的东西,而 module 相比就弱很多。

回到最开始,你说的这个情况现在本地 node 已经是支持的呀,但是你这个做法是跨环境的么?比如你会为了方便而在一个文件里面写既能本地当 cli 又能在浏览器环境里面当 module 的代码么?

退一万步将,如果真的需要,webpack 把 hashbang 的头去掉就好了 // 手动完美

xtx1130 commented 5 years ago

@XGHeaven 哦哦,那你和Hax说的情况是一致的。

你可以看下各大 cli 包,基本都是 cli 和 module 分成两个文件。

我刚才认为你说的情况是只针对node的。

hax commented 5 years ago

如果一定要加的话,那就干脆把 # 也当做一个注释符号不就可以了么?

@XGHeaven JS几乎把所有符号都已经用尽,所以为了将来语言还能扩展,每个符号都很『珍贵』。目前单符号只剩下『#』和『@』,并已经被用在了新的提案里(class fields 和 decorators)。所以是不可能把『#』用作注释了。

比较可行的是将『#!』组合视作注释。

XGHeaven commented 5 years ago

@hax 贺老你不说我差点忘记了。确实不能把 # 当做注释符号。但是 #! 这个当注释符号也是真的很奇怪 :joy:

hax commented 5 years ago

@XGHeaven 目前提案的语义相当于只在#!位于文件首/脚本首时才作为注释,可能更『奇怪』一点。其实在JS中除了常见的///* ... */注释之外,<!----> 也有注释作用(行为有一定的差异),目的是为了兼容早期以html注释包裹脚本块的惯例。

zhangenming commented 4 years ago

@XGHeaven JS几乎把所有符号都已经用尽,所以为了将来语言还能扩展,每个符号都很『珍贵』。目前单符号只剩下『#』和『@』,并已经被用在了新的提案里(class fields 和 decorators)。

那岂不是已经用完了

hax commented 4 years ago

@zhangenming 是已经用完了,只不过在某些场景上还能一鸭多吃而已。比如#现在同时被用在 class fields、smart pipeline、records and tuples 和这里提到的 hashbang 这四个提案里。