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
相关推荐
吕彬-前端12 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(二)
前端·react.js·前端框架
小白小白从不日白33 分钟前
react hooks--useCallback
前端·react.js·前端框架
恩婧41 分钟前
React项目中使用发布订阅模式
前端·react.js·前端框架·发布订阅模式
mez_Blog42 分钟前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
珊珊而川1 小时前
【浏览器面试真题】sessionStorage和localStorage
前端·javascript·面试
森叶1 小时前
Electron 安装包 asar 解压定位问题实战
前端·javascript·electron
drebander1 小时前
ubuntu 安装 chrome 及 版本匹配的 chromedriver
前端·chrome
软件技术NINI1 小时前
html知识点框架
前端·html
深情废杨杨1 小时前
前端vue-插值表达式和v-html的区别
前端·javascript·vue.js
GHUIJS1 小时前
【vue3】vue3.3新特性真香
前端·javascript·vue.js