前端中级面试知识点总结(个人总结自用,不具有普适性,请自行斟酌使用)
Promise
Promise概述
Promise是异步编程的一种解决方案,它的构造函数是同步执行的,then 方法是异步执行的,所以Promise创建后里面的函数会立即执行,构造函数中的resolve和reject只有第一次执行有效,,也就是说Promise状态一旦改变就不能再变。
promise主要是用来解决回调地狱的问题,通过使用.then来使得代码成链式调用,方便维护和使用。.then中的回调函数属于异步任务中的微任务
promise的状态
promise一共有3个状态:pending、fulfilled、rejected
pedding->初始状态:调用promise时,一开始就呈现出等待状态,遇到resolve或者reject之前,都处于这个状态,且可以改变,但如果确定了状态(fulfilled/reject),则结果将永远不变,不能再次修改
fulfilled->成功状态:在执行了resolve后,promise则会从pedding变成fulfilled,后续会进入.then 的回调函数中,在回调函数的第一个参数函数中可以获取到值
rejected->失败状态:在执行了reject后,promise状态会变成rejected,rejected函数传递的参数,可以在.then的第二个参数函数中获取的到,或者是在.catch获取到,但是如果程序上的错误,得通过.catch函数去拿到失败消息,在.then中是获取不了的。
操作promise
Promise.resolve():静态方法,返回一个成功的promise
Promise.reject():静态方法,返回一个被拒绝的promise
Promise.then():实例方法,成功时的回调
Promise.catch():实例方法,被拒绝时的回调
Promise.finally():实例方法,无论成功还是失败都会执行
Promise 并发
Promise.all():只要有一个被拒绝,整个pormise就被拒绝,返回第一个被拒绝的,所有的都成功,会返回成功的数组。
Promise.any():只要有一个成功,整个pormise就成功,返回第一个成功的,所有的都被拒绝,会返回被拒绝的数组。
Promise.race():只要有一个确定了状态,不管是成功,还是被拒绝,整个promise都会返回,其状态和被确定的保持一致。
Promise.allSettled():所有的都执行完成后,才会返回,返回的数组中每个对象有两个属性,state表示promise的状态:resolve和rejected,value代表的是promise传递的值。
Mapbox
基础示例
其中style是重点,可以是url,可以是json配置对象,主要配置图层、图标、数据源等
mapboxgl.accessToken = '<输入你的token>';
const map = new mapboxgl.Map({
container: 'map', // 地图容器 ID
style: 'mapbox://styles/mapbox/streets-v12', // 样式url
center: [116.42396,39.91784], // 中心位置[lng, lat]
zoom: 16, // 缩放
pitch: 35, // 倾斜角度
});
sources中的数据源类型
sources 是对象 {} 的形式,其属性名就是 数据源的名称(或者说 数据源的 id),这样可以根据 数据源的名称(或者说 数据源的 id)快速获取数据源的信息。每个数据源 source 都有一个 type 属性,用于指定其具体的类型:
vector:矢量raster:栅格raster-dem:栅格化的数字高程模型geojson:GeoJSON 数据源image:图片video:视频
{
"sources":{
"vector-source": {
"type": "vector", // 类型(必填)
"url": "mapbox://mapbox.mapbox-streets-v6" // TileJSON 的请求地址(可选)
// 用于指定一个或多个切片数据源的请求地址(可选,和 TileJSON 中的 tiles 属性一致)
"tiles": [
"http://a.example.com/tiles/{z}/{x}/{y}.pbf",
"http://b.example.com/tiles/{z}/{x}/{y}.pbf"
]
}
}
}
layers中的图层类型
每个图层 layer 都有 id(具有唯一性)和 type 属性,其中 type 属性指定了其具体的渲染类型:
fill:填充line:线circle:圆点symbol:符号background:背景raster:栅格heatmap:热力图hillshade:坡面阴影fill-extrusion:三维填充
{
"layers":[
{
"id": "line-id", // 唯一 id (必填)
"type": "line", // 类型(必填)
"source": "source-name",// 数据源的名称
"filter": [], // 过滤(可选,用特定的表达式过滤指定的数据源的要素。
"layout": {}, // 布局类属性
"paint": {} // 绘制类属性
...
}
]
}
跳过accesstoken检测
MapBox在内网使用时,accesstoken不能使用,导致局域网内地图服务不能使用
mapboxgl.Map.prototype._authenticate = () => {};
sprite精灵图
主要用在symbol图层中,可以直接取高德或百度地图的精灵图,当有 layer 使用了 background-pattern、fill-pattern、line-pattern、fill-extrusion-pattern、icon-image 等属性时,sprite 必填。当指定了 sprite 后,mapbox 会自动生成雪碧图的完整请求地址,分别如下:
// style节点中定义
{
"sprite": "http://localhost:8080/sprite"
}
// 会发出两个请求,需要在对应url下返回一个sprite.png图片,一个sprite.json配置文件
`${sprite}.png`
`${sprite}.json`
sprite字段所指的url需要能请求到两个文件,一个是png文件,一个是json配置文件,json文件中指定了每个图标的位置和大小等属性
{
"zgyh": {
"visible": "true",
"pixelRatio": 1,
"x": 0,
"width": 32,
"y": 105,
"height": 32
},
"jsyh": {
"visible": "true",
"pixelRatio": 1,
"x": 0,
"width": 32,
"y": 35,
"height": 32
}
}
在图层中引用
// 图层中引用
{
'id': 'points',
'type': 'symbol',
'source': 'points',
"layout": {
"icon-image": "jsyh",
"icon-size": 0.25
}
}
glyphs字体图标
使用mapboxgl-js开发时,为了在内网环境使用字体库或使用我们喜欢的字体,需要将字体发布为内网pbf格式的服务。例如使用聚合图cluster时,默认字体在内网环境无法加载,导致聚合的标注文字无法显示。
有两种方法可以使用:一是使用 fontnik 工具生成,二是编写脚本自行下载默认的官方字体。
// style节点中定义
{
// URL 模板必须带有占位符 {fontstack} 和 {range}
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"
}
// 当有 layer 使用了 text-field 属性时,glyphs 必填
"layers": [
{
"id": "road-label",
"type": "symbol",
"source": "composite",
"source-layer": "road",
"layout": {
"text-field": "{name}",
"text-font": ["Open Sans Bold", "Arial Unicode MS Bold"]
}
}
]
}
Expressions表达式
Expressions:表达式集合(并非 style 的属性,只是 layer 的任何 layout 布局属性和 paint 绘制属性,以及 filter 属性等,它们的值都可以指定成一个表达式 Expression)
一个 Expression 定义了一个公式,总体来说可以将公式中的操作符分为以下 5 种:
Mathematical operators:数学操作符,用来对数值进行数学运算Logical operators:逻辑操作符,用来计算布尔值和条件控制String operators:字符串操作符,用来操作字符串Data operators:数据操作符,用来访问数据源中的要素featureCamera operators:照相机操作符,用来访问当前地图视图的各个参数
Expressions 是 Expression 的集合。而 Expression 是以 JSON 数组的形式来表示的,数组的第一个元素是 Expression 的操作符的名称,后续的元素表示操作的参数(也可以是一个 Expression)。
Data expressions
一个 data expression 是可以访问要素数据的任何表达式。而这些表达式使用了以下至少一种数据操作符:
get:用于获取要素的属性值,格式为["get", "property_name"],余下具体的可以看Expression referencehasidgeometry-typepropertiesfeature-state
通过 data expression 可以实现区分同一个图层中的不同要素,并以不同的形式呈现。比如设置颜色 circle-color,例如使用表达式给行政区划图的不同区域按等级设置不同的颜色。
{
"circle-color": [
"rgb", // rgb 操作符,用于表达颜色:rgb(red, green, blue)
["get", "temperature"], // 获取属性 temperature 的值,作为 rgb 中的 red 的值
0, // rgb 中的 green 始终为 0
// 用 100 减去属性 temperature 的值,作为 rgb 中的 blue 的值
["-", 100, ["get", "temperature"]],
]
}
Shape文件
shapefile 是一种ArcGis矢量数据存储格式,用于存储地理要素的位置、形状和属性。其存储为一组相关文件,并包含一个要素类。 一个shapfile包含三个必需的文件和一些可选的文件:
- .shp 地理要素的几何实体。
- .shx 地理要素几何实体的位置索引。
- .dbf 地理要素几何实体的属性。
使用xlsx-extract读取超大shp文件解析表头,完美解决用流的方式读取excel的问题
var powXLSX = require('xlsx-extract').XLSX;
// 读取文件所有sheet,默认只读取第一张sheet,参数配置如下
new powXLSX().extract('./test.xlsx', { sheet_all: true })
.on('sheet', function (sheet) {
console.log('sheet', sheet); // sheet is array [sheetname, sheetid, sheetnr]
})
.on('row', function (row) {
console.log('row', row); // row is a array of values or []
// 读取第一行表头后抛出异常提前结束
})
.on('cell', function (cell) {
// console.log('cell', cell); //cell is a value or null
})
.on('error', function (err) {
console.error('error', err);
})
.on('end', function (err) {
console.log('eof');
});
Cesium技术总结
实现气泡弹窗:
-
监听viewer的左键点击事件,监听类型为LEFT_CLICK,在setInputAction中使用pick拾取点击位置处的entity
-
监听场景渲染事件postRender
-
使用wgs84ToWindowCoordinates将拾取对象的场景坐标转换为屏幕坐标
-
找到弹窗的dom元素,设置其style属性更新位置及显示内容
-
监听viewer的右键点击事件,取消postRender的监听,并销毁弹窗
// 弹出框样式 <div id="stateShow"> <div>标题:<span id="title"></span></div> <div>状态:<span id="state"></span></div> <div>信息:<span id="info"></span></div> </div> // function updatePosition() { // 计算屏幕坐标 let windowPosition = viewer.scene.cartesianToCanvasCoordinates(target.position); // 更新弹窗位置 if (windowPosition == undefined){ document.getElementById('stateShow').style.left = (windowPosition.x - (220 / 2)) + 'px' document.getElementById('stateShow').style.top = (windowPosition.y - 150) + 'px' } } // 监听Entity的点击事件 viewer.screenSpaceEventHandler.setInputAction(function(e) { const pickedObject = viewer.scene.pick(e.position); if (Cesium.defined(pickedObject) && pickedObject.id === entity) { // 更新弹窗内容 document.getElementById('title').innerHTML = pick.id.data.title; document.getElementById('state').innerHTML = pick.id.data.state; document.getElementById('info').innerHTML = pick.id.data.info; // 监听场景帧渲染事件,需要判断一下,已经注册过的话就不用再注册了 viewer.scene.postRender.addEventListener(updatePosition); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 取消帧渲染事件监听 viewer.screenSpaceEventHandler.setInputAction(function(e) { viewer.scene.postRender.removeEventListener(updatePosition); }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
Entity知识
Entity 类是 Cesium 中描述和呈现地球上实体对象的核心类。它具有丰富的属性和方法,用于控制和定制地理实体的外观和行为。对 Entity 类进行实例化后,我们就可以得到 Entity 对象;
Entity 对象可以表示各种地理实体,如点、线、面等,并具有位置、方向、模型、标牌、折线、多边形等属性,通过设置这些属性可以实现各种类型的地理可视化;Entity 也是构建各种三维开发应用的核心基础;
entity分类:
| Entity类型 | 特点描述 | 属性示例 | 用途示例 |
|---|---|---|---|
| Point(点) | 在地球表面上显示一个单独的点 | 位置、颜色、像素大小 | 标记特定地理位置,如兴趣点 |
| Billboard(图标) | 使用自定义图像表示,并且总是面向摄像机 | 图像URL、颜色混合模式、像素偏移 | 显示带有图标的地点,如标记建筑物 |
| Polyline(折线) | 连接多个地理位置的线条 | 颜色、宽度、跟随地形 | 展示路径、边界或连接不同地点 |
| Polygon(多边形) | 绘制覆盖地球表面区域的封闭形状 | 填充颜色、边缘颜色和宽度、是否跟随地形 | 表示地理区域,如国家边界 |
| Rectangle(矩形) | 定义由经纬度坐标确定的矩形区域 | 坐标范围、填充材质、边缘样式 | 精确控制经纬度范围的应用场景 |
| Corridor(走廊) | 沿着一系列点创建具有一定宽度的带状区域 | 顶点列表、宽度、高度、材质 | 表示道路、河流等具有宽度的线性特征 |
| Wall(墙) | 从地面延伸至指定高度的垂直墙面 | 顶点列表、顶部和底部高度、材质 | 模拟城市中的建筑物轮廓或其他垂直结构 |
| Ellipse(椭圆) | 在地球上绘制椭圆形区域 | 半径、旋转角度、填充和边框样式 | 标记圆形或椭圆形的兴趣区域 |
Entity示例
const point = new Cesium.Entity({
position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),
point: {
pixelSize: 10,//点像素大小
color: Cesium.Color.RED,//点颜色,不能用rgb等css方法,需要用Cesium.Color
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
});
Primitive知识
在Cesium中,Primitive是一个核心概念,用于高效地渲染大量的地理空间数据。与Entity相比,Primitive提供了更底层、更直接的控制,适用于需要高性能和自定义渲染的应用场景。下面是对Cesium中Primitive的一些简要介绍:
Primitive是Cesium中的一个低级渲染对象,它允许开发者以更高的效率和灵活性来绘制复杂的3D图形。Primitive通常包含几何形状(Geometry)和外观(Appearance),可以用来表示点、线、多边形等。
当需要处理大量数据或实现高度定制化的渲染效果时,Primitive比Entity更加合适。例如,实时渲染大规模地形数据、建筑物模型或其他复杂3D对象。
const primitive = new Cesium.Primitive(
geometryInstances: new Cesium.GeometryInstance(
geometry: new Cesium.EllipseGeometry(
center: Cesium.Cartesian3.fromDegrees(-100.0, 20.0),
semiMinorAxis: 500000.0,
semiMajorAxis: 1000000.0,
rotation: Cesium.Math.PI_OVER_FOUR,
vertexFormat: Cesium.VertexFormat.POSITION_AND_ST
),
),
appearance: new Cesium.EllipsoidSurfaceAppearance(
material: Cesium.Material.fromType('Stripe')
)
);
viewer.scene.primitives.add(primitive);
其主要特性是:
- 几何形状(Geometry)
- 几何形状定义了物体的空间结构,如位置、形状等。Cesium提供了一些内置的几何类型,包括:
RectangleGeometry:矩形区域。PolygonGeometry:多边形。PolylineGeometry:折线。EllipseGeometry:椭圆形。- 自定义几何体:通过实现
Geometry接口,可以创建任意复杂的几何形状。
- 几何形状定义了物体的空间结构,如位置、形状等。Cesium提供了一些内置的几何类型,包括:
- 外观(Appearance)
- 外观决定了几何形状的视觉表现形式,包括材质、颜色、纹理等。常见的外观类型有:
MaterialAppearance:支持使用材质进行渲染。PerInstanceColorAppearance:为每个实例设置不同的颜色。EllipsoidSurfaceAppearance:用于地球表面的渲染。
- 外观决定了几何形状的视觉表现形式,包括材质、颜色、纹理等。常见的外观类型有:
- 性能优化
Primitive通过批量处理数据来减少绘制调用次数,从而提高渲染效率。这对于处理大规模数据集尤为重要。- 支持GPU加速,利用WebGL的强大功能实现高效的图形渲染。
- 灵活性
Primitive允许对渲染过程进行细粒度的控制,比如可以调整着色器代码(Shader Programs),以实现特定的视觉效果。
CZML知识:
CZML:CZML是一种JSON格式的字符串,用于描述与时间有关的动画场景,CZML包含点、线、地标、模型、和其他的一些图形元素,并指明了这些元素如何随时间而变化。某种程度上说, Cesium 和 CZML的关系就像 Google Earth 和 KML。
CZML常见属性:
id:实体的唯一标识符。
name:实体名称。
description:实体的描述信息。
path:定义轨道线的样式;
position:绘制轨道线所需的位置信息,可以是固定值或随时间变化。
model:3D模型配置。
label:标签样式配置。
CZML 的一个典型结构如下:
var czml = [
{
id: 'document',
name: 'CZML Point',
version: '1.0'
},
{
id: 'point 1',
name: 'point',
position: {
cartographicDegrees: [-111.0, 40.0, 0]
},
point: {
color: {
rgba: [255, 255, 255, 255]
},
outlineColor: {
rgba: [255, 0, 0, 255]
},
outlineWidth: 4,
pixelSize: 20
}
},
{
id: 'path',
name: '移动路径',
availability: '2024-12-19T00:00:00Z/2024-12-19T00:10:00Z',
position: {
epoch: '2024-12-19T00:00:00Z',
cartographicDegrees: [0, 116.3914, 39.9075, 100, 300, 116.3925, 39.9085, 100]
},
path: {
material: {
solidColor: { color: { rgba: [0, 255, 0, 255] } }
},
width: 3
}
}
]
加载CZML:
var viewer = new Cesium.Viewer('cesiumContainer');
var dataSourcePromise = Cesium.CzmlDataSource.load(czml);
viewer.dataSources.add(dataSourcePromise);
viewer.zoomTo(dataSourcePromise);
Three
场景(Scene)
场景是Three.js中的一个核心概念。场景代表了一个3D空间,其中包含了所有要渲染的物体。创建一个场景非常简单:
const scene = new THREE.Scene();
相机(Camera)
相机定义了场景中的观察点,决定了哪些部分会被渲染。Three.js提供了多种类型的相机,其中最常用的是透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)。透视相机适用于大多数场景,具有透视投影效果。创建一个透视相机如下所示:
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
其中,fov表示视场角度,aspect表示宽高比,near和far表示近平面和远平面的距离。
渲染器(Renderer)
渲染器负责将场景和相机的信息渲染到屏幕上。Three.js提供了多种渲染器,其中最常用的是WebGL渲染器。创建一个WebGL渲染器如下所示:
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
几何体(Geometry)
几何体定义了3D物体的形状。Three.js内置了许多常用的几何体,如立方体、球体、圆柱体等。创建一个立方体几何体的示例如下:
const geometry = new THREE.BoxGeometry(width, height, depth);
材质(Material)
材质决定了物体的外观,如颜色、纹理、透明度等。Three.js提供了多种材质类型,如基本材质(MeshBasicMaterial)、光照材质(MeshLambertMaterial)、Phong材质(MeshPhongMaterial)等。创建一个绿色基本材质的示例如下:
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
网格(Mesh)
网格是由几何体和材质组成的3D物体,它将几何体的形状和材质的外观组合在一起。创建一个由立方体几何体和绿色基本材质组成的网格如下所示:
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
光源(Light)
光源为场景提供了光照,使物体具有明暗、阴影等效果。Three.js提供了多种类型的光源,如环境光(AmbientLight)、点光源(PointLight)、平行光(DirectionalLight)等。创建一个白色点光源的示例如下:
const light = new THREE.PointLight(0xffffff);
light.position.set(x, y, z);
scene.add(light);
Echarts
echarts概述
百度团队开发的,提供了一些直观,易用的交互方式以便于对展示数据进行挖掘.提取.修正或整合,拥有互动图形用户界面的深度数据可视化工具。echarts所支持的常见图表有:
折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)
雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等

echarts绘制基础折线图
import * as echarts from 'echarts';
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;
option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
};
option && myChart.setOption(option);
常见配置项
| 配置项类别 | 配置项名称 | 描述 | 示例值 |
|---|---|---|---|
| 全局设置 | title |
设置图表标题 | { text: 'ECharts 入门示例' } |
tooltip |
提示框组件,用于显示数据项的具体数值 | { trigger: 'axis' } |
|
legend |
图例组件,展示不同系列的标记、颜色和名字 | { data: ['销量'] } |
|
| 直角坐标系网格 | grid |
直角坐标系内绘图网格 | { left: '3%', right: '4%', bottom: '3%', containLabel: true } |
| X轴/Y轴 | xAxis/yAxis |
坐标轴配置,包括类型、数据等 | { type: 'category', data: ['Mon', 'Tue', 'Wed'] } |
| 数据系列 | series |
数据系列列表,每个元素是一个数据系列的配置和数据 | [ { name: '销量', type: 'bar', data: [5, 20, 36] } ] |
| 图形样式 | itemStyle |
设置图形样式,如颜色、边框色等 | { color: '#c23531' } |
| 数据标签 | label |
设置数据标签的相关属性 | { show: true, position: 'top' } |
| 视觉映射 | visualMap |
视觉映射组件,用于将数据映射到视觉通道 | { min: 0, max: 100, calculable: true } |
| 工具箱 | toolbox |
工具栏,包含导出图片、数据视图、动态类型切换等功能按钮 | { feature: { saveAsImage: {}, dataView: {readOnly: false}, magicType: {type: ['line', 'bar']} } } |
| 区域缩放 | dataZoom |
区域缩放组件,用于区域缩放,支持横向或纵向 | { type: 'slider', start: 10, end: 70 } |
| 时间轴 | timeline |
时间轴组件,用于联动控制多个图表的播放 | { axisType: 'category', autoPlay: true, playInterval: 1000 } |
| 实例方法 | resize |
调整图表大小以适应其容器的新大小 | chart.resize(); |
| 实例方法 | dispose |
销毁图表实例,释放资源 | chart.dispose(); |
性能优化
HTTP方面
减少不必要的请求、防抖、节流、设置缓存、CDN、本地存储
工程化方面
按需加载、chunk分包,代码压缩、css合并,小图片转base64
图片方面
懒加载、图片压缩、精灵图、字体图标、使用缩略图
代码方面
减少全局变量、减少闭包、优化循环,少创建对象
dom方面
减少回流:读取几何属性、改变布局等会引发回流(例如读取offset、clientWidth、激活伪类、改变窗口尺寸等)
减少重绘:当一个元素的外观发生变化,但没有改变布局会引发重绘:(visibility、opacity、颜色、背景、阴影等),js中一条语句尽量设置多个样式、尽量使用class控制样式
Webpack
Webpack概念及主要功能
Webpack是一个前端模块打包工具。它可以将多个模块按照依赖关系进行静态分析,并生成一个或多个打包后的文件。Webpack的主要功能包括:
| 作用 | 说明 |
|---|---|
| 模块打包 | 将项目中的所有模块(JavaScript、CSS、图片等)当作一个整体,通过依赖关系将它们打包成一个或多个静态资源文件 |
| 依赖管理 | Webpack可以分析模块之间的依赖关系,根据配置的入口文件找出所有依赖的模块,并将其整合到打包结果中 |
| 文件转换 | Webpack本身只能处理JavaScript模块,但通过加载器(Loader)的使用,可以将其他类型的文件(如CSS、LESS、图片等)转换为有效的模块,使其能够被打包到最终的结果中 |
| 代码拆分 | Webpack支持将代码拆分成多个模块,按需加载,实现按需加载和提升应用性能 |
| 插件系统 | Webpack提供了丰富的插件系统,可以通过插件实现各种功能的扩展,例如压缩代码、自动生成HTML文件等 |
Webpack的核心概念
Entry(入口):Webpack将从指定的入口文件开始分析和构建依赖关系树。入口可以是单个文件或多个文件,Webpack会根据入口配置找出所有的依赖模块。
Output(输出):指定Webpack打包后的文件输出的路径和文件名。可以通过配置output选项来指定输出文件的路径、名称和格式等。
Loader(加载器):Webpack本身只能处理JavaScript模块,但通过Loader的使用,可以处理其他类型的文件(如CSS、LESS、图片等)。Loader的作用是在模块加载时对其进行转换和处理。
Plugin(插件):插件用于扩展Webpack的功能。它可以在打包的不同阶段执行特定的任务。例如,可以使用插件来压缩代码、拆分代码、生成HTML文件等。插件通过在Webpack配置中引入并实例化,然后将其添加到plugins数组中。
常见的loader工具
| 名称 | 作用 |
|---|---|
| babel-loader | 将ES6+代码转换为ES5语法,以便在旧版本的浏览器中运行 |
style-loader和css-loader |
用于处理CSS文件。css-loader主要负责处理样式文件中的import和url语句,而style-loader将转换后的CSS模块直接注入到HTML页面中 |
file-loader和url-loader |
用于处理图片和其他资源文件。file-loader会为每一个文件生成一个对应的文件,而url-loader将小于设定大小的文件转换为base64编码的URL,减少HTTP请求 |
sass-loader和less-loader |
用于处理Sass和Less预处理器。它们将Sass和Less代码转换为普通的CSS代码 |
| postcss-loader | 用于为CSS代码添加浏览器兼容性前缀,以确保在不同浏览器上的一致性 |
| html-loader | 用于处理HTML文件,将其中的图片等资源转换为Webpack可以识别的模块 |
webpack配置示例
// webpack.config.js
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
port: 3000,
hot: true,
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
docker
使用docker的好处
快速部署服务、实现环境隔离、一个主机运行多个容器、简化部署和迁移、实现软件的跨平台。
docker安装和配置
官方的一键安装方式
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
修改docker配置文件:sudo vim /etc/docker/daemon.json
{
"insecure-registries": ["192.168.10.10:5000"], // 本地仓库地址
"registry-mirrors": [ // 镜像加速地址
"https://docker.m.daocloud.io",
"https://docker.imgdb.de",
"https://docker-0.unsee.tech",
"https://docker.hlmirror.com"
]
}
重启docker
sudo systemctl daemon-reload && sudo systemctl restart docker
docker镜像
docker search nginx 查看注册表中是否有nginx镜像
docker image pull nginx 下载nginx镜像
docker image ls 查看本地镜像
docker image load < redis-img.tar.gz 导入redis镜像
docker image save nginx > nginx.tar.gz 导出nginx镜像
dcker inspect nginx 显示nginx镜像的详细信息
docker image rm nginx 删除镜像
docker push ip/nginx:v1 推送镜像nginx到本地仓库
docker tag nginx nginx:v1 给镜像nginx标记标签v1
docker history nginx 查看镜像nginx的历史构建信息
docker容器
docker run -d redis 后台启动容器
docker ps 查看启动的容器
docker stop/start redis 停止/启动容器
docker exec -it redis bash 登入容器(常用用法)
docker rm -f redis 删除容器
docker rm $(docker ps -aq) 删除全部已退出的容器
dockerfile
Dockerfile大体由四部分组成:指明基础镜像指令:FROM;维护者信息指令:MAINTAINER;镜像操作指令:RUN、EVN、ADD和WORKDIR等;容器启动时的执行指令:CMD、ENTRYPOINT和USER等。
下边是一个Dockerfile的例子
FROM nginx:1.2.7
MAINTAINER <xxx@qq.com>
COPY . /app
WORKDIR /app
RUN nmp install
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]
docker-compose
Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。通过Docker Compose,您可以使用YAML文件来配置应用程序需要的所有服务,并使用一个命令从YAML文件配置中创建并启动所有服务。
# 创建一个docker-compose.yaml文件,内容如下:
version: '3'
services:
mysql:
image: mysql:latest
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:latest
ports:
- "6379:6379"
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpress
REDIS_HOST: redis
depends_on:
- mysql
- redis
volumes: mysql_data:
docker打包流程
编写Dockerfile文件
FROM node:11
ADD . /app
COPY . /app
WORKDIR /app
RUN npm install && npm install -g nodemon
CMD nodemon app.js
构建镜像、推送仓库、运行容器
docker build -t my-node-app:v1 . // 构建docker镜像
docker push my-node-app:v1 // 推送到远程仓库
docker pull my-node-app:v1 // 从远程仓库拉取
docker run -p 9564:9000 --name testProject -v path:/app my-node-app:v1 // 运行容器
nginx
基本配置
server {
listen 80;
server_name example.com;
location / {
root /path/to/your/dist;
index index.html index.htm;
# 用于配合 history 路由模式使用
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://service_api_ip:service_api_port/service_api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
404跳转处理
location / {
root /path/to/your/dist;
index index.html index.htm;
# 用于配合 history 路由模式使用
try_files $uri $uri/ /index.html;
}
反向代理(api转发)
location /api {
proxy_pass http://service_api_ip:service_api_port/service_api/;
proxy_set_header Host $host; # 传递域名
proxy_set_header X-Real-IP $remote_addr; # 传递ip
proxy_set_header X-Scheme $scheme; # 传递协议
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
安全策略
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN";
# 启用浏览器 XSS 保护
add_header X-XSS-Protection "1; mode=block";
# 禁止浏览器 MIME 类型猜测
add_header X-Content-Type-Options "nosniff";
# 控制 Referer 信息传递
add_header Referrer-Policy "strict-origin-when-cross-origin";
# 内容安全策略,允许来自同源的资源
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
其他配置
# 开启gzip压缩
gzip on;
# 监听端口 HTTPS
listen 443 ssl;
# 配置域名证书
ssl_certificate C:\WebServer\Certs\certificate.crt;
ssl_certificate_key C:\WebServer\Certs\private.key;
# 代理连接超时
proxy_connect_timeout 90
#允许客户端请求的最大单文件字节数(文件上传大小限制)
client_max_body_size 10m
Linux
防火墙
# 开启/关闭防火墙
systemctl start firewalld # 启动firewalld服务
systemctl stop firewalld # 停止firewalld服务
systemctl enable firewalld # 启用firewalld开机自启
systemctl disable firewalld # 禁用firewalld开机自启
firewall-cmd --state # 检查防火墙状态
firewall-cmd --reload # 重新加载防火墙配置,修改配置执行此命令修改才会生效
# 查看端口/服务等
firewall-cmd --list-all
# 开启/关闭端口
firewall-cmd --zone=public --add-port=8080/tcp --permanent # 开放端口(--permanent永久开启,否则重启失效)
firewall-cmd --zone=public --remove-port=8080/tcp --permanent # 关闭端口
# 允许/禁止服务
firewall-cmd --zone=public --add-service=http --permanent # 允许HTTP服务
firewall-cmd --zone=public --remove-service=ssh --permanent # 禁止SSH服务
# 允许/禁止特定IP地址的访问
# 添加允许某个IP地址访问所有端口规则
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.43.4" accept' --permanent
# 添加禁止某个IP地址访问所有端口规则
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address=192.168.43.4 drop' --permanent
# 移除允许某个IP地址访问所有端口规则
firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.43.4" accept' --permanent
问题定位
-
使用top指令查看cpu占用的情况
top -d 3 // number代表秒数 默认5秒 刷新一次 top -p 45532 // 指定pid 多个pid以‘逗号’分开,只显示指定pid进程的状态 -
使用free查看内存占用情况
free -m // 以MB为单位显示内存使用情况 free -h // 以人类可读的方式显示内存使用情况 free -t // 以总和的形式查询内存的使用信息 free -s 5 // 周期性的查询内存使用信息,每5秒执行一次命令 -
使用ps指令查看进程状态
ps -ef // 显示所有进程 ps -aux // 显示所有进程(同上) ps -aux | grep nginx // 查看指定进程信息 -
使用kill命令结束进程
kill -9 -PID // 常用方式 SIGKILL(信号9):立即结束进程,不能被捕获或忽略。 SIGTERM(信号15):正常结束进程,可以被捕获或忽略。 SIGSTOP(信号19):暂停进程,不能被捕获、忽略或结束。 SIGCONT(信号18):继续执行被暂停的进程。 SIGINT(信号2):通常是Ctrl+C产生的信号,可以被进程捕获或忽略 -
netstate查看端口占用
netstat -a // 列出所有当前的连接 netstat -l // 只列出当前被监听的端口(可以搭配u或t) netstat -at // 只列出 TCP协议的连接 netstat -au // 只列出 UDP协议的连接 sudo netstat -p // 显示进程信息 sudo netstat -apl | grep 8080 // 搭配grep查看指定端口的占用情况
Service服务管理
Systemd服务相关
sudo systemctl enable clamd@scan.service // 设置开机自启动
sudo systemctl disable clamd@scan.service // 禁用开机自启动
sudo systemctl daemon-reload // 修改配置文件后重新加载
service服务管理
service nginx start // 启动服务
service nginx status // 查看服务状态
service nginx stop // 停止服务
日志管理
# 查看所有日志(默认情况下 ,只保存本次启动的日志)
$ sudo journalctl
# 查看内核日志(不显示应用日志)
$ sudo journalctl -k
# 查看指定时间的日志
$ sudo journalctl --since="2012-10-30 18:17:16"
$ sudo journalctl --since "20 min ago"
$ sudo journalctl --since yesterday
$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$ sudo journalctl --since 09:00 --until "1 hour ago"
# 显示尾部的最新10行日志
$ sudo journalctl -n
# 显示尾部指定行数的日志
$ sudo journalctl -n 20
# 实时滚动显示最新日志
$ sudo journalctl -f
# 查看指定服务的日志
$ sudo journalctl /usr/lib/systemd/systemd
# 查看某个 Unit 的日志
$ sudo journalctl -u nginx.service
$ sudo journalctl -u nginx.service --since today
浙公网安备 33010602011771号