在windows中观察到这种现象,其中字符串". y"是由path.join("..","y")
自然产生的
然而,它也可以在Linux中被观察到运行这段代码作为测试:
import ts from 'typescript'
const compopts = {};
const out = ts.transpileModule('import x from "..\y"n console.log(x);n',{});
console.log(out); // ... var __y_1 = require("..y"); The "\" has been elided
Typescript是由微软作为开放软件开发的,他们在Windows上开发Typescript,所以我猜他们在Windows上运行时广泛支持Windows样式的路径。因此,当我在windows上测试我的Linux开发的程序时,我非常惊讶地发现这似乎与windows路径不兼容。
这是预期的吗?是bug吗?
编辑:正如Kevin在评论中建议的那样,我将使用/
代替\
由于我一直在使用nodejspath
函数,如join
,我将通过替换
path.<whatever>
path.posix.<whatever>
对于通过ts.transpileModule
的相对路径有效。
幸运的是,我没有处理绝对路径,例如,C:\y
,因为path.posix
不处理字母驱动器。
如何处理字母驱动器(当通过ts.transpileModule
时)是一个有待回答的问题。
你没有使用足够的反斜杠。
正如一些评论已经指出的那样,使用正斜杠更容易,也更易于移植。但是你可以在你的windows脚本中使用反斜杠,如果你使用两倍的反斜杠的话。__
这是让几乎每个Windows开发人员时不时地猝不及防的事情。因为在大多数编程语言中,反斜杠在字符串中有特殊的含义,Windows路径是出了名的难以处理,而且许多语言都有显式的字符串文字形式来禁用反斜杠的特殊行为,只是为了减少这个问题。例如,c#有"逐字";字符串,用"标记;符号,例如:
var hostsFile = @"C:WindowsSystem32driversetchosts";
同时,Python有"raw"字符串,标记为前导r
:
hosts_file = r"C:WindowsSystem32driversetchosts"
在JavaScript中,有String.raw
:
const hostsFile = String.raw`C:WindowsSystem32driversetchosts`;
让我们回过头来看看你的代码。
const out = ts.transpileModule('import x from "..\y"n console.log(x);n',{});
不叫ts.transpileModule
,叫console.log
。
console.log('import x from "..\y"n console.log(x);n');
我们从中得到的输出可能看起来有点像你想要的:
import x from "..y"
console.log(x);
也许现在你看到问题了。因为反斜杠是一个特殊字符,所以实际上不是这样写导入的。你可能通常会用两个反斜杠来写。
import x from "..\y";
console.log(x);
因为路径在字符串字面值内,所以必须通过将其加倍来转义反斜杠。但是现在你已经将字符串文字嵌入到另一个字符串文字中,所以你需要再次使用双反斜杠。
console.log('import x from "..\\y"n console.log(x);n');
这实际上会给你你想要的:
import x from "..\y"
console.log(x);
但是使用String.raw
:
console.log(String.raw`import x from "..\y"n console.log(x);n`);
import x from "..\y"n console.log(x);n
哦!现在我们真正想要的转义码没有被处理!
如果你问我,那实际上是更好,因为n
比实际的换行符更难读。因此,使用String.raw
,您希望以一种更容易阅读的方式编写嵌入代码:
console.log(String.raw`
import x from "..\y";
console.log(x);
`.trim());
import x from "..\y";
console.log(x);
或者如果你想让它看起来很漂亮:
console.log(String.raw`
import x from "..\y";
console.log(x);
`.trim().replace(/^ /gm, ''));
话虽如此,你还是最好在导入中使用正斜杠,这是为了实现跨平台兼容性(这样也更容易输入)。但即便如此,使用String.raw
处理长、多行字符串字面值,也使它们更容易阅读和维护。另外,它将允许你使用插值,这是你可能想要的东西,如果你做这样的事情。