使用前需要引入fs模块(var 必威:fs= require(,n

二、蹩脚JS下的Node.js初体验

绝大数厂子都是小厂,很大部分小厂都只有一个前端,很多前端的JS其实都一般般。

圈子里面经常把“前端解决方案”挂在嘴边的,实际上都是有前端团队的,因为有团队, 才能显价值。

“前端解决方案”是好,但是,如果真正关心行业发展,应该知道,能够在一个大团队里面玩耍的实际上是小部分人,有很多很多的小伙伴都是孤军奋战,这套东西说不定反而阻碍了敏捷和灵活;有很多很多的小伙伴在二三四线城市,是野生的前端开发,底子不够,这套庞杂的东西很难驾驭;有很多很多的项目就是几个静态活动页面,没必要回回使用高射炮打蚊子。

此时,往往需要的是定制化很强的小而美的处理。有同学可能会疑虑,哎呀,我JS水平比较菜,自造工具这种事情会不会有点挑大梁啊。实际上,即使你JS一般般,借助Node.js构建一些小工具提升自己的前端开发效率这种事情,完全不在话下。

前端这东西,有个博尔特都认同的特点,就是上手快!

首先,我们需要一份Node.js API文档,我们使用“动物搜索”,搜一下:
必威 1

就第一个吧,进入会看到一长排的API列表内容: 必威 2

不要怕,我们只需要这一个就可以,没错,就一个文件系统(fs)!必威 3 其他都不需要管,那些都是资深玩家玩的:
必威 4

点击去,又是洋洋洒洒,一群API:必威 5
必威 6

不要怕,我们只需要……淡定,不是一个,是若干个常规的增删读写重命名文件就可以了。必威 7

好了,然后只需要一点蹩脚的JS,我们就可以玩起来了。

玩什么呢?容我看集动漫想一想……

设计师给的图标重命名
勤劳的设计师送来了香饽饽的小图片素材,但是,连接字符是下划线_,恰巧,此时,前端童鞋的处女病发错,其他自己处理的图片全部是短横线-连接的,这里图标全是下划线受不了,想要全部替换为短横线,怎么办?

必威 8

如果就一两个图标还好,大不了手动改改,但是,要是如上截图,设计师一口气给了57个图标,我去,要改到头皮发麻了吧~倒不是时间问题,而是重复劳动带来的那种枯燥和不愉悦会影响工作的激情,而且这种劳动用完就没了,无法复用,且不能作为业绩(我可以5分钟完成100个文件的重命名,有个卵用~)。

此时,Node.js就可以闪亮登场了,有了Node.js环境,我们只要寥寥几行JS代码,就可以完全秒杀了,很简单,读取文件夹里面的所有图片,然后把名称里面所有的下划线_替换成短横线-, 假设我们的.js文件和需要处理的小图标文件夹结构如下:
必威 9

underscore2dash.js内容如下:

// 引入fs文件处理模块 var fs = require("fs"); // 现在我们要关心的是'icons'文件夹 // 我们不妨用变量表示这个文件夹名称,方便日后维护和管理 var src = 'icons'; // API文档中中找到遍历文件夹的API // 找到了,是fs.readdir(path, callback) // 文档中有叙述: // 读取 path 路径所在目录的内容。 回调函数 (callback) 接受两个参数 (err, files) 其中 files 是一个存储目录中所包含的文件名称的数组 // 因此: fs.readdir(src, function(err, files) { // files是名称数组,因此 // 可以使用forEach遍历哈, 此处为ES5 JS一点知识 // 如果不清楚,也可以使用for循环哈 files.forEach(function(filename) { // 下面就是文件名称重命名 // API文档中找到重命名的API,如下 // fs.rename(oldPath, newPath, callback) // 下面,我们就可以依葫芦画瓢,确定新旧文件名称: var oldPath = src + '/' + filename, newPath = src + '/' + filename.replace(/_/g, '-'); // 重命名走起 fs.rename(oldPath, newPath, function(err) { if (!err) { console.log(filename + '下划线替换成功!'); } }) }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 引入fs文件处理模块
var fs = require("fs");
// 现在我们要关心的是'icons'文件夹
// 我们不妨用变量表示这个文件夹名称,方便日后维护和管理
var src = 'icons';
 
// API文档中中找到遍历文件夹的API
// 找到了,是fs.readdir(path, callback)
// 文档中有叙述:
// 读取 path 路径所在目录的内容。 回调函数 (callback) 接受两个参数 (err, files) 其中 files 是一个存储目录中所包含的文件名称的数组
// 因此:
fs.readdir(src, function(err, files) {
    // files是名称数组,因此
    // 可以使用forEach遍历哈, 此处为ES5 JS一点知识
    // 如果不清楚,也可以使用for循环哈
    files.forEach(function(filename) {
        // 下面就是文件名称重命名
        // API文档中找到重命名的API,如下
        // fs.rename(oldPath, newPath, callback)      
        // 下面,我们就可以依葫芦画瓢,确定新旧文件名称:
        var oldPath = src + '/' + filename, newPath = src + '/' + filename.replace(/_/g, '-');
        // 重命名走起
        fs.rename(oldPath, newPath, function(err) {
            if (!err) {
                console.log(filename + '下划线替换成功!');
            }      
        })
    });
});

window系统举例,我们使用cmd或者PowerShell,在对应文件夹目录下执行下该JS文件:

node underscore2dash

1
node underscore2dash

结果:
必威 10

此时的文件夹的图片们:
必威 11

此处的文件名批量替换不仅适用于图片,实际上适用于任意格式的文件。

当前,对命名的批量处理不仅仅如此,还包括统一前缀(例如icon_*),此时只要把newPath =后满的代码改成src + '/icon_' + filename。或者非开发需求,比方说批量下载的小视频名称从1依次往后排,则……还是自己处理下吧,forEach方法第二个参数是数组序号值,可以直接拿来用,就当课后作业了,看好你哟!

本文件夹批量处理例子,抛开详尽的注释,差不多10行出头JS代码,用到的JS方法也都是非常非常基本的,对吧,数组遍历forEach和字符替换replace方法,其他就是套API走套路,就算我老婆(非IT领域)亲自上阵,也都可以弄出来。简单,而且有意思。

我强烈建议大学的程序开发入门课程就学JavaScript,跑web网页,跑Node.js, 简单且所见即所得,容易激发学习的乐趣,要比枯燥不知干嘛用的C语言更适合科普和入门。

2:js文件:update-name.js

复制代码 代码如下:fs.rename = function(oldPath, newPath, callback) { callback = makeCallback; if (!nullCheck return; if (!nullCheck return; binding.rename(pathModule._makeLong, pathModule._makeLong;};

node.js中的fs.writeFile方法使用说明,node.jsfs

方法说明:

以异步的方式将data写入文件,文件已存在的情况下,原内容将被替换。

语法:

复制代码 代码如下:

fs.writeFile(filename, data, [options], [callback(err)])

由于该方法属于fs模块,使用前需要引入fs模块(var fs= require(“fs”) )

接收参数:

filename      (String)            文件名称

data        (String | Buffer)    将要写入的内容,可以使字符串 或 buffer数据。

options        (Object)           option数组对象,包含:

· encoding   (string)            可选值,默认 ‘utf8′,当data使buffer时,该值应该为 ignored。

· mode         (Number)        文件读写权限,默认值 438

· flag            (String)            默认值 ‘w'

callback {Function}  回调,传递一个异常参数err。

例子:

复制代码 代码如下:

fs.writeFile('message.txt', 'Hello Node', function (err) {
  if (err) throw err;
  console.log('It's saved!');
});

源码:

复制代码 代码如下:

fs.writeFile = function(path, data, options, callback) {
  var callback = maybeCallback(arguments[arguments.length - 1]);
  if (util.isFunction(options) || !options) {
    options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' };
  } else if (util.isString(options)) {
    options = { encoding: options, mode: 438, flag: 'w' };
  } else if (!util.isObject(options)) {
    throw new TypeError('Bad arguments');
  }
  assertEncoding(options.encoding);
  var flag = options.flag || 'w';
  fs.open(path, options.flag || 'w', options.mode, function(openErr, fd) {
    if (openErr) {
      if (callback) callback(openErr);
    } else {
      var buffer = util.isBuffer(data) ? data : new Buffer('' + data,
          options.encoding || 'utf8');
      var position = /a/.test(flag) ? null : 0;
      writeAll(fd, buffer, 0, buffer.length, position, callback);
    }
  });
};

方法说明: 以异步的方式将data写入文件,文件已存在的情况下,原内容将被替换。 语法: 复制...

安装过程就不说了。如果成功是能使用node的命令。node.js调试是非常方便的。每种后台语言都有一个向那个黑黢黢的控制台团输出语用的命令。node.js沿用FF那套东西,也就是console对象与其方法。我们首先建一个example.js文件,内容如下,然后在控制台打开它。 复制代码 代码如下: console.log for{ console.log } node example.js。 你千万不要在node.js使用alert进行调试,那是浏览器带的全局方法,不报错才怪。 输出结果如下: 复制代码 代码如下: var log = function () { process.stdout.write(format.apply + 'n'); } var info = function () { process.stdout.write(format.apply + 'n'); } var warn = function () { writeError(format.apply + 'n'); } var error = function () { writeError(format.apply + 'n'); } var dir = function { var util = require; process.stdout.write + 'n'); } var time = function { times[label] = Date.now(); } var timeEnd = function { var duration = Date.now() - times[label]; exports.log('undefined: NaNms', label, duration); } var trace = function { // TODO probably can to do this better with V8's debug object once that is // exposed. var err = new Error; err.name = 'Trace'; err.message = label || ''; Error.captureStackTrace(err, arguments.callee); console.error; } var assert = function { if { var arr = Array.prototype.slice.call; require.ok(false, format.apply; } } 通过这些函数,我们大概了解到node.js在全局作用域添加了些什么,如require, process。但也不能武断说是,因为它们可能是某个作用域的私有对象。不过,了解这些全局对象,并从这些对象上出发去了解其他对象,非常有助于我们了解node.js的生态结构。在前端,每当浏览器升级,我就遍历一下window对象以及其个元素节点就得知它又增加了什么方法与属性,然后再查文档。那些更新日志不可能把全部细节都告诉你的,必须自己动手遍历一下,这样你就比别人知道得更多。好了,我们去找node.js的全局对象。 node.js的文档告诉我们,有如下几个全局对象: global, process, require,__filename,__dirname, module 但我们为什么能直接使用console.log呢?经验告诉我们,console肯定是某全局对象的成员,正如我们可以alert, 也可以window.alert。好了,我们选遍历一下global这个名字取得非常霸气的对象 复制代码 代码如下: for{ console.log("var " + i+" = "+global[i]) } 结果如下: 复制代码 代码如下: var global = [object global] var process = [object EventEmitter] var GLOBAL = [object global] var root = [object global] var Buffer = function Buffer(subject, encoding, offset) { //太长了,省略 } var setTimeout = function () { var t = NativeModule.require; return t.setTimeout.apply; } var setInterval = function () { var t = NativeModule.require; return t.setInterval.apply; } var clearTimeout = function () { var t = NativeModule.require; return t.clearTimeout.apply; } var clearInterval = function () { var t = NativeModule.require; return t.clearInterval.apply; } var console = [object Object] 发现global与浏览器的window一样,都有个指向自身的同名成员。window === window.window, global === global.global。但node.js早期设计得不好,又一搞了个多余的GLOBAL成员。 console.log(global === global.global)//true console.log(global === global.GLOBAL)//true 我们再遍历module对象: 复制代码 代码如下: for{ console.log("var " + i

一、非计算机背景前端如何快速了解Node.js?

做前端的应该都听过Node.js,偏开发背景的童鞋应该都玩过。

对于一些没有计算机背景的,工作内容以静态页面呈现为主的前端,可能并未把玩过Node.js,且很有可能对Node.js都没有一个比较立体的认识——知道这玩意可以跑服务,构建很多前端工具,看上去很厉害的样子,但是,可能就仅限于此了。

“那可否三言两语概括Node.js的林林总总呢?”
“不可!”
“那怎么办?”
“那就六言四语!”

首先,要知道,Node.js一个JavaScript运行环境(runtime),没错,就是用来运行Javascript. 以前JavaScript只能在浏览器这个小世界里称王称霸。很多前端小伙伴可能就JS这门程序语言熟一点,其他C++, .net之类的就呵呵了。如果是过去,如果浏览器一觉醒来灭绝了,很多人就会失业。就像食物单一的物种一旦这种食物没了,就坐等灭绝是一个道理。

但是,现在,不要担心了,Node.js让JavaScript变成杂食的了,也就是除了网页行为,可以和其他C++等语言一样,构建服务,操作文件等等。

我们应该都使用过.exe后缀的文件,双击一下,就可以潜伏个病毒什么的;我们可能还使用过.bat后缀的批处理文件,一点击,文件夹里面的图片全部重命名;那么如果是.js后缀的文件呢(假设你的系统已经安装了Node.js环境),双击一下则……当当当当……会打开编辑器看到JS代码,双击是没有用的!

必威 12

我们可以打开命令行工具,cd到指定目录,然后输入(假设JS文件名为test.js):

node test

1
node test

然后test.js里面的代码就可以欢快地跑起来啦!

对于“页面仔”而言,了解这么多就够了!

  1. 安装后Node.js环境;
  2. 用我们蹩脚的JS写一个蹩脚处理的.js文件;
  3. node执行下。

简简单单三部曲,我们就变身成了具有开发味道的前端从业人员了。必威 13

// API文档中中找到遍历文件夹的API
// 找到了,是fs.readdir(path, callback)
// 文档中有叙述:
// 读取 path 路径所在目录的内容。 回调函数 (callback) 接受两个参数 (err, files) 其中 files 是一个存储目录中所包含的文件名称的数组
// 因此:
fs.readdir(src, function(err, files) {
// files是名称数组,因此
// 可以使用forEach遍历哈, 此处为ES5 JS一点知识
// 如果不清楚,也可以使用for循环哈
files.forEach(function(filename) {
// 下面就是文件名称重命名
// API文档中找到重命名的API,如下
// fs.rename(oldPath, newPath, callback)
// 下面,我们就可以依葫芦画瓢,确定新旧文件名称:
var oldPath = src + '/' + filename,
// newPath = src + '/' + filename.replace(/_/g, '-');
newPath = src + '/' + filename + "-20";

方法说明:

  • " = "+module[i]) } 结果如下: 复制代码 代码如下: var id = . var exports = [object Object] var parent = null var filename = /home/cheng19840218/node/example.js var loaded = false var exited = false var children = var paths = /home/cheng19840218/node/node_modules,/home/cheng19840218/node_modules,/home/node_modules,/node_modules var load = function { //太长了,省略 } var _compile = function { //太长了,省略 } 原来那个着名的exports是在此提供的,__filename大概也是filename的引用。只要遍历一下,你就发现许多有趣的东西。但别以为一下秘密就暴光在你眼皮下,还有许多不可遍历属性。比如上面我遍历global对象,只有尞尞可数几个成员,我们可以使用ecma262v5新增的方法去考察一下: console.log(Object.getOwnPropertyNames 结果如下: 复制代码 代码如下: [ 'clearInterval', 'TypeError', 'decodeURI', 'Buffer', 'parseFloat', 'Number', 'URIError', 'encodeURIComponent', 'RangeError', 'ReferenceError', 'RegExp', 'Array', 'isNaN', 'setTimeout', 'console', 'Date', 'Infinity', 'Boolean', 'Error', 'root', 'NaN', 'String', 'Function', 'Math', 'undefined', 'encodeURI', 'escape', 'unescape', 'process', 'decodeURIComponent', 'EvalError', 'clearTimeout', 'GLOBAL', 'setInterval', 'SyntaxError', 'Object', 'eval', 'global', 'parseInt', 'JSON', 'isFinite' ] 许多人学node.js就立即看其文档,殊不知node.js本身所依赖的V8引擎就拥有许多要学的东西,这其中包括ecma262v5带来的新方法新对象,还有效仿firefox的一些语法: __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__ set get __proto__ 不过以"__"开头的东西我是不建议用的,像set与get现在最新的浏览器都支持,如IE9,可以在其开发人员工具下试试下面的脚本: 复制代码 代码如下: var a = { get latest () { if { return this.log[this.log.length - 1]; } else { return null; } }, log: [] } a.log[0] = "a"; a.log[1] = "b"; console.log 在node.js基本上没有兼容问题,而且原生对象又加了这么多扩展,再加上node.js自带的库,每个模块都提供了花样繁多的API,如果还嫌不够,github上还有上千个插件。对于想向尝试一下后端编程的JSer来说,这是极具诱惑力的。可能有人说,后端不是涉及数据库操作吗?这与比前端的DOM兼容比起来,不值一提。还有什么文件夹与文件操作 ,你就当成是一种特殊的数组操作就是。因此你完全可以愤愤不平! 好了,我们来点实质的内容吧。node.js本来就是一个http服务器,它是要与前端交互的,因此少不了两个对象:请求。请求与响应显然一种异步的东西,因为我们 不知道前端什么时候发请求过来,响应也不能立即给前端,还要做日志,读写数据库等操作呢。因此对于javascript来说,这用回调函数来实现最好。那么由谁来接受这个回调呢?一个服务器对象! 复制代码 代码如下: var http = require; http.createServer(function { response.writeHead(200, {"Content-Type": "text/plain"}); response.write; response.end; node.js有个特殊的require,用于同步加载其他模块的对象,这与其他语言的require, import差不多。能同步就是好,不像前端那样一层套一层。然后利用一个函数去实例化一个服务器对象,然后监听8888端口。这是node.js官网最初的例子,大家都写烂了。但这样的程序在现实中一无是处,我们在地址栏上输入URL,你起码要返回一个完整页面给我吧! 对此,我们首先要进行模块化。模块化是以文件为单位的,把example.js更名为server.js,然后再把里面的内容改为一个模块。对于一个node.js的文件,其实它里面的内容是在一个封闭的环境中执行。要想共享给其他模块使用,就必须绑定在exports对象上。 复制代码 代码如下: var http = require; exports.start = function(){ http.createServer(function { console.log("Request received..."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write; response.end; console.log; } 然后我们再建一个index.js作为入口(index.js与server.js放在同一目录下)。 复制代码 代码如下: var server = require; server.start(); 然后建一个index.html页面。 复制代码 代码如下:

四、结束语

当项目比较小的时候,当团队成员比较少的时候,当开发同学不鸟你的时候,此时,要发扬自己动手,丰衣足食的精神。

开发时候遇到痛点,或者感觉自己在做重复劳动的时候,想想看,是不是可以花点时间捣腾出一个Node.js的小脚本。

不要以为npm仓库里面的那些工具好像很Diao很难搞,其实呢,也就是一点点核心加上应付各种场景弄出来的。由于我们是自娱自乐,追求的是敏捷高效,专注于眼前任务功能,所以,我们只要把核心弄出来就好,而这些核心往往就几行JS代码+几个fs API就可以了。

蚂蚁虽小,咬人也疼。所以,不要觉得自己JS比较菜,搞不来,就几行JS代码,你不动手搞一搞你怎么就确定呢?

写CSS为主的前端想要往后发展,没有比本文介绍内容更适合学习和入门的了。

Try it!

2 赞 7 收藏 3 评论

必威 14

1:文件夹:icons

源码:

这是首页

现在我们就在要请求过来时,把此页的内容读出来,返给用户。这时我们就要用到fs模块的方法了。 复制代码 代码如下: var http = require; var fs = require; exports.start = function(){ http.createServer(function { fs.readFile('./index.html', 'utf-8',function {//读取内容 if throw err; response.writeHead(200, {"Content-Type": "text/html"});//注意这里 response.write; }); }).listen; console.log; } 好了,这时我们重启再次输入地址,就看到一个完整的页面了。 但一个页面除了HTML结构层外,还有javascript与css。那么,我们在当前目录建一个文件夹javascripts, 里面建index.js,内容如下: 复制代码 代码如下: window.onload = function(){ var p = document.createElement; p.innerHTML = "这是动态添加的" document.body.appendChild; } 再建一个styles目录,里面建index.css,内容如下: 复制代码 代码如下: html,body{ background: #3671A5; height: 100% } 然后在index.html引入这两个文件: 复制代码 代码如下:

index

本文由必威发布于必威-前端,转载请注明出处:使用前需要引入fs模块(var 必威:fs= require(,n

相关阅读