问题现象
更新别人代码之后,项目无法启动了
问题原因就是项目打包工具的js执行文件因为Windows样式行结尾跟mac的不同造成报错的。
根本原因解析
说一下“换行”与“回车”两个概念来历与区别
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
研发人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
后来,计算机发明了,这两个概念也就被般到了计算机上。当时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
在文本字符存储中,Unix系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<换行><回车>”,即“\n\r”;Mac早期系统里,每行结尾是“<回车>”,即“\r”;在 Mac OS X 系统发布后投奔 Unix,在现代的 macOS 系统中,换行符是 “\n”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
在实际显示过程中,在Unix/Linux系统中,行尾只使用换行符 \n,系统会自动加上\r实现 回车+换行 的操作,在早期Mac 系统(Mac OS 9 以及之前)中,行尾只使用回车符 \r,系统会自动加上 \n实现 回车+换行 的操作;Windows不需要处理
注意:显示过程中添加的\r和 \n并不在文本字符里的,这个是由操作系统实现的。
在macOS9之后macOS 和 Linux 使用的换行符是相同的\n,因此,在大多数情况下,文本文件在 Linux 和 macOS 之间是兼容的
而 Windows 使用的换行符是 \r\n。
Windows下写的脚本解释器声明语句就是 #!/usr/bin/env node\r\n ,在windows下的程序会认为这是一行,一次性去掉了\r\n,而linux和mac下则认为#!/usr/bin/env node\r是一行程序,只去掉了\n。根本没有node\r这个文件,也就报错了。
这二者的区别也是两个换行符的标准,Windows是CRLF,linux/unix是LF,mac早期是CR,后面也是LF,CRLF:\r\n,LF:\n,CR:\r。
由于换行符的不同,不同系统之间传递文件产生的问题
1,文本显示问题,windows 下的文件在linux 下会产生 ^M 符号,而 linux 下创建编辑的文件 在windows 下会显示成一行; 2,window 下写的shell脚本不能再linux下执行了(shell 解释器对用换行符作为一个命令的提交) 3,影响版本控制软件呢的检入检出,(git对于工作空间和版本库中换行符有转换控制)产生一些无用的文件差异(git diff),尤其在多人协作中,每个人设置的换行符模式不同。)
不同系统换行符的转化工具
windows -> unix :dos2unix
unix ->windows:unix2dos (UltraEdit 和 EditPlus 等软件也能识别和转换)
单文件: vim 打开文件,:set ff=unix,然后保存。vim 打开文件,:set ff=doc,然后保存
开发中如何规避这种问题
-
使用EditorConfig将不同系统不同编辑器文本格式统一
JetBrains的编辑器都默认支持EditorConfig,vscode需要安装一下插件
项目根目录添加.editorconfig文件,添加如下内容,具体字段解析官方文档有详细说明
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
- git bash 中设置默认检入检出换行符为linux(\n)风格
git config --global core.autocrlf true # 开启自动换行
# 其他相关配置(根据需要选择)
git config --global core.autocrlf true # 签出时将换行符转换成CRLF,签入时转换回 LF
git config --global core.autocrlf input # 签出时不转换换行符,签入时转换回 LF
git config --global core.autocrlf false # #签出签入均不转换
git config --global core.safecrlf true # 开启安全换行,拒绝提交包含混合换行符的文件
# 如果一个文件中既包含windows风格的换行符也包含unix风格换行符,那么 safecrlf 就可以发挥作用了
# 其他相关配置(根据需要选择)
git config --global core.safecrlf false # 允许提交包含混合换行符的文件
git config --global core.safecrlf warn # 提交包含混合换行符的文件时候给出警示