/**
* 目标:基于 fs 模块 读写文件内容
* 1. 加载 fs 模块对象
* 2. 写入文件内容
* 3. 读取文件内容
*/
// 1. 加载 fs 模块对象
const fs = require('fs')
// 2. 写入文件内容
fs.writeFile('./text.txt', 'Hello,node.js', err => {
if(err) console.log(err)
else console.log('写入成功')
})
// 3. 读取文件内容
fs.readFile('./text.txt', (err, data) => {
if(err) console.log(err)
// data 是 buffer 16 进制数据流对象
// .toString() 转换成字符串
else console.log(data.toString())
})
/**
* 目标:在Node.js环境的代码中,应使用绝对路径
* 原因:代码的相对路径是以终端所在文件夹为起点,而不是Vscode资源管理器
* 容易造成目标文件找不到的错误
*/
const fs = require('fs')
// 1.引入path模块对象
const path = require('path')
// 2.调用path.join()配合__dirname组成目标文件的绝对路径
console.log(__dirname)
fs.readFile(path.join(__dirname, '../text.txt'), (err, data) => {
if (err) console.log(err)
else console.log(data.toString())
})
// 1.1 读取源 html 文件内容
const fs = require('fs')
const path = require('path')
fs.readFile(path.join(__dirname, 'public/index.html'), (err, data) => {
if (err) console.log(err)
else {
const htmlStr = data.toString()
// 1.2 正则替换字符串
const resultStr = htmlStr.replace(/[\r\n]/g, '')
console.log(resultStr)
// 1.3 写入到新的 html 文件中
// writeFile方法没有文件可以自动创建,但是不能自动创建文件夹(自己手动创建)
fs.writeFile(path.join(__dirname, 'dist/index.html'), resultStr, err => {
if (err) console.log(err)
else console.log('写入成功')
})
}
})
/**
* 目标:基于 http 模块创建 Web 服务程序
* 1.1 加载 http 模块,创建 Web 服务对象
* 1.2 监听 request 请求事件,设置响应头和响应体
* 1.3 配置端口号并启动 Web 服务
* 1.4 浏览器请求(http://localhost:3000)测试
*/
// 1.1 加载 http 模块,创建 Web 服务对象
const http = require('http')
const server = http.createServer()
// 1.2 监听 request 请求事件,设置响应头和响应体
server.on('request', (req, res) => {
// 设置响应头-内容类型-普通文本以及中文编码格式
res.setHeader('Content-Type', 'text/plain;charset=utf-8')
// 设置响应体内容,结束本次请求与响应
res.end('欢迎使用 Node.js 和 http 模块创建的 Web 服务')
})
// 1.3 配置端口号并启动 Web 服务
server.listen(3000, () => {
console.log('Web 服务启动成功了')
})
/**
* 目标:基于 Web 服务,开发提供网页资源的功能
* 步骤:
* 1. 基于 http 模块,创建 Web 服务
* 2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求方
* 3. 其他路径,暂时返回不存在提示
* 4. 运行 Web 服务,用浏览器发起请求
*/
const fs = require('fs')
const path = require('path')
// 1. 基于 http 模块,创建 Web 服务
const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => {
// 2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求方
if (req.url === '/index.html') {
fs.readFile(path.join(__dirname, 'dist/index.html'), (err, data) => {
res.setHeader('Content-Type', 'text/html;charset=utf-8')
res.end(data.toString())
})
} else {
// 3. 其他路径,暂时返回不存在提示
res.setHeader('Content-Type', 'text/html;charset=utf-8')
res.end('你要访问的资源路径不存在')
}
})
server.listen(8080, () => {
console.log('Web 服务启动成功了')
})
/**
* 目标:基于 CommonJS 标准语法,封装属性和方法并导出
*/
const baseURL = 'http://hmajax.itheima.net'
const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
// 导出
module.exports = {
url: baseURL,
arraySum: getArraySum
}
index.js
/**
* 目标:基于 CommonJS 标准语法,导入工具属性和方法使用
*/
// 导入
const obj = require('./utils.js')
console.log(obj)
const result = obj.arraySum([5,1,2,3])
console.log(result)
需求:封装并导出基地址和求数组元素和的函数
默认标准使用:
1.导出:export default {}
2.导入:import 变量名 from ‘模块名或路径’
注意:Node.js 默认支持 CommonJS 标准语法
如需使用 ECMAScript 标准语法,在运行模块所在文件夹新建 package.json 文件,并设置 { “type” : “module” }
练习:
/**
* 目标:基于 ECMAScript 标准语法,封装属性和方法并"命名"导出
*/
export const baseURL = 'http://hmajax.itheima.net'
export const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
index.js
/**
* 目标:基于ECMAScript 标准语法,'命名'导入
* 工具属性和方法使用
*/
// 命名导入
import {baseURL, getArraySum} from './utils.js'
console.log(baseURL)
console.log(getArraySum)
const result = getArraySum([10, 20, 33])
console.log(result)
package.json
{
"type": "module"
}
/**
* 目标:使用npm 下载 dayjs 软件包,来格式化日期时间
* 1. 初始化清单文件 :npm init -y(得到 package.json 文件,有则略过此命令)
* 2. 下载软件包 :npm i 软件包名称
* 3. 使用软件包
*/
// 3. 使用软件包
const dayjs = require('dayjs')
const nowDateStr = dayjs().format('YYYY-MM-DD')
console.log(nowDateStr)
问题:项目中不包含 node_modules,能否正常运行?
答案:不能,缺少依赖的本地软件包
原因:因为,自己用 npm 下载依赖比磁盘传递拷贝要快得多
解决:项目终端输入命令:npm i
下载 package.json 中记录的所有软件包
软件包区别:
➢ 本地软件包:当前项目内使用,封装属性和方法,存在于 node_modules
➢ 全局软件包:本机所有项目使用,封装命令和工具,存在于系统设置的位置
nodemon 作用:替代 node 命令,检测代码更改,自动重启程序
使用:
1.安装:npm i nodemon -g(-g 代表安装到全局环境中)
2.运行:nodemon 待执行的目标 js 文件
需求:启动准备好的项目,修改代码保存后,观察自动重启应用程序
Webpack 配置(https://webpack.docschina.org/concepts/#entry):影响 Webpack 打包过程和结果
步骤:
webpack.config.js
const path = require('path');
module.exports = {
// 入口
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './logon/index.js',
clean: true //生成打包内容之前,清空输出目录
},
};
需求:点击登录按钮,判断手机号和验证码长度
步骤:
1.准备用户登录页面
2.编写核心 JS 逻辑代码
3.打包并手动复制网页到 dist 下,引入打包后的 js,运行
核心:Webpack 打包后的代码,作用在前端网页中使用
插件 html-webpack-plugin: 在 Webpack 打包时生成 html 文件
步骤:
1.下载 html-webpack-plugin 本地软件包
2.配置 webpack.config.js 让 Webpack 拥有插件功能
3.重新打包观察效果
加载器 css-loader:解析 css 代码
加载器 style-loader:把解析后的 css 代码插入到 DOM
步骤:
1.准备 css 文件代码引入到 src/login/index.js 中(压缩转译处理等)
2.下载 css-loader 和 style-loader 本地软件包
3.配置 webpack.config.js 让 Webpack 拥有该加载器功能
4. 打包后观察效果
注意:Webpack 默认只识别 js 代码
插件 mini-css-extract-plugin:提取 css 代码
步骤:
1.下载 mini-css-extract-plugin 本地软件包
2.配置 webpack.config.js 让 Webpack 拥有该插件功能
3.打包后观察效果
注意:不能和 style-loader 一起使用
好处:css 文件可以被浏览器缓存,减少 js 文件体积
问题:css 代码提取后没有压缩
解决:使用 css-minimizer-webpack-plugin 插件
步骤:
1.下载 css-minimizer-webpack-plugin 本地软件包
2.配置 webpack.config.js 让 webpack 拥有该功能
3. 打包重新观察
加载器 less-loader:把 less 代码编译为 css 代码
步骤:
1.新建 less 代码(设置背景图)并引入到 src/login/index.js 中
2.下载 less 和 less-loader 本地软件包
3.配置 webpack.config.js 让 Webpack 拥有功能
4.打包后观察效果
注意:less-loader 需要配合 less 软件包使用
问题:之前改代码,需重新打包才能运行查看,效率很低
开发环境:配置 webpack-dev-server 快速开发应用程序
作用:启动 Web 服务,自动检测代码变化,热更新到网页
注意:dist 目录和打包内容是在内存里(更新快)
步骤:
打包模式:告知 Webpack 使用相应模式的内置优化
分类:
设置:
方式1:在 webpack.config.js 配置文件设置 mode 选项
方式2:在 package.json 命令行设置 mode 参数
注意:命令行设置的优先级高于配置文件中的,推荐用命令行设置
将css文件放入login中
webpack.config.js
// 插件(给webpack提供更多功能)
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/login.html'), //模板文件
filename: path.resolve(__dirname, 'dist/login/index.html') //输出文件
}),
new MiniCssExtractPlugin({
filename: './login/index.css' //放入login中
}) //生成css文件
],
需求:在开发模式下用 style-loader 内嵌更快,在生产模式下提取 css 代码
方案1:webpack.config.js 配置导出函数,但是局限性大(只接受 2 种模式)
方案2:借助 cross-env (跨平台通用)包命令,设置参数区分环境
步骤:
1.下载 cross-env 软件包到当前项目
2.配置自定义命令,传入参数名和值(会绑定到 process.env 对象下)
3.在 webpack.config.js 区分不同环境使用不同配置
4.重新打包观察两种配置区别
方案3:配置不同的 webpack.config.js (适用多种模式差异性较大情况)
需求:前端项目中,开发模式下打印语句生效,生产模式下打印语句失效
问题:cross-env 设置的只在 Node.js 环境生效,前端代码无法访问 process.env.NODE_ENV
解决:使用 Webpack 内置的 DefinePlugin 插件
作用:在编译时,将前端代码中匹配的变量名,替换为值或表达式
问题:代码被压缩和混淆,无法正确定位源代码位置(行数和列数)
source map:可以准确追踪 error 和 warning 在原始代码的位置
设置:webpack.config.js 配置 devtool 选项
inline-source-map 选项:把源码的位置信息一起打包在 js 文件内
注意:source map 仅适用于开发环境,不要在生产环境使用(防止被轻易查看源码位置)
解析别名:配置模块如何解析,创建 import 引入路径的别名,来确保模块引入变得更简单
例如:原来路径如图,比较长而且相对路径不安全
解决:在 webpack.config.js 中配置解析别名 @ 来代表 src 绝对路径
CDN定义:内容分发网络,指的是一组分布在各个地区的服务器
作用:把静态资源文件/第三方库放在 CDN 网络中各个服务器中,供用户就近请求获取
好处:减轻自己服务器请求压力,就近请求物理延迟低,配套缓存策略
需求:开发模式使用本地第三方库,生产模式下使用 CDN 加载引入
需求:开发模式使用本地第三方库,生产模式下使用 CDN 加载引入
步骤:
单页面:单个 html 文件,切换 DOM 的方式实现不同业务逻辑展示,后续 Vue/React 会学到
多页面:多个 html 文件,切换页面实现不同业务逻辑展示
需求:把黑马头条-数据管理平台-内容页面一起引入打包使用
步骤:
1.准备源码(html,css,js)放入相应位置,并改用模块化语法导出
2.下载 form-serialize 包并导入到核心代码中使用
3.配置 webpack.config.js 多入口和多页面的设置
4.重新打包观察效果
需求:把发布文章页面一起打包
步骤:
需求:把 2 个以上页面引用的公共代码提取
步骤: