Node.js /webpack DAY6

一、Node.js 入门

1. 什么是 Node.js?

2. 什么是前端工程化?

3. Node.js 为何能执行 JS?

4. Node.js 安装

5. 使用 Node.js

总结

6. fs 模块 - 读写文件

/**
 * 目标:基于 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())
})

7. path 模块 - 路径处理

8.path 模块 - 路径处理

/**
 * 目标:在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())
})

9. 案例 - 压缩前端 html

// 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('写入成功')
    })
  }
})

10.URL 中的端口号

协议+域名+端口号+资源路径

10.常见的服务程序

总结

11. http 模块-创建 Web 服务


/**
 * 目标:基于 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 服务启动成功了')
})

运行结果:

ctrl+c 结束进程
cls清空

案例:浏览时钟

需求:基于 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 服务启动成功了')
})

二、Node.js 模块化

1.什么是模块化?

2.CommonJS 标准

utils.js

/**
 * 目标:基于 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)

总结

3.ECMAScript 标准 - 默认导出和导入

需求:封装并导出基地址和求数组元素和的函数

默认标准使用:

1.导出:export default {}

2.导入:import 变量名 from '模块名或路径'

注意:Node.js 默认支持 CommonJS 标准语法

如需使用 ECMAScript 标准语法,在运行模块所在文件夹新建 package.json 文件,并设置 { "type" : "module" }


练习:


总结

4. ECMAScript 标准 - 命名导出和导入

utils.js

/**
 * 目标:基于 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"
}

总结

5.包的概念

  • 包:将模块,代码,其他资料聚合成一个文件夹
  • 包分类:
    ✓ 项目包:主要用于编写项目和业务逻辑
    ✓ 软件包:封装工具和方法进行使用
  • 要求:根目录中,必须有 package.json 文件(记录包的清单信息)
  • 注意:导入软件包时,引入的默认是 index.js 模块文件 / main 属性指定的模块文件
  • 需求:封装数组求和函数的模块,判断用户名和密码长度函数的模块,形成成一个软件包

总结

6.npm - 软件包管理器


server.js

/**
 * 目标:使用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)

总结

7.npm - 安装所有依赖

问题:项目中不包含 node_modules,能否正常运行?

答案:不能,缺少依赖的本地软件包

原因:因为,自己用 npm 下载依赖比磁盘传递拷贝要快得多

解决:项目终端输入命令:npm i
下载 package.json 中记录的所有软件包


总结

8.npm - 全局软件包 nodemon

软件包区别:

➢ 本地软件包:当前项目 内使用,封装属性和方法 ,存在于 node_modules

➢ 全局软件包:本机 所有项目使用,封装命令和工具 ,存在于系统设置的位置

nodemon 作用:替代 node 命令,检测代码更改,自动重启程序

使用:

1.安装:npm i nodemon -g(-g 代表安装到全局环境中)

2.运行:nodemon 待执行的目标 js 文件

需求:启动准备好的项目,修改代码保存后,观察自动重启应用程序

总结

9.Node.js 总结



三、Webpack

1.什么是 Webpack?

2.使用 Webpack

3.修改 Webpack 打包入口和出口

Webpack 配置(https://webpack.docschina.org/concepts/#entry):影响 Webpack 打包过程和结果

步骤:

  1. 项目根目录,新建 webpack.config.js 配置文件
  2. 导出配置对象,配置入口,出口文件的路径
  3. 重新打包观察
    注意:只有和入口产生直接/间接的引入关系,才会被打包


    webpack.config.js
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  //生成打包内容之前,清空输出目录
  },
};

4.案例:用户登录 - 长度判断

需求:点击登录按钮,判断手机号和验证码长度

步骤:

1.准备用户登录页面

2.编写核心 JS 逻辑代码

3.打包并手动复制网页到 dist 下,引入打包后的 js,运行

核心:Webpack 打包后的代码,作用在前端网页中使用

5.自动生成 html 文件

插件 html-webpack-plugin: 在 Webpack 打包时生成 html 文件

步骤:

1.下载 html-webpack-plugin 本地软件包

2.配置 webpack.config.js 让 Webpack 拥有插件功能

3.重新打包 观察效果

6.打包 css 代码

加载器 css-loader:解析 css 代码

加载器 style-loader:把解析后的 css 代码插入到 DOM

步骤:

1.准备 css 文件代码 引入到 src/login/index.js 中(压缩转译处理等)

2.下载 css-loader 和 style-loader 本地软件包

3.配置 webpack.config.js 让 Webpack 拥有该加载器功能

  1. 打包后观察效果

注意:Webpack 默认只识别 js 代码

7.优化-提取 css 代码

插件 mini-css-extract-plugin:提取 css 代码

步骤:

1.下载 mini-css-extract-plugin 本地软件包

2.配置 webpack.config.js 让 Webpack 拥有该插件功能

3.打包后观察效果

注意:不能和 style-loader 一起使用

好处:css 文件可以被浏览器缓存,减少 js 文件体积

8.优化-压缩过程

问题:css 代码提取后没有压缩

解决:使用 css-minimizer-webpack-plugin 插件

步骤:

1.下载 css-minimizer-webpack-plugin 本地软件包

2.配置 webpack.config.js 让 webpack 拥有该功能

  1. 打包重新观察

9.打包 less 代码

加载器 less-loader:把 less 代码编译为 css 代码

步骤:

1.新建 less 代码(设置背景图)并引入到 src/login/index.js 中

2.下载 less 和 less-loader 本地软件包

3.配置 webpack.config.js 让 Webpack 拥有功能

4.打包后观察效果

注意:less-loader 需要配合 less 软件包使用

10.打包图片

11、搭建开发环境

问题:之前改代码,需重新打包才能运行查看,效率很低

开发环境:配置 webpack-dev-server 快速开发应用程序

作用:启动 Web 服务,自动 检测代码变化,热更新到网页

注意:dist 目录和打包内容是在内存里(更新快)

步骤:

  1. 下载 webpack-dev-server 软件包到当前项目
  2. 设置模式为开发模式 ,并配置自定义命令
  3. 使用 npm run dev 来启动开发服务器,试试热更新效果

    注意1:webpack-dev-server 借助 http 模块创建 8080 默认 Web 服务
    注意2:默认以 public 文件夹作为服务器根目录
    注意3:webpack-dev-server 根据配置,打包相关代码在内存当中,以 output.path 的值作为服务器根目录(所以可以直接直接拼接访问dist目录下内容)

12、打包模式

打包模式:告知 Webpack 使用相应模式的内置优化

分类:

设置:

方式1:在 webpack.config.js 配置文件设置 mode 选项

方式2:在 package.json 命令行设置 mode 参数

注意:命令行设置的优先级高于配置文件中的,推荐用命令行设置

将css文件放入login中
webpack.config.js

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文件
  ],

13、打包模式的应用

需求:在开发模式下用 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 (适用多种模式差异性较大情况)

14、前端-注入环境变量

需求:前端 项目中,开发模式下打印语句生效,生产模式下打印语句失效

问题:cross-env 设置的只在 Node.js 环境生效,前端代码无法访问 process.env.NODE_ENV
解决:使用 Webpack 内置的 DefinePlugin 插件

作用:在编译时,将前端代码中匹配的变量名,替换为值或表达式

15、开发环境调错 - source map

问题:代码被压缩和混淆,无法正确定位源代码位置(行数和列数)
source map:可以准确追踪 error 和 warning 在原始代码的位置

设置:webpack.config.js 配置 devtool 选项

inline-source-map 选项:把源码的位置信息一起打包在 js 文件内

注意:source map 仅适用于开发环境,不要在生产环境使用(防止被轻易查看源码位置)

16、解析别名 alias

解析别名:配置模块如何解析,创建 import 引入路径的别名,来确保模块引入变得更简单

例如:原来路径如图,比较长而且相对路径不安全

解决:在 webpack.config.js 中配置解析别名 @ 来代表 src 绝对路径

17、优化-CDN使用

CDN定义:内容分发网络,指的是一组分布在各个地区的服务器

作用:把静态资源文件/第三方库放在 CDN 网络中各个服务器中,供用户就近请求获取

好处:减轻自己服务器请求压力,就近请求物理延迟低,配套缓存策略

需求:开发模式 使用本地 第三方库,生产模式 下使用 CDN 加载 引入

需求:开发模式使用本地第三方库,生产模式下使用 CDN 加载引入

步骤:

  1. 在 html 中引入第三方库的 CDN 地址 并用模板语法判断
  2. 配置 webpack.config.js 中 externals 外部扩展选项(防止某些 import 的包被打包)
  3. 两种模式下打包观察效果


18、多页面打包

单页面单个 html 文件,切换 DOM 的方式实现不同业务逻辑展示,后续 Vue/React 会学到

多页面:多个 html 文件,切换页面实现不同业务逻辑展示

需求:把黑马头条-数据管理平台-内容页面一起引入打包使用

步骤:

1.准备源码 (html,css,js)放入相应位置,并改用模块化语法导出

2.下载 form-serialize 包并导入 到核心代码中使用

3.配置 webpack.config.js 多入口多页面 的设置

4.重新打包观察效果

19、案例-发布文章页面打包

需求:把发布文章页面一起打包

步骤:

  1. 准备发布文章页面源代码,改写成模块化的导出和导入方式
  2. 修改 webpack.config.js 的配置,增加一个入口和出口
  3. 打包观察效果

20、优化-分割公共代码

需求:把 2 个以上页面引用的公共代码提取

步骤:

  1. 配置 webpack.config.js 的 splitChunks 分割功能
  2. 打包观察效果

    除了CDN外还有http://unpkg.comhttp://unpkg.com
相关推荐
y先森5 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy5 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189115 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿6 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡7 小时前
commitlint校验git提交信息
前端
虾球xz7 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇8 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒8 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员8 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐8 小时前
前端图像处理(一)
前端