程序员

nodeJS 基础

2018-05-16  本文已影响33人  那就远走

Node.js

简单理解

安装

# 显示版本
node -v

nodejs模块

// 定义一个方法
var counter = function(arr) {
    return "这里有" + arr.length + "个元素在数组里";
}

// 定义一个方法
var adder = function (a, b) {
    return `两数和为 ${a+b}`;
}

// 定义一个变量
var pi = 3.14;

// 暴露模块 module.exports.模块名 = 要暴露的东西
// module.exports.counter = counter;
// module.exports.adder = adder;
// module.exports.pi = pi;
// 简写
module.exports = {
    // 键 : 值
    counter : counter,
    adder : adder,
    pi : pi
}
// var 定义一个变量 = require('模块存放的路径');
var modules = require('./node模块');
// require引用的是一个module.exports暴露出来的对象,所以也可以直接引用它下面的某一个属性。
var pi = require('./node模块').pi;

// modules 是一个对象,调用方法就用 (对象.属性)即可
console.log(modules.counter(['1', '2', '3']));
console.log(modules.adder(1, 2));
console.log(modules.pi);

事件

// 引用事件模块
var events = require('events');

// 新建一个事件对象
var myEmitter = new events.EventEmitter();

// 绑定事件 .on('事件名', 事件触发回调函数(){//...});
myEmitter.on('someEvent', function(message1, message2) {
    console.log(message1 + message2);
});

// 手动触发事件 .emit('事件名', 参数列表);
myEmitter.emit('someEvent', '触发1', '触发2');
// 引用事件模块
var events = require('events');
// 引用工具库模块 util
var util = require('util');

// 定义一个Person类
var Person = function(name) {
    // 创建类时给属性name一个值
    this.name = name;
}

// 工具库.继承(让Person类, 继承events模块下的EventEmitter类)
util.inherits(Person, events.EventEmitter);

// 创建三个对象
var xiaoming = new Person('xiaoming');
var lili = new Person('lili');
var lucy = new Person('lucy');

// 将三个对象放进一个数组
var people = [xiaoming, lili, lucy];

// 循环数据
people.forEach(function(person) {
    // 给每个对象绑定一个事件
    person.on('speak', function(message) {
        // 事件名speak, 事件执行控制台日志记录 对象.名字属性说参数message
        console.log(person.name + "说" + message);
    });
});

// 触发事件
xiaoming.emit('speak', 'hi1');
lili.emit('speak', 'hi2');
lucy.emit('speak', 'hi3');

同步文件IO操作

// 引入文件系统模块
var fs = require('fs');

// 读取文件 fsreadFileSynt("文件", "编码");
var content = fs.readFileSync("readMe.txt", "utf-8");
    // console.log(content);

// 写文件
fs.writeFileSync("writeMe.txt", content);
    // console.log("文件writeMe.txt创建成功,内容写入成功");
// writeFileSync会覆盖原内容
fs.writeFileSync("writeMe.txt", "Hello World");

异步读写文件

// 1:引用文件模块
var fs = require('fs');

// 2:异步读文件, fs.readFile("文件", "编码", 回调函数(发生错误, 文件内容) {//...});
var content = fs.readFile("readMe.txt", "utf-8", function(error, data) {
    // 异步写文件
    fs.writeFile("writeMe.txt", data, function() {
        console.log("写入完毕");
    });
});

// 3:控制台打印提示
console.log("读取完毕");

/**
 * 为什么“读取”完毕会先出现?
 * 3段代码依旧是按顺序执行的,
 * 但是执行2的时候,只是执行:node自动在“事件队列”里注册一个事件(如果文件过大,采用同不方法就会阻塞其他操作)
 * 然后直接执行3
 * 然后再回头去,执行“事件队列”里的事件:读取文件
 */

目录操作

// 引用文件系统模块
var fs = require('fs');

fs.unlink("writeMe.txt", function() {
    console.log("删除成功");
});

// 同步就是后面加Sync,参数不加回调函数因为没啥需要回调的程序顺着跑
// fs.unlinkSync("writeMe.txt");

/* 实现一个小功能 */
// 创建目录stuff
fs.mkdir('stuff', function() {
    // 读取文件readMe.txt
    fs.readFile('readMe.txt', 'utf-8', function(error, data) {
        // 将文件内容写到 ./stuff/writeMe.txt中
        fs.writeFile('./stuff/writeMe.txt', data, function(){
            console.log('文件写入成功');
        });
    });
});

流和管道

// 模块
var fs = require('fs');

// 创建读取流
var myReadStream = fs.createReadStream(__dirname + '/readMe.txt', 'utf-8');
// 创建写入流(文件名)
var myWriteStream = fs.createWriteStream(__dirname + '/writeMe.txt');

// 读取流.pipe(写入流) : 读取文件流内容,写入写入文件流
myReadStream.pipe(myWriteStream);

web服务

web服务具体实现

// http模块
var http = require('http');

// 创建服务器(回调函数2个参数(请求, 响应){//...})
var server = http.createServer(function(request, response) {
    // 这里的控制台日志输出是在服务器端的
    console.log("接收请求");
    // 写响应头 writeHead(状态码, {内容})
    response.writeHead(200, {
        'Content-Type': 'text/plain',
    });
    // 写响应体 write
    // response.write('Hello World!');
    // 关闭文件流(结束一次http请求和响应)
    // response.end();
    // 可以直接写 end(响应体);
    response.end('Hello World!');
});

// listen(端口, ip)
server.listen(3000, '127.0.0.1');
console.log("服务器启动了!");

JSON

// http模块
var http = require('http');

// 创建请求
var server = http.createServer(function(request, response) {
    console.log("接收请求");
    response.writeHead(200, {
        // json的内容-类型为 application/json
        'Content-Type': 'application/json'
    });
    // 定义一个json对象
    var myJson = {
        'name': 'liuhaoyu',
        'job': 'programmer',
        'age': 22
    }
    // 解析一下json对象为字符串 JSON.stringify(json对象)
    // 把字符串形式的json变回对象 JSON.parse(json字符串)
    response.end(JSON.stringify(myJson));
});

server.listen(3000, '127.0.0.1');
console.log("服务器启动了!");

响应html

// http模块
var http = require('http');
// 优化:响应请求时将html文件以文件流的形式发送给浏览器
var fs = require('fs');

// 来个html文本
// var htmlText = 
// '<!DOCTYPE html>' +
// '<html lang="en">' +
// '<head>' +
//     '<meta charset="UTF-8">' +
//     '<meta name="viewport" content="width=device-width, initial-scale=1.0">' +
//     '<meta http-equiv="X-UA-Compatible" content="ie=edge">' +
//     '<title>响应html5代码</title>' +
// '</head>' +
// '<body>' +
//     '<h1>响应成功</h1>' +
//     '<p>恭喜你,成功解锁nodeJS.http.server技能</p>' +
// '</body>' +
// '</html>' ;

// 优化:读取文件流存储在变量中
var htmlText = fs.createReadStream(__dirname + '/html.html', 'utf-8');

var server = http.createServer(function(request, response) {
    console.log("接收请求");
    response.writeHead(200, {
        // html : text/html
        'Content-Type': 'text/html'
    });
    // response.end(htmlText);
    // 优化:管道传递给响应
    htmlText.pipe(response);
});

server.listen(3000, '127.0.0.1');
console.log("服务器启动了!");

模块化

// 引用系统模块...
// 编写自己的模块...

// 暴露
module.exports.startServer = startServer;
// 引用模块
var module = require('./module');
// 跑
module.startServer();

实现简单的路由

// http模块
var http = require('http');
// 文件操作模块
var fs = require('fs');

function startServer() {
    var htmlText;
    var server = http.createServer(function(request, response) {
        // 先确定所有路由都响应html文件  
        response.writeHead(200, {
            // html : text/html
            'Content-Type': 'text/html'
        });
        // 获取请求路由 request.url
        // console.log(request.url);
        // 根据请求路由不同,获得不同的html文件
        switch (request.url) {
            case '/':
            case '/home':
                htmlText = fs.createReadStream(__dirname + '/home.html', 'utf-8');
                break;
            case '/user':
                htmlText = fs.createReadStream(__dirname + '/user.html', 'utf-8');
                break;
            default:
                htmlText = fs.createReadStream(__dirname + '/404.html', 'utf-8');
                break;
        }
        htmlText.pipe(response);
    });

    // 启动服务
    server.listen(3000, '127.0.0.1');
    console.log("服务器启动了!");

}

// 可以直接exports暴露模块
exports.startServer = startServer;
// 引用模块
var module = require('./module');
// 跑
module.startServer();

获取get / post

// http模块
var http = require('http');
// 文件操作模块
var fs = require('fs');
// url操作模块
var url = require('url');

function startServer() {
    var htmlText;
    var server = http.createServer(function(request, response) {
        response.writeHead(200, {
            'Content-Type': 'text/html'
        });
        // 获取地址
        var pathname = url.parse(request.url).pathname;
        // 获取GET方式传递的参数 url true返回对象 false返回字符串
        var params = url.parse(request.url, true).query;
        // 获取POST方式传递的参数
        var data = "";
        // 错误时
        request.on(error, function() {
            console.log(error);
        // 接收时
        }).on('data', function(chunk) {
            data += chunk;
        // 接收完成后 
        }).on('end', function() {
            console.log(data);
        });

        switch (pathname) {
            case '/':
            case '/home':
                htmlText = fs.createReadStream(__dirname + '/home.html', 'utf-8');
                break;
            case '/user':
                htmlText = fs.createReadStream(__dirname + '/user.html', 'utf-8');
                break;
            default:
                htmlText = fs.createReadStream(__dirname + '/404.html', 'utf-8');
                break;
        }
        htmlText.pipe(response);
    });

    // 启动服务
    server.listen(3000, '127.0.0.1');
    console.log("服务器启动了!");

}

// 可以直接exports暴露模块
exports.startServer = startServer;
// 引用一下queryString模块
var queryString = require('querystring');

// ...

// 根据method方式获取参数
        var data = "";
        // 错误时
        request.on(error, function() {
            console.log(error);
        // 接收时
        }).on('data', function(chunk) {
            data += chunk;
        // 接收完成后 
        }).on('end', function() {
            // 判断method
            if(request.method == 'POST') {
                // post 就用queryString模块.parse() 把数据变成对象
                data = queryString.parse(data);
            }else {
                // get 就用url.parse() 把数据变成对象
                data = url.parse(request.url, true).query;
            }
            console.log(data);
        });

npm是个啥?

安装

npm -v
#npm 安装 自己安装自己@最新版 -g全局
npm install npm@latest -g
npm -install 包名
# 国内镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 更新cnpm
cnpm install cnpm@latest -g
cnpm install 包名
cnpm install -g 包名

package.json

# 会问你无数个问题
npm init
# 不想回答?
npm init -y
# 用国内镜像 安装 --包依赖写进package 安装的包叫express一个nodeJS后台框架
cnpm install --save express
# 只要有package.json文件,不用给他node_modules文件夹,直接给执行命令,把package.json记录的所有包全部下载下来
npm install

nodemon

cnpm install -g nodemon
nodemon 入口文件名

补充

# install 简写为 i
cnpm i 包
cnpm install 包 --save
cnpm uninstall 包

这样只是干掉了依赖,并没有干掉node_modules里的包源代码。当你开发完成后,最好在生产环境部署的时候,先把node_modules==移除项目文件夹并备份==,确定package.json的依赖关系正确(只要你不乱编辑它,装包卸包都用命令),然后在生产环境服务器上用 npm install 把包下好是最好的方法

cnpm update 包
cnpm istall 包@版本 --save

npm配置

# 你初始化一个项目,相当于初始化一个npm包
npm init
# 开始答题
package name: 包名
version: 版本
description: 描述
git repository: git仓库地址
author:作者
license: ISC许可证
最后给你一个初始化的package.json文件内容,问你客官这样行不行,回车yes
初始化了一个package.json

package.json 里的 ==scripts==

...

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1" ,
    "yo": "echo \" yo!\" "
},
  
...
npm run yo

webpack是啥

安装

# 全局安装
npm install webpack -g
# 有个小坑
#The CLI moved into a separate package: webpack-cli
#Would you like to install webpack-cli? (That will run npm install -D webpack-cli) (yes/NO)n
#It needs to be installed alongside webpack to use the CLI
#上面就是提示你 CLI这个东西 webpack自身没带 你需要装一个 才能使用webpack (webpack4更新的坑)
npm install --save-dev webpack-cli -g

打包

module.exports = {
    // 入口文件,其他被暴露的模块不用管,webpack打包时会读require代码,它自动取找
    entry: './index.js',
    // 出口文件(打包后生成的文件)
    output: {
        // 文件名
        filename: 'pack.js',
        // 路径
        path: __dirname
    }
}
cmd > webpack

多个入口文件

module.exports = {
    // 多个入口文件写成对象的形式
    entry: {
        // key入口名称: value入口文件具体路径
        home : './js/home.js',
        user : './js/user.js',
    },
    output: {
        // 这里的[name]对应entry里的入口名称
        filename: '[name].bundle.js',
        // /dist 是惯例用法,一般npm打包的文件都放这里
        path: __dirname + '/dist',
    }
}
# 就会在当前目录/dist/下打包home.bundle.js & user.bundle.js
webpack

loader

#不想答题
npm init -y
#--save-dev 可以简写为 -D
npm install webpack -D
#cli 等会跑的时候会提示你安装
// ...
"scripts": {
    // 这是默认的
    "test": "echo \"Error: no test specified\" && exit 1",
    // 这是我们添加的一条 想要执行? npm run dopack, --watch是一条不挂断的命令,当任何源码发生改变时,都会根据package.config.js的配置重新打包
    "dopack": "node_modules/.bin/webpack --watch"
},
// ...
npm install css-loader style-loader -D
module.exports = {
    entry: './js/index.js',
    output: {
        filename: 'bundle.js',
        path: __dirname + '/dist'
    },
    // 配置module
    module: {
        // 配置rules
        rules: [
            {
                // 正则匹配 .css 后缀文件
                test: /\.css$/,
                // 使用两个loader , 注意: 顺序从右往左
                use: ['style-loader', 'css-loader'],
            }
        ]
    }
}
<style type="text/css">body {
    background: #ccc;
}</style>
上一篇下一篇

猜你喜欢

热点阅读