您好,欢迎访问一九零五行业门户网

使用Node.js处理前端代码文件的编码问题_node.js

使用 nodejs 编写前端工具时,操作得最多的是文本文件,因此也就涉及到了文件编码的处理问题。我们常用的文本编码有 utf8 和 gbk 两种,并且 utf8 文件还可能带有 bom。在读取不同编码的文本文件时,需要将文件内容转换为 js 使用的 utf8 编码字符串后才能正常处理。
bom 的移除
bom 用于标记一个文本文件使用 unicode 编码,其本身是一个 unicode 字符(\ufeff),位于文本文件头部。在不同的 unicode 编码下,bom 字符对应的二进制字节如下:
bytes encoding---------------------------- fe ff utf16be ff fe utf16le ef bb bf utf8
因此,我们可以根据文本文件头几个字节等于啥来判断文件是否包含 bom,以及使用哪种 unicode 编码。但是,bom 字符虽然起到了标记文件编码的作用,其本身却不属于文件内容的一部分,如果读取文本文件时不去掉 bom,在某些使用场景下就会有问题。例如我们把几个 js 文件合并成一个文件后,如果文件中间含有 bom 字符,就会导致浏览器 js 语法错误。因此,使用 nodejs 读取文本文件时,一般需要去掉 bom。例如,以下代码实现了识别和去除 utf8 bom 的功能。
function readtext(pathname) { var bin = fs.readfilesync(pathname); if (bin[0] === 0xef && bin[1] === 0xbb && bin[2] === 0xbf) { bin = bin.slice(3); } return bin.tostring('utf-8');}
gbk 转 utf8
nodejs 支持在读取文本文件时,或者在 buffer 转换为字符串时指定文本编码,但遗憾的是,gbk 编码不在nodejs自身支持范围内。因此,一般我们借助 iconv-lite 这个三方包来转换编码。使用 npm 下载该包后,我们可以按下边方式编写一个读取 gbk 文本文件的函数。
var iconv = require('iconv-lite');function readgbktext(pathname) { var bin = fs.readfilesync(pathname); return iconv.decode(bin, 'gbk');}
单字节编码
有时候,我们无法预知需要读取的文件采用哪种编码,因此也就无法指定正确的编码。比如我们要处理的某些 css 文件中,有的用 gbk 编码,有的用 utf8 编码。虽然可以一定程度可以根据文件的字节内容猜测出文本编码,但这里要介绍的是有些局限,但是要简单得多的一种技术。
首先我们知道,如果一个文本文件只包含英文字符,比如 hello world,那无论用 gbk 编码或是 utf8 编码读取这个文件都是没问题的。这是因为在这些编码下,ascii0~128 范围内字符都使用相同的单字节编码。
反过来讲,即使一个文本文件中有中文等字符,如果我们需要处理的字符仅在 ascii0~128 范围内,比如除了注释和字符串以外的js代码,我们就可以统一使用单字节编码来读取文件,不用关心文件的实际编码是 gbk 还是 utf8。以下示例说明了这种方法。
1. gbk编码源文件内容:
var foo = '中文';
2. 对应字节:
76 61 72 20 66 6f 6f 20 3d 20 27 d6 d0 ce c4 27 3b
3. 使用单字节编码读取后得到的内容:
var foo = '{乱码}{乱码}{乱码}{乱码}';
4. 替换内容:
var bar = '{乱码}{乱码}{乱码}{乱码}';
5. 使用单字节编码保存后对应字节:
76 61 72 20 62 61 72 20 3d 20 27 d6 d0 ce c4 27 3b
6. 使用 gbk 编码读取后得到内容:
var bar = '中文';
这里的诀窍在于,不管大于 0xef 的单个字节在单字节编码下被解析成什么乱码字符,使用同样的单字节编码保存这些乱码字符时,背后对应的字节保持不变。
nodejs 中自带了一种 binary 编码可以用来实现这个方法,因此在下例中,我们使用这种编码来演示上例对应的代码该怎么写。
function replace(pathname) { var str = fs.readfilesync(pathname, 'binary'); str = str.replace('foo', 'bar'); fs.writefilesync(pathname, str, 'binary');}
其它类似信息

推荐信息