Web前端笔记-11、JS基础-Nodejs、模块化、webpack
Node.js
使用 Node.js 编写后端程序/支持前端工程化
后端程序:提供接口和数据,网页资源等
前端工程化:对代码压缩,转译,整合(使用各种工具,提升效率)
首先:浏览器能执行J 代码,依靠的是内核中的V8引擎(C++程序)
其次:Node.js 是基于 Chrome V8 引擎进行封装(运行环境)
区别:都支持 ECMAScript 标准语法,Node.js 有独立的 API
Node.js 环境没有 DOM 和 BOM 等
浏览器独有:
document、window、XMLHttpRequest等
共有:
ECMAScript、String、Number、setTimeout、console、Promise等
Node.js独有:
fs、path、http等
Node.js 代码中,相对路径是根据终端所在路径来查找的
fs模块-读写文件
模块:类似插件,封装了方法/属性
fs 模块:封装了与本机文件系统进行交互的,方法/属性
加载:const fs = require('fs')
写入文件内容:fs.writeFile('path', 'content', err=>{写入后的回调函数})
读取文件内容:fs.readFile('path', (err, data)=>{读取后的回调函数})
读取文件内容中的data 是文件内容的 Buffer 数据流
path模块-路径处理
建议:在 Node.js 代码中,使用绝对路径
补充: __dirname 模块内置变量(获取当前文件所在的目录名)
path.join()会使用特定于平台的分隔符,作为定界符,将所有给定的路径片段连接在一起
加载:const fs = require('path')
path.join('D:', '代码', 'index.js')
path.join(__dirname, '../', 'resource/file.txt')
压缩前端HTML
目标:压缩前端代码,让浏览器加载网页更快(体验前端工程化)
前端工程化:对代码压缩,转译,整合,测试,自动部署等等
需求:把 回车符(\r)和換行符(\n)去掉进行压缩,写入到新html中
步骤:
- 读取源 html 文件内容
- 正则替换字符串
- 写入到新的 html 文件中
const fs = require('fs')
const path = require('path')
const url = path.join(__dirname, 'public', 'index.html')
// console.log(url)
fs.readFile(url, (err, data)=>{
if(err) return console.log(err)
// console.log(data.toString())
const str = data.toString().replace(/[\r\n]/g, '')
// console.log(str)
fs.writeFile(path.join(__dirname, 'dist', 'index.html'), str, err=>{
if(err) return console.log(err)
})
})
压缩JS并整合到HTML中
目标:压缩和整合前端JS代码,写入新到 html 中
- 压缩HTML
- 读取js 文件内容
- 正则替换换行,回车字符串和打印语句
- 拼接 html 内容和js 代码,写入到新的 html文件中
const fs = require('fs')
const path = require('path')
fs.readFile(path.join(__dirname, 'public', 'index.html'), (err, data)=>{
if(err) return console.log(err)
const htmlStr = data.toString().replace(/[\r\n]/g, '')
fs.readFile(path.join(__dirname, 'public', 'index.js'), (err, data)=>{
if(err) return console.log(err)
let jsStr = data.toString().replace(/\r\n/g, '').replace(/console.log\('.+?'\)/g, '')
jsStr = `<script>${jsStr}</script>`
fs.writeFile(path.join(__dirname, 'dist', 'index.html'), htmlStr + jsStr, err=>{
if(err) return console.log(err)
})
})
})
http模块-创建Web服务
需求:基于 http 模块编写程序,返回给请求方'hello,world'
步骤:
- 引入 http 模块,创建 web 服务对象
- 监听 request 请求事件,对本次请求,做一些响应处理
- 启动 Web 服务监听对应端口号
- 运行本服务在终端,用浏览器发起请求
const http = require('http')
const server = http.createServer()
// 监听 request 事件
server.on('request', (req, res)=>{
// response 给一个字符串
res.end('hello http')
})
// 启动服务器
server.listen(3000, ()=>{
console.log('3000开始监听')
})
中文字符的支持:
需求:让 web 服务返回的中文字符,浏览器正常解析
步骤:给响应头添加内容类型。
在server.on里加上:res.setHeader('content-Type','text/html;charset=utf-8')
Node.js模块化
在 Nodejs 中,每个文件都被视为一个单独的模块。
项目是由很多个模块文件组成的。
好处:提高代码复用性,按需加载,独立作用域。
使用:需要标准语法导出和导入进行使用
CommonJS标准
导入:const name = require('./file.js')
导出:module.exports = {name: 属性, name2: 方法}
ECMAScript 标准
导入:import 变量名 from '模块名或路径'
导出:export default {}
如需使用 ECMAScript 标准语法,在运行模块所在文件夹新建package.json 文件,并设置{"type" :"module"}
包和软件包的使用
包:将模块,代码,其他资料聚合成一个文件夹
项目包:主要用于编写项目和业务逻辑
软件包:封装工具和方法进行使用
要求:根目录中,必须有 package.json 文件(记录包的清单信息)
注意:导入软件包时,引入的默认是 index.js 模块文件/main 属性指定的模块文件
npm-软件包管理器
- (可选)初始化清单文件package.json:
npm init -y npm i 软件包名称,将下载的包源码放到项目的node_modules文件夹中- npm 会把下载的包记录到 package.json 中并固化版本
npm-安装所有依赖
npm i
下载 package.json 中记录的所有软件包
npm-全局软件包 nodemon
软件包区别:
本地软件包:当前项目内使用,封装属性和方法,存在于 node_modules
全局软件包:本机所有项目使用,封装命令和工具,存在于系统设置的位置
nodemon 作用:替代 node 命令,检测代码更改,自动重启程序
npm i nodemon -g
Express - 框架
基于 Node.js 平台, 快速、开放、极简的Web开发框架
概念:使用 express 本地软件包,快速搭建 web 服务(基于 http 模块)
功能:提供数据接口、提供网页资源等
- 下载 express 软件包
- 导入 express 创建 Web 服务对象
- 监听请求方法和请求路径
- 对其他请求方法和请求路径,默认返回 404 提示
- 监听端口号,启动 web 服务,在浏览器请求测试
const express = require('express')
const server = express()
server.get('/', (req, res)=>{
res.send('你好,欢迎使用express')
})
server.all('*', (req,res)=>{
res.status(404)
res.send('访问路径不存在')
})
server.listen(3000, ()=>{
console.log('Web 启动!')
})
浏览器的同源策略
同源策略是一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。
它能帮助阻隔恶意文档,减少可能被攻击的媒介。例如,它可以防止互联网上的恶意网站在浏览器中运行JS脚本,从第三方网络邮件服务(用户已登录)或公司内网(因没有公共IP 地址而受到保护,不会被攻击者直接访问)读取数据,并将这些数据转发给攻击者。
Web 内容的源由用于访问它的URL的方案(协议)、主机名(域名)和端口定义。只有当协议、主机和端口都匹配时,两个对象才具有相同的源。
同源:网页加载时所在源,和AJAX 请求时的源(协议,域名,端口号)全部相同即为同源。
作用:保护浏览器中网站的安全,限制 AJAX 只能向同源 URL 发起请求。
跨域问题
跨域:从一个源的文档/脚本,加载另一个源的资源就产生了跨域
网页所在源和 AJAX访问的源(协议,域名,端口)有一个不同,就发生了跨域访问,请求响应是失败的。
CORS
目标:前后端分离的项目,前端和后端不在一个源,还要保证数据通信
解决:采用CORS(跨域资源共享),一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),来访问加载服务器上的资源
服务器端:设置 Access-Control-Allow-Origin 响应头字段,允许除了它自己以外的源来访问自己的资源
步骤:
- 下载 cors 本地软件包
- 导入 cors 函数
server.use(cor())
同源访问
目标:开发环境用 cors,上线部署关闭 cors,并采用同源访问方式
做法:让后端web 服务既可以提供数据接口,也可以返回网页资源
好处:安全,后端的接口不允许非同源来访问
server.use(express.static('./public'))
webpack静态模块打包工具
静态模块:指的是编写代码过程中的,html,GSS,js,图片等固定内容的文件。
注意: 只有和入口有直接/间接的引入关系的模块,才会被打包。
原因:把静态模块内容,压缩,工整合,转译等(前端工程化)。
把less / sass 转成 css代码
把ES6+ 降级成 ES5
支持多种模块文件类型,多种模块标准语法
需求:封装 utils 包,校验用户名和密码长度,在 index.js 中使用,使用Webpack 打包
步骤:
- 新建项目文件夹,初始化包环境
- 新建 srC 源代码文件夹,编写验证用户名代码,代码会被webpack解析,,可以使用ECMAscript语法
- 下载 webpack webpack-cli 到项目(版本独立)--save-dev表示只在开发环境使用,线上不需要
- 项目中运行工具命令,采用自定义命令的方式(局部命令)
- 自动产生 dist 分发文件夹(压缩和优化后,用于最终运行的代码)
webpack默认的入口和出口:src/index.js 和 dist/main.js
修改 Webpack 打包入口和出口
步骤:
- 项目根目录,新建 webpack.config.js 配置文件
- 导出配置对象,配置入口,出口文件路径
webpack配置文件会被node解析 node默认支持 CommcnJS 语法
增加属性:clean:true 会清空dist目录
const path = require('path');
module.exports ={
entry: path.resolve(__dirname, 'src/main.js'),
output:{
path: path.resolve(__dirname, 'dist'),
filename:'app.js'
},
clean: true
};
webpack生成HTML文件
插件 html-webpack-plugin: 在 Webpack 打包时生成 html 文件
npm install --save-dev html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports ={
entry: path.resolve(__dirname, 'src/main.js'),
output:{
path: path.resolve(__dirname, 'dist'),
filename:'app.js'
},
clean: true,
plugin: [new htmlWebpackPlugin({
template:path.resolve(__dirname, 'public/index.html')
})],
};
webpack打包CSS
加载器 css-loader:解析 css 代码
加载器 style-loader:把解析后的CSS 代码插入到 DOM
npm install css-loader style-loader --save-dev
步骤:
- 准备 cSS 文件引入到 src/main.js 中(压缩转译处理等)在src/main.js中
import 'css/path' - 下载 cSS-loader 和 style-loader 本地软件包
- 配置 webpack.config.js 让 Webpack 拥有该加载器功能
const htmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports ={
entry: path.resolve(__dirname, 'src/main.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
},
clean: true,
plugin: [new htmlWebpackPlugin({
template:path.resolve(__dirname, 'public/index.html')
})],
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};
webpack打包less
npm install less less-loader --save-dev
const htmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports ={
entry: path.resolve(__dirname, 'src/main.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
},
clean: true,
plugin: [new htmlWebpackPlugin({
template:path.resolve(__dirname, 'public/index.html')
})],
module: {
rules: [
{
test: /\.lcss$/i,
use: ["style-loader", "css-loader", "less-loader"],
},
],
},
};
步骤:
- 准备 less 样式并引入到 src/main.js 中
import './less/index. less' - 下载 less 和 less-loader 本地软件包
- 配置 webpack.config.js 让 Webpack 拥有功能
- 打包后运行 dist/index.html观察效果
webpack打包图片
资源模块:Webpack5 内置了资源模块的打包,无需下载额外 loader
module.exports ={
entry: path.resolve(__dirname, 'src/main.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
},
clean: true,
plugin: [new htmlWebpackPlugin({
template:path.resolve(__dirname, 'public/index.html')
})],
module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext]'
},
},
],
},
};
步骤:
- 准备图片素材到 src/assets 中
- 在 index.less 中给 body 添加背景图
- 在 main.js 中给img 标签添加 logo 图片
- 配置 webpack.config.js 让 Webpack 拥有打包图片功能
babel编译器
babel 定义:是一个Javascript 语法编译器,将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
babel-loader:让 Webpack 可以使用babel 转译JavaScript 代码
npm i babel-loader @babel/core @babel/preset-env -D
Webpack 开发服务器
webpack-dev-server:快速开发应用程序
作用:启动 web 服务,打包输出源码在内存,并检测代码变化热更新到网页
npm i webpack-dev-server --save-dev
"scripts": {
"build": "webpack",
"dev": "webpack serve --open --mode=development"
},
- 下载 webpack-dev-server 软件包到当前项目
- 配置自定义命令,并设置打包的模式为开发模式
- 使用 npm run dev 来启动开发服务器
- 只要入口文件中的内容发生了改变就会热更新
npm run dev
打包模式
打包模式:告知 Webpack 使用相应模式的内置优化
| 模式名称 | 模式名字 | 特点 |
|---|---|---|
| 开发模式 | development | 调试代码,实时加载,模块热替换等 |
| 生产模式 | production | 压缩代码,资源优化,更轻量等 |
设置:
方式1:在 webpack.config.js 配置文件设置 mode 选项(不灵活)
方式2:在 package.json 命令行设置 mode 参数
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack serve --open --mode=development"
},
开发环境调错-source map
source map:可以准确追踪 error 和 warning 在原始代码的位置
问题:代码被压缩和混淆,无法正确定位源代码位置(行数和列数)
设置:webpack.config.js 配置 devtool选项
inline-source-map 值:把源码的位置信息一起打包在js 文件内
注意:source map 仅适用容开发环境,不要在生产环境使用(防止被轻易查看源码位置)
解析别名 alias
解析别名:配置模块如何解析,创建import或 require 的别名,来确保模块引入变得更简单
import {checkuserName,checkPassword} from '../src/utils/check.js'
太长
resolve: { // 解析
alias: { // 别名
Myutils: path.resolve(__dirname, 'src/utils"),
'@': path.resolve(__dirname, 'src/')
}
},
import {checkuserName,checkPassword} from 'Myutils/check.js'
import '@css/index.js'

浙公网安备 33010602011771号