下载模块,插件一定要注意目录, 是全局的,还是单个项目的;
node是基于谷歌浏览器V8引擎的JS运行时环境;
Node的特点
单线程 JS就是单线程的,指的是在同一时间,只有一个线程在执行任务。
非阻塞I/O ; I/O: 指的是输入; 输出 I: input 往内存中输入内容; O: output 从内存中向外输入内容 ; 在执行IO这种耗时行为的时候,不阻塞线程
事件驱动 当IO行为完成之后,会将后续的代码追加到Node的事件队列中
NodeJS的模块
模块化规范
AMD 前端的异步加载模块规范(依赖前置: 指的是在定义模块时,就将所依赖的模块标明)
CMD 前端的异步加载同步书写模块规范(依赖就近: 指的是在定义模块时,用到哪个模块,才引入哪个模块)
CommonJS 后端的同步加载模块
---------------------------------------------------------------------------------------------------------------------
通过Node运行JS文件
打开cmd命令面板
一定要先切换到js文件所在目录
通过 node xxx.js 尝试运行JS文件
运行结果
成功
失败并报错
NodeJS中的模块分类
内置模块/核心模块
NodeJS能做很多事情,比如搭建服务器,比如操作文件,比如监听网络等
HTTP模块:用于搭建服务器
var http = require("http"); // 引入核心模块HTTP
FS模块:用于操作文件和文件夹
var fs = require("fs"); .
- 提供功能的方式,就是通过模块。不同的模块做不同的事情。
第三方模块
别人写好的模块,自己写的模块都属于第三方模块
NodeJS模块化相关
定义模块
在NodeJS中,一个JS文件默认就是一个模块
暴露接口
exports
只能通过点语法或者方括号语法进行内容的暴露
不可以使用等号暴露内容
module.exports
可以通过module.exports点语法或者方括号语法向外暴露内容
可以通过等号暴露内容
一旦使用module.exports = xxx 之后,exports将会失效
引入内容
require
引入的内容取决于目标模块暴露的内容
参数可以是直接的内部核心模块名称
可以是"./"开头的相对路径
node_modules文件夹
该文件夹就是普通文件夹,但是nodejs赋予了特殊的意义: 只要你的名字是 node_modules 不论是如何创建出来 就是一个node的模块"聚集地"
特殊之处
只要一个第三方模块放在了该文件夹下 就可以不通过./这种相对路径写法 直接写文件名就能找得到 而且不论层级(但一定要在同级或上级)
//导入http内置模块,进行http服务的协议;
var http = require("http");
//创建http服务的方法
//语法: http.createServer(函数),返回值是一个http服务;
//每一次前端发出请求,都会被触发;
//这个函数接受两个参数:request和response;
//request:req,请求头; 本次请求的所有请求消息;
//response:res,响应头;请求返回的东西;
var server = http.createServer(function (req, res) {
//req.url 本次请求的是path
console.log(req.url);
console.log("---------------------------");
// res.end() 响应体,返回给前端的内容;
console.log(res.end("hello world"));
});
//监听某一个端口使用的方法 listen()
//语法 服务.listen(端口号,回调函数),监听端口完毕的时候,cmd终端里运行这段代码,cmd窗口会变成服务器;
server.listen(8080, function () {
console.log("8080端口");
});
node的操作命令
NPM
NPM是一个NodeJS的模块管理器 随着Node安装到我们的系统中。可以在任意的命令行目录下调用它。它可以上传、下载、查询模块等;
下载命令:
npm install moduleName 安装moduleName这个模块到本地
npm i moduleName -g 安装moduleName这个模块到全局
初始化命令:
npm init 生成一个package.json文件 该文件的作用是描述你的模块的相关信息;
安装命令:
npm install 根据package.json文件的依赖模块进行模块的安装
express 这是一个NodeJS的第三方模块 :用于快速搭建服务器
package.json文件, 这是一个用于记录当前项目(模块)信息的文件
npm的简写:
- 下载 install 简写成 i ;
- 卸载 uninstall简写 un;
NRM
SASS
Sass是CSS的预编译语言。 编译之前不是CSS,编译之后是CSS。
sass idnex.scss index.css
sass --watch index.scss:index.css 时时编译
sass --watch 编译的文件夹:生成的文件夹 时时编译
sass语法:
注释 :
- 单行注释 // ,编译的时候会被忽略掉;
- 多行注释 / * */ , 编译会被保留,但打包的时候会被忽略掉;
- / *! */ 强力注释,编译和打包都会保留;
定义变量: 方便统一修改和复用 $名字 : 值 ;
- $color:red;
- div{ color: $color}; 直接使用变量;
- #{ $名字 } 插值表达式 ;
分支语句:
- @if 表达式 { 内容 }
- @if $className == "price" { color : $color ;}
- @if 表达式 { } @else if 表达式 { } @else { }
- @if 表达式 { 内容 } @else { 内容 }
循环语句:
- @for $变量 from 开始数字 to 结束数字 { } ; 包含开始,不包含end ;
- @for $变量 from 开始数字 through 结束数字 { } ; 包含开始和结束;
- @while 表达式 { }
sass嵌套语法:
- 基本嵌套(后代嵌套) ,在一个选择器里面写后代选择器;
- 子代嵌套, > 子代选择器(亲儿子选择器);
- 连接符的选择器嵌套; $表示当前的选择器; p {$:hover{ color:red } } ;
群组选择器嵌套; 通过 ,
属性嵌套; 属性名中带有 - 的; 例如 margin-top:
//画三角形 h2 { width: 0; height: 0; border: 100px solid transparent { bottom-color: green; } } 等价与 h2 { width: 0; height: 0; border: 100px solid transparent; border-bottom-color: green; }
sass混合器语法: [ mix 混合]
实际上定义了一个函数;
语法:
- 定义 : @mixin 混合器名字 { } ;
- 使用: @include 混合器名字;
sass继承语法: [extend 延伸]
- @extend 选择器; 表示继承指定选择器的css样式;
- 一样的内容单独写出来,不一样的单独写,然后继承相同的类;
.extend1 { width: 100px; height: 100px; background-color: pink; } h2 { color: yellow; @extend .extend1; //继承extend1; } 等价与 .extend1, h2 { width: 100px; height: 100px; background-color: pink; } h2 { color: yellow; }
sass 导入语法: [import 导入]
- @import "路径"
- 导入文件,导入混合器文件
Gulp
Gulp是一个工程化工具,编译打包构建工具。它是Node的一个第三方模块。
准备使用gulp
1. 准备一个项目
+ 需求: 你要确定好自己的目录结构
你要分开源码和打包以后的内容
dist 文件夹, 上传服务器的, 打包后的文件,不需要创建, gulp自动创建;
src 文件夹, 存放源码文件, 明确src文件夹下的目录;
+ 确定自己的目录结构
- xiaomi
- src 源码
+ pages 存放html文件
+ css/sass 存放 css/scss文件
+ js 存放 js文件
+ lib 第三方文件(jquery, swiper, ...)
+ images 图片
+ videos 视频
+ audios 音频
+ fonts 字体图标文件
2. 准备一个 gulpfile.js 的文件
+ 必须有 , 直接写在项目根目录, 和 src 同级**
+ gulp 进行打包的依据
+ 每一个项目需要一个 gulpfile.js
+ 我们再这个文件里面进行本项目的打包配置
+ gulp 再运行的时候, 会自动读取 gulpfile.js 文件里面的配置
+ 按照你再 gulpfile.js 文件里面的配置进行打包工作
3. 再项目里面再次安装 gulp
+ 注意: **项目里面的 gulp 是以第三方模块的形式出现的**
+ 专门给你提供配置打包流程的 API 的
+ 每一个项目都要安装一次
+ 打开命令行, 切换到项目目录
=> 输入指令 $ npm install gulp -D / npm i gulp -D
4. 再 gulpfile.js 里面书写配置文件
+ 书写你该项目的打包流程
+ 书写完毕以后, 按照打包流程去执行 gulp 指令运行 gulpfile.js 文件
package.json 记录的第三方依赖
通过package.json下载开发过程中用到的全部模块; npm i
npm init 创建 package.json文件,注意切换目录里 ;
+ dependencies
=> 表示的你项目的 项目依赖
=> 比如 jquery, swiper
=> 指项目运行需要用到的内容, 将来上线以后也需要用到的内容
+ devDependencies
=> 表示的你项目的 开发依赖
=> 比如 gulp
=> 指项目开发阶段需要用到的内容, 将来上线以后不需要用到的
gulp 第三方包最好是放在 devDependencies
+ 在你安装第三方依赖的时候, 书写 $ npm install --dev 包名; 或简写: npm i gulp -D
+ 就会把依赖项记录再 devDependencies
gulp常用的API(接口)
gulp 的常用 API
+ 前提: 下载 gulp 第三方, 导入以后使用
1. gulp.task()
=> 语法: gulp.task(任务名称, 任务处理函数)
=> 作用: 创建一个基于流的任务
=> 例子: gulp.task('htmlHandler', function () {
// 找到 html 源文件, 进行压缩, 打包, 放入指定目录
})
2. gulp.src()
=> 语法: gulp.src(路径信息)
=> 作用: 找到源文件
=> 书写方式
2-1. gulp.src('./a/b.html')
-> 找到指定一个文件
2-2. gulp.src('./a/*.html')
-> 找到指定目录下, 指定后缀的文件
2-3. gulp.src('./a/**')
-> 找到指令目录下的所有文件
2-4. gulp.src('./a/** /*')
-> 找到 a 目录下所有子目录里面的所有文件
2-5. gulp.src('./a/** /*.html')
-> 找到 a 目录下所有子目录里面的所有 .html 文件
3. gulp.dest()
=> 语法: gulp.dest(路径信息)
=> 作用: 把一个内容放入指定目录内
=> 例子: gulp.dest('./abc')
-> 把他接收到的内容放到 abc 目录下
4. gulp.watch()
=> 语法: gulp.watch(路径信息, 任务名称)
=> 作用: 监控指定目录下的文件, 一旦发生变化, 从新执行后面的任务
=> 例子: gulp.watch('./src/pages/*.html', htmlHandler)
-> 当指定目录下的 html 文件发生变化, 就会执行 htmlHandler 这个任务
5. gulp.series()
=> 语法: gulp.series(任务1, 任务2, 任务3, ...)
=> 作用: 逐个执行多个任务, 前一个任务结束, 第二个任务开始
6. gulp.parallel()
=> 语法: gulp.parallel(任务1, 任务2, 任务3, ...)
=> 作用: 并行开始多个任务
7. pipe()
=> 管道函数
=> 所有的 gulp API 都是基于流
=> 接收当前流, 进入下一个流过程的管道函数
=> 例子:
gulp打包流程:
gulp.src().pipe(压缩任务).pipe(转码).pipe(gulp.dest('abc'))
项目中的gulp最好下载到: devDependencies 中; (开发依赖) ;
npm i gulp -D
项目中的gulp的第三方插件也要下载到 devDependencies 中; -D
例如 :npm i gulp-cssmin -D
gulp常用的插件
gulp 常用插件
+ gulp 的各种插件就是用来执行各种各样的压缩混淆转码任务的
下载到本地 npm i 插件名 -D
1. gulp-cssmin
作用:打包css文件
=> 下载: npm i gulp-cssmin -D
=> 导入: const cssmin = require('gulp-cssmin')
=> 导入以后得到一个处理流文件的函数
=> 直接再管道函数里面执行就好了
2. gulp-autoprefixer
作用: 自动添加属性的前缀;
=> 下载: npm i gulp-autoprefixer -D
=> 导入: const autoPrefixer = require('gulp-autoprefixer')
=> 导入以后得到一个处理流文件的函数
=> 直接再管道函数里面使用, 需要传递参数
-> { browsers: [要兼容的浏览器] }
// 或者在package.json文件里 添加 "browserslist" :["浏览器的版本号"], 就可以直接写 .pipe(autoPrefixer());
3. gulp-sass
=> 下载: npm i gulp-sass -D
-> 很容易报错, 基本下载不成功
-> 为什么: 因为 gulp-sass 依赖另一个第三方, node-sass
=> node-sass 很难下载成功
=> 以前都是再一个地方下载, 后来 node-sass 自己单独有一个下载地址
=> 如果你不进行单独的 node-sass 下载地址配置, 就很容易失败
-> 解决: 给 node-sass 单独配置一个下载地址
=> 下载 node-sass 从这个单独的地址下载, 下载其他的东西还是统一地址
-> node-sass 单独下载地址
=> $ set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/
=> 单独配置一个下载地址, 只有下载 node-sass 的时候会使用
-> 过程
1. $ set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/
2. $ npm i node-sass -D
3. $ npm i gulp-sass -D
=> 导入: const sass = require('gulp-sass')
=> 导入以后得到一个可以处理流文件的函数, 直接再管道函数里面执行就可以了
4. gulp-uglify
=> 把 JS 文件压缩的
=> 下载: npm i -D gulp-uglify
=> 导入: const uglify = require('gulp-uglify')
=> 导入以后得到一个可以处理流文件的函数
=> 直接再管道函数中使用就可以了
=> 注意: 你不能写 ES6 语法, 一旦有了 ES6 语法就会报错
5. gulp-babel
=> 专门进行 ES6 转 ES5 的插件
=> gulp-babel 的版本
-> gulp-babel@7: 大部分使用再 gulp@3 里面
-> gulp-babel@8: 大部分使用再 gulp@4 里面
=> 下载:
-> gulp-babel 需要依赖另外两个包, 我们要一起下载
-> 另外两个包: @babel/core @babel/preset-env
=> 导入:
-> 只要导入一个包就够了, 他会自动导入另外两个包
-> const babel = require('gulp-babel')
=> 导入以后得到一个可以处理流文件的函数
=> 直接再管道函数内部使用, 需要传递参数
6. gulp-htmlmin
=> 下载: npm i -D gulp-htmlmin
=> 导入: const htmlmin = require('gulp-htmlmin')
=> 导入以后得到一个可以处理流文件的函数
=> 直接再管道函数里面调用, 需要传递参数
7. del
=> 下载: npm i -D del
=> 作用: 删除文件目录
=> 导入: const del = require('del')
=> 导入以后得到一个函数, 直接使用传递参数就可以了
8. gulp-webserver
=> 作用: 启动一个基于 node 书写的服务器
=> 下载: npm i -D gulp-webserver
=> 导入: const webserver = require('gulp-webserver')
=> 导入以后得到一个处理流文件的函数
=> 我们再管道函数内调用就可以了, 需要传递参数
9. gulp-file-include
=> 作用: 再一个 html 页面里面导入一个 html 片段
=> 下载: npm i -D gulp-file-include
=> 导入: const fileInclude = require('gulp-file-include')
=> 导入以后得到一个处理流文件的函数
=> 我们再管道函数内调用就可以了, 需要传递参数
书写gulpfile.js配置文件
执行一个 gulp 配置好的任务
+ 直接打开命令行, 切换到 gulpfile.js 所在的目录
+ 执行指令 gulp 任务名称
gulp 是依赖于 node 环境运行的
+将来的运行也是以 node 为基础运行的
+书写 gulpfile.js 文件就按照 node 的模块化语法进行书写(CommonJS);
书写gulpfile.js配置文件
// 0. 导入第三方
// 0-1. 导入 gulp
const gulp = require('gulp');
// 0-2. 导入 gulp-cssmin =>打包 sass 文件的任务
const cssmin = require("gulp-cssmin");
// 0-3. 导入 gulp-autoprefixer
const autoPrefixer = require("gulp-autoprefixer");
// 0-4. 导入 gulp-sass =>打包 sass 文件的任务
const sass = require("gulp-sass");
// 0-5. 导入 gulp-uglify
const uglify = require("gulp-uglify");
// 0-6. 导入 gulp-babel
const babel = require("gulp-babel");
// 0-7. 导入 gulp-htmlmin => 打包 html 文件的任务
const htmlmin = require("gulp-htmlmin");
// 0-8. 导入 del
const del = require("del");
// 0-9. 导入 gulp-webserver
const webserver = require("gulp-webserver");
// 0-10. 导入 gulp-file-include
const fileInclude = require("gulp-file-include");
1. 创建任务
// 1-1. 创建一个打包 css 的任务
const cssHandler = function () {
return gulp
.src("./src/css/*.css") // 1. 找到内容
.pipe(autoPrefixer()) // 2. 自动添加前缀
.pipe(cssmin()) // 3. 压缩
.pipe(gulp.dest("./dist/css/")); // 4. 放到指定目录
};
// 1-2. 创建一个打包 sass 文件的任务
const sassHandler = function () {
return gulp
.src("./src/sass/*.scss")
.pipe(sass())
.pipe(autoPrefixer())
.pipe(cssmin())
.pipe(gulp.dest("./dist/sass/"));
};
// 1-3. 创建一个打包 js 文件的任务
const jsHandler = function () {
return gulp
.src("./src/js/*.js") // 1. 找到 js 文件
.pipe(
babel({
// babel@7, presets: ['es2015']
presets: ["@babel/env"],
})
)
.pipe(uglify())
.pipe(gulp.dest("./dist/js/"));
};
// 1-4. 创建一个打包 html 文件的任务
const htmlHandler = function () {
return gulp
.src("./src/pages/*.html")
.pipe(
fileInclude({
// 根据你的配置导入对应的 html 片段
prefix: "@-@", // 你自定义的一个标识符
basepath: "./src/components", // 基准目录, 你的组件文件都在哪一个目录里面
})
)
.pipe(
htmlmin({
// 通过你配置的参数来进行压缩
// collapseWhitespace: true, // 表示移出空格
removeEmptyAttributes: true, // 表示移出空的属性(仅限于原生属性)
collapseBooleanAttributes: true, // 移出 checked 类似的布尔值属性
removeAttributeQuotes: true, // 移出属性上的双引号
minifyCSS: true, // 压缩内嵌式 css 代码(只能基本压缩, 不能自动添加前缀)
minifyJS: true, // 压缩内嵌式 JS 代码(只能基本压缩, 不能进行转码)
removeStyleLinkTypeAttributes: true, // 移出 style 和 link 标签上的 type 属性
removeScriptTypeAttributes: true, // 移出 script 标签上默认的 type 属性
})
)
.pipe(gulp.dest("./dist/pages/"));
};
// 1-5. 创建一个打包 images 文件的任务
const imgHandler = function () {
return gulp.src("./src/images/**").pipe(gulp.dest("./dist/images/"));
};
// 1-6. 创建一个打包 videos 文件的任务
const videoHandler = function () {
return gulp.src("./src/videos/**").pipe(gulp.dest("./dist/videos/"));
};
// 1-7. 创建一个打包 audios 文件的任务
const audioHandler = function () {
return gulp.src("./src/audios/**").pipe(gulp.dest("./dist/audios/"));
};
// 1-8. 创建一个打包 第三方 的任务
const libHandler = function () {
return gulp.src("./src/lib/**/*").pipe(gulp.dest("./dist/lib/"));
};
// 1-9. 创建一个打包 fonts 文件的任务
const fontHandler = function () {
return gulp.src("./src/fonts/**/*").pipe(gulp.dest("./dist/fonts/"));
};
// 1-10. 创建一个删除 dist 目录的任务
const delHandler = function () {
// del 直接执行就可以了, 不需要流
// 参数以数组的形式传递你要删除的文件夹
return del(["./dist/"]);
};
// 1-11. 创建一个启动 服务器 的任务
const webHandler = function () {
return gulp.src("./dist").pipe(
webserver({
host: "www.gx.com", // 域名(可以配置自定义域名)
port: "8080", // 端口号
livereload: true, // 当文件修改的时候, 是否自动刷新页面
open: "./pages/login.html", // 默认打开哪一个文件(从 dist 目录以后的目录开始书写)
proxies: [
// 配置你的所有代理
// 每一个代理就是一个对象数据类型
// 注意: 如果你没有代理, 不要写空对象
{
// 代理标识符
source: "/dt",
// 代理目标地址
target: "https://www.duitang.com/napi/blog/list/by_filter_id/",
},
{
source: "/gx",
target: "http://localhost:80/server.php",
},
{
source: "/gx2",
target: "http://localhost:80/",
},
],
})
);
};
// 1-12. 创建一个监控任务
const watchHandler = function () {
// 使用 gulp.watch()
gulp.watch("./src/sass/*.scss", sassHandler);
gulp.watch("./src/css/*.css", cssHandler);
gulp.watch("./src/js/*.js", jsHandler);
gulp.watch("./src/pages/*.html", htmlHandler);
};
// 3. 配置一个默认任务
module.exports.default = gulp.series(
delHandler,
gulp.parallel(
cssHandler,
sassHandler,
jsHandler,
htmlHandler,
imgHandler,
videoHandler,
audioHandler,
libHandler,
fontHandler
),
webHandler,
watchHandler
);