node.js+gulp入门必备

3,529 阅读9分钟

写在前面

这两周了解了node相关知识,今天复盘了这几天的知识。该文章大概有以下内容。

  • node.js介绍使用
  • node的模块化开发
  • 用第三方模块gulp的使用
  • 模块引入后查找规则

本文章适合初学者阅读,接下来就一起来看看吧。

什么是node

node是一个基于Chrome v8引擎的js代码运行环境。 js运行环境有两种,浏览器和node,去node官网安装node环境,配置好环境变量。

js由ECMAScript,dom,bom组成,node.js 也是ECMAScript和一些附加的API组成,api可以理解成实现某个功能的函数。

node的组成

在node环境下执行代码

使用node命令在终端执行后缀为.js的文件。比如node a.js即可。

node.js中的全局对象gloubal。浏览器中全局对象是window, node中console.log===global.console.log(),通常global可以省略。 node全局对象中有以下六个方法可以在任何地方使用。

  • console.log()
  • setTimeout()
  • clearTimeout()
  • setInterval()
  • clearInterval

node.js模块化开发

-js使用存在两大问题,文件依赖和命名冲突。

软件中模块化开发就是为了避免依赖和命名冲突,让一个功能就是一个模块,多个模块可以组成完整的应用,抽离一个模块不会影响其他功能的运行。

在node.js中一个js文件就是一个模块,模块内部定义的变量和函数默认情况下变量和函数默认情况下外部无法得到。

  • 模块内部使用exports对象进行导出。
  • 使用require进行导入。

导入模块要注意的地方

//在exports.js文件中
const greeting = name => `hello ${name}`;
const x = 100;
exports.x = x;
module.exports.greeting = greeting;
//在require.js文件中
const a = require('exports.js');
console.log(a);
// console.log(a.greeting('zhangsan'));

同时导出x和greeting方法是成立的,执行node require.js文件的时候终端输出的导出对象{x:100,greeting:[Function: greetig]}。

说明:exports.x=x和module.exports.x=x是等价的,他们指向的都是同一个地址。

但是当两者导出的不是同一个对象的时候以module.expots为准,上面两个都是global对象。我们将上面的代码进行改进

//在exports.js文件中
const greeting = name => `hello ${name}`;
const x = 100;
exports.x = x;
module.exports.greeting = greeting;
// 当exports对象和moudle.exports对象指向的不是同一个对象时 以module.exports为准
module.exports = {
	name: 'zhangsan'
}

module.exports = {
	age: 20
}
exports = {
	age:30
}
//在require.js文件中
const a = require('./04.module.exports.js');
// console.log(a.greeting('zhangsan'));
console.log(a);
console.log(a.name);

观察上面代码,先打印导出对象,再打印该对象下面的name属性。

exports和module.exports指向不同的对象以后面module.exports 为准,同时出现多个module.exports对象以后面的为准,所以终端执行后的结果是{age:20} undefined,结果如下图所示。

node中的系统模块

node环境提供的api就是系统模块,这些api都是以模块化进行开发的。这里将两个模块,文件模块和路径模块。

1.文件模块fs

  • 文件写入
// 1.通过模块的名字fs对模块进行引用
const fs = require('fs');

// 2.通过模块内部的readFile读取文件内容
fs.readFile('./01.helloworld.js', 'utf8', (err, doc) => {
	// 如果文件读取出错err 是一个对象 包含错误信息
	// 如果文件读取正确 err是 null
	// doc 是文件读取的结果
	console.log(err);
	console.log(doc);
});
  • 文件写出
const fs = require('fs');

fs.writeFile('./demo.txt', '即将要写入的内容', err => {
	if (err != null) {
		console.log(err);
		return;
	}

	console.log('文件内容写入成功');
})

2.路径拼接模块path

const fs = require('fs');
const path = require('path');

console.log(__dirname);
console.log(path.join(__dirname, '01.helloworld.js'))

fs.readFile(path.join(__dirname, '01.helloworld.js'), 'utf8', (err, doc) => {
	console.log(err)
	console.log(doc)
});

执行后的终端中,第一行是当前为文件的绝对路径,第二行是路径拼接后的结果,第三行null说明读取文件没有发生错误,第四行是打印文件的结果。

node中第三方模块

第三方模块是别人写好的实现特定功能的模块,我们能够拿来直接用的,通常放在文件夹中。在了解第三方模块之前,要知道npm(node package manager):node的第三方模块(包)管理工具。

第三方模块形式

  • 以js文件的形式存在,提供实现项目具体功能的API接口。一般本地下载
  • 以命令行工具形式存在,辅助项目开发。一般全局下载

第三方模块的使用

  • npm install 模块名 // ---安装模块
  • npm uninstall 模块名 // ----删除模块

nodemon模块

  • nodemon是一个命令行工具,用以辅助项目开发。

  • 在Node.js中,每次修改文件都要在命令行工具中重新执行该文件,非常繁琐。 nodemon命令执行js文件,修改文件后不用重新执行文件也可以在终端看到改变的结果。

  • 使用步骤

    • 1.使用npm install nodemon –g 下载它

    • 2.在命令行工具中用nodemon命令替代node命令执行文件

nrm模块

  • npm是国外的模块,用起来比较慢可以使用nrm命令转换成国内的命令
  • nrm ( npm registry manager ):npm下载地址切换工具
  • 使用方式
    • 使用npm install nrm –g 下载它
    • 查询可用下载地址列表 nrm ls
    • 切换npm下载地址 nrm use 下载地址名称,比如nrm use cnpm.

gulp模块

将机械化操作编写成任务,想要执行机械化操作时候执行一个命令任务就可以自动执行,让机器代替手动,提高开发效率。

  • gulp作用
    • 项目上线,HTML、CSS、JS文件压缩合并
    • 语法转换(es6、less转css ...)
    • 公共文件抽离
    • 修改文件浏览器自动刷新
  • gulp使用
    • 使用npm install gulp下载gulp库文件

    • 在项目根目录下建立gulpfile.js文件,文件名是gulp规定不能更改。

    • 重构项目的文件夹结构 src目录放置源代码文件 dist目录放置构建后文件

    • 在gulpfile.js文件中编写任务.

    • 在命令行工具中执行gulp任务

  • gulp中的方法
    • gulp.task()创建gulp任务
    • gulp.src()获取文件
    • gulp.dest()输出处理后的文件
    • gulp.watch()监控文件的变化
案例1
gulp.task('first',(done) => {
    console.log("我的第一个gulp任务执行了");
    gulp.src('./src/css/bass.css')
        .pipe(gulp.dest(dist/CSS));
        done();
});

我们通过gulp来看看如何使用,pipe是处理的方法,对于gulp中的处理要写在里面,上面代码中我们输出gulp.src方法获取到的文件到dist目录下的css目录。 现在我们到终端执行gulp任务,这时候node只能执行js文件无法执行某个gulp任务,不能使用node命令。所以要 下载gup-cli命令行工具。我们使用npm install gulp-cli -g进行全局安装。

在命令行中输入gulp first后,会自动去当前目录下找gulpfile.js文件,然后执行first任务

最后的结果是,在dis目录下生成css目录,在css下看到导入的base.css文件 库文件本地安装,命令行工具本地安装

案例2

用gulp插件创建任务。插件有很多,下面列举一部分。

1.gulp-htmlmin :html文件压缩

2.gulp-csso :压缩css

3.gulp-babel :JavaScript语法转化

4.gulp-less: less语法转化

5.gulp-uglify :压缩混淆JavaScript

6.gulp-file-include 公共文件包含

7.browsersync 浏览器实时同步

// 引用gulp模块
const gulp = require('gulp');
//压缩html模块
const htmlmin = require('gulp-htmlmin');
//提取公共样式
const fileinclude = require('gulp-file-include');
const less = require('gulp-less');
const csso = require('gulp-csso');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
// 使用gulp.task建立任务
// 1.任务的名称
// 2.任务的回调函数
gulp.task('first', () => {
	console.log('我们人生中的第一个gulp任务执行了');
	// 1.使用gulp.src获取要处理的文件
	gulp.src('./src/css/base.css')
	//pipe是处理的意思,dest是输出文件,将处理大的文件输出到dist目录下
		.pipe(gulp.dest('dist/css'));
});

// html任务
// 2.html文件中代码的压缩操作
// 1.抽取html文件中的公共代码
gulp.task('htmlmin', () => {
	gulp.src('./src/*.html')
		.pipe(fileinclude())
		// 压缩html文件中的代码,压缩的时候是否压缩空格
		.pipe(htmlmin({ collapseWhitespace: true }))
		.pipe(gulp.dest('dist'));
});

// css任务
// 1.less语法转换
// 2.css代码压缩
gulp.task('cssmin', () => {
	// 选择css目录下的所有less文件以及css文件,用数组接收所有的less文件和css文件
	gulp.src(['./src/css/*.less', './src/css/*.css'])
		// 将less语法转换为css语法
		.pipe(less())
		// 将css代码进行压缩
		.pipe(csso())
		// 将处理的结果进行输出
		.pipe(gulp.dest('dist/css'))
});

// js任务
// 1.es6代码转换
// 2.代码压缩
gulp.task('jsmin', () => {
	gulp.src('./src/js/*.js')
		.pipe(babel({
			// 它可以判断当前代码的运行环境 将代码转换为当前运行环境所支持的代码
            presets: ['@babel/env']
        }))
        .pipe(uglify())
        .pipe(gulp.dest('dist/js'))
});

// 复制文件夹
gulp.task('copy', () => {

	gulp.src('./src/images/*')
		.pipe(gulp.dest('dist/images'));

	gulp.src('./src/lib/*')
		.pipe(gulp.dest('dist/lib'))
});

// 构建任务
//执行defalut任务后就可以依次执行数组中的任务,不用一个个执行
//gulp default==gulp,它会自动去找default这个任务去执行
gulp.task('default', ['htmlmin', 'cssmin', 'jsmin', 'copy']);

模块加载规则

在代码中引入了各种模块,如果当前环境中有同路径同名和同后缀的模块,那么就引入这个文件。但是如果不一样呢,这里分两种情况来看

  • 模块没有后缀,比如require('./find'),引入当前路径下的find文件,由于文件没有后缀,会按以下顺序去执行。
    • 先看当前目录有没有同名的find.js文件,有就执行
    • 如果没有看有没有find文件夹,如果有且find文件夹中有index.js文件,就引入index.js文件
    • 如果没有,就找package.json的main中有没有入口文件且写的文件是否真实存在,有就导入
    • 以上都没有就会报错。
  • 模块没有路径也没有后缀,只有名字。比如require('find')
    • Node.js会假设它是系统模块,看系统模块有没有这个模块
    • 没有的话Node.js会去node_modules文件夹中 ,看是否有同名js文件
    • 如果没有再看node_modules中是否有该名字的文件夹
    • 如果有这个文件夹,看里面是否有index.js
    • 如果没有index.js,查看该文件夹中的package.json中的main选项确定模块入口文件是否存在
    • 如果找不到报错

package.json文件

文件的作用

项目描述文件,记录了当前项目信息,例如项目名称、版本、作者、github地址、当前项目依赖了哪些第三方模块等。 使用npm init -y命令生成。

依赖的分类

  • 项目依赖:在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖 使用npm install 包名命令下载的文件会默认被添加到 package.json 文件的 dependencies 字段中
  • 开发依赖:在项目的开发阶段需要依赖,线上运营阶段不需要依赖的第三方包,称为开发依赖 使用npm install 包名 --save-dev命令将包添加到package.json文件的devDependencies字段中。
  • 分类的好处:npm install 会下载所有的依赖、npm install --production线上运行依赖,只会下载dependencies中的依赖。

package-lock.json文件的作用

当我们下载第三方模块的时候,npm同时会产生该文件。这个文件记录了不同模块之间的依赖关系,模块版本模块的下载地址。

  • 锁定包的版本,确保再次下载时不会因为包版本不同而产生问题,防止下载最新版与别人不同导致项目运行失败
  • 加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装时只需下载即可,不需要做额外的工作

写在最后

最后我想说最近疫情很严重,大家就响应国家号召,待在家里学习吧。 春招也来了,好好准备,希望看到该文章的你offer拿到手软,已经工作的伙伴升职加薪哈哈哈。 emmm...

The most important thing is to be safe and peaceful. 希望疫情早日结束,中国加油,湖北加油。

ending...