[字节青训营]前端方向Day24 - 前端入门 - 工具篇 - 完结版 | 豆包MarsCode AI刷题

56 阅读13分钟

前端入门 - 工具篇

响应式系统与React

Reacet的历史与应用

  • 前端应用开发,如Facebook, Instagram,Netflix 网页版。
  • 移动原生应用开发(React代码->native代码),如Instagram,Discord,Oculus。
  • 结合 Electron(结合了node),进行桌面应用开发。
  • react three fiber 用来写3D图形的库
React的历史

2010 年 Facebook 在其 php 生态中,引入了 xhp 框架,首次引入了组合式组件的思想,启发了后来的 React 的设计。

(写php的时候可以写一个组件片段(声明式,类似HTML),在别的地方也可以写一个组件片段,然后可以把两个组件片段像两个变量一样拼在一起。声明式的写法。)

2011 年 Jordan Walke 创造了 FaxJS,也就是后来的 React 原型。

image.png

2012 年 在 Facebook 收购 Instagram 后,该 FaxJS 项目在内部得到使用,Jordan Walke 基于 FaxJS 的经验,创造了 React。

2013 年 React 正式开源,在 2013 JSConf 上 Jordan Walke 介绍了这款全新的框架。

image.png

2014年 - 今天 生态大爆发,各种围绕 React 的新工具/新框架开始涌现

React 的设计思路

用原生JS写UI的痛点:

  • 状态(自己声明的变量)更新,UI不会自动更新,需要手动地调用DOM进行更新。
  • 欠缺基本的代码层面的封装和隔离,代码层面没有组件化。
  • UI之间的数据依赖关系(当某些东西改变的时候,其它东西也要跟着改变),需要手动维护,如果依赖链路长,则会遇到"Callback Hell"

image.png

监控系统(响应式系统):监控火灾:当火灾发生之后,要监听到这个事件,当事件发生之后,要做一些响应(报警,疏散人群)

image.png

image.png

对上述组件划分的总结

  • 1.组件是 组件的组合/原子组件
  • 2.组件内拥有状态,外部不可见
  • 3.父组件可将状态传入组件内部(对外暴露的接口,外部可以传进来,内部可以消费)

[当前价格]状态属于谁? 只能属于Root节点!!!

状态上升:状态归属于两个节点向上寻找到最近的祖宗节点。

image.png

思考:

  • 1.React 是单向数据流,还是双向数据流?

    单向数据流,永远只能父组件给子组件传东西。但这并不代表子组件不能改变父组件的状态。

  • 2.如何解决状态不合理上升的问题 ?

  • 3.组件的状态改变后,如何更新 DOM ?

组件设计:

  • 1.组件声明了状态和 UI的映射

    输入几个状态,返回一个UI

  • 2.组件有 Props(外)/State(内) 两种状态,

    组件内部有自己的状态,外部不可见。

    同时外部的父组件可以给子组件传状态。

  • 3.“组件”可由其他组件拼装而成。

组件代码:

  • 1.组件内部拥有私有状态 State。
  • 2.组件接受外部的 Props 状态提供复用性。
  • 3.根据当前的 State/Props,返回一个 UI。

image.png

组件的生命周期:

image.png

React(hooks)的写法

image.png

useEffect: 传入一个函数,和一个数组,数组是状态的数组,称作依赖项,该函数在 mount时,和依赖项被 set 的时候会执行。

  • 有“副作用”的函数,要传入 useEffect来执行。
  • 副作用代表除了单纯的计算之外,还要做其它的一些事情,比如网络请求,更新DOM,localStorage存储数据等。

Hook使用法则

  • 不要在循环,条件或者嵌套函数中调用Hook。

image.png

React 的实现

Problems

  • JSX 不符合 JS 标准语法

image.png

  • 返回的 JSX 发生改变时,如何更新 DOM

    Virtual DOM(虚拟 DOM)

    真实的DOM不是js中的对象,而是一个在浏览器内部维护的状态,只能通过DOM接口修改DOM。

    Virtual DOM 是一种用于和真实 DOM 同步,而在 JS 内存中维护的一个对象,它具有和 DOM 类似的树状结构,并和DOM 可以建立一一对应的关系。

    它赋予了 React 声明式的 API:您告诉 React 希望让 UI是什么状态,React 就确保 DOM 匹配(自动更新)该状态。这使您可以从属性操作、事件处理和手动 DOM 更新这些在构建应用程序时必要的操作中解放出来。

    • 指令式: 需要手动的告诉程序该怎么做

    • 声明式: 发出指令

    • 响应式: 声明式编程的一个类别,当某个状态发生改变时,自动的更新UI,自己响应自己

image.png

    • Heuristic算法

    • 不同类型的元素 替换

      • image span div 整个子树都要被替换
    • 同类型的DOM元素 更新

      • 调用DOM接口的setattribute元素
    • 同类型的组件元素 递归

  • State/Props 更新时,要重新触发 render 函数(就是组件函数本身)

React 状态管理库

会降低组件的复用性,和外部的Store强耦合了。

把所有的节点看成一个大的UI组件,Store是大的UI组件的State。

image.png

哪些东西放在状态管理库:

思考这个状态是被整个APP所拥有的还是被某个组件所拥有的?

字节做的全栈开发:

image.png

import {useModel} from '@modern-js/runtime/model'
// 共享xy状态
const Subcomponent = props =>{
    const [{x,y}] = useModel(countModel);
    return (
        <h1>
            {x} and {y}
        </h1>
    )
}
const [{x,y},{incrementX,incrementY}] = useModel(countModel);
​
<button type="button" onClick={()=>{incrementX()}}> 
    x + 1
</button>
<button type="button" onClick={()=>{incrementY()}}> 
    y + 1
</button>

应用级框架科普

image.png

Vite知识体系

浅谈构建工具

image.png

Vite概要介绍

定位: 新一代前端构建工具

两大组成部分

1.No-bundle 开发服务,

源文件无需打包

2.生产环境

基于 Rollup 的 Bundler

核心特征

1.高性能,dev 启动速度热更新速度非常快!

2.简单易用,开发者体验好

Why Vite:

问题:

缓慢的启动 ->项目编译等待成本高 缓慢的热更新 ->修改代码后不能实时更新

瓶颈: bundle带来的性能开销 JavaScript语言的性能瓶颈(单线程解释性语言)

  • 浏览器原生ESM支持

image.png

  • 基于原生ESM的开发服务优势

image.png

Vite Dev Server底层原理就是type="module"

  • 基于Esbuild的编译性能优化

image.png

  • 内置的web构建能力

image.png

Vite上手实战

1.项目初始化

image.png

npm i -g pnpm
pnpm create vite
vite_project
react
react-ts 
cd vite_project // 切换目录
pnpm install  // 安装依赖
npm run dev // 启动项目

2.接入Sass/Scss & CSS Modules

image.png

pnpm install sass -D
在src下新建一个components/Header/index.tsx
// index.tsx
import React from "react";
​
export function Header(){
    return <div>Header</div>
}
然后在src/App.tsx下引入<Header></Header>
​
// 在components/Header/新建文件index.module.scss
// 把.module.scss结尾的文件当作cssmodule文件来处理
.header{
    color: red;
}
//然后在index.tsx中引入样式
import React from "react";
import styles from './index.module.scss'
export function Header(){
    return <div className={styles.header}>Header</div>
}

3.使用静态资源

react.svg

image.png

4.HMR(Hot Module Replacement)

热更新 + 状态保留

image.png

5.生产环境 Tree Shaking

把代码里面没用的删除掉

// 在src下新建util.ts
export const add = {a:number,b:number}:number => a+b;
export const multi = {a:number,b:number}:number => a*b;
​
// 然后在src/components/Header/index.tsx中使用
import React from "react";
import styles from './index.module.scss'
import {add} from "../../util"
export function Header(){
    return <div className={styles.header}>Header{add(1+2)}</div>
}
​
// build:tsc && vite build
// tsc的编译:为了进行项目的类型检查
// vite build打包// 可在dist/assets下的文件找到打包后的文件
// 没有用到multi,所以multi会被删掉

image.png

优化原理:

1.基于 ESM 的 import/export 语句依赖关系,与运行时状态无关

2.在构建阶段将未使用到的代码进行删除

image.png

Vite

  • 响应迅速
  • 开箱即用

Vite整体架构

image.png

预打包

image.png

单文件编译

image.png

代码压缩

image.png

插件机制(最重要)

image.png

Vite进阶路线

深入双引擎

推荐学习顺序 先了解基本使用,动手尝试各项常用配置; 然后学习其插件开发。

Vite插件开发

  • 抽离核心逻辑
  • 易于拓展

image.png

参考资料:

Vite插件开发文档cn.vitejs.dev/guide/api-p…

复杂度较低的插件:json加载插件github.com/vitejs/vite…

复杂度中等的插件:Esbuild接入插件github.com/vitejs/vite…

复杂度较高的插件:官方React插件

前端必须知道的开发调试知识

PC端

  • Elements

    • styles 动态修改元素和样式

      • 点击 .cls 开启动态修改元素的 class

      • 输入字符串可以动态的给元素添加类名

      • 勾选/取消类名可以动态的查看类名生效效果

      • 点击具体的样式值(字号、颜色、宽度高度等)可以进行编辑,浏览器内容区域实时预览

      • Computed 下点击样式里的箭头可以跳转到 styles面板中的 css 规则

image.png

image.png

  • Console

    控制台,可以在里面去打字,打印出代码里面的日志。

    console.log("Welcome to ByteDance!");
    console.warn('Welcome to ByteDance!');
    console.error('Welcome to ByteDance!');
    console.debug('Welcome to ByteDance!');
    console.info('Welcome to ByteDance!');
    console.log('%s %o,%c%s','hello', { name: 'Tom', age: 18 }, 'font-size:24px;color:red', 'Welcome to ByteDance!');
    ​
    // Corrected goods array
    const goods = [
        {
            name: 'apple',
            count: 300,
            price: 10
        },
        {
            name: 'banana',
            count: 110,
            price: 4
        },
        {
            name: 'orange',
            count: 30,
            price: 7
        }
    ];
    

image.png

image.png

注意:不同类型的值输出的颜色是不一样的。

image.png

  • console.table()

image.png

  • console.dir()

image.png

  • console.time()

  • Sources

    展示项目的源代码

    image.png

    • 第一种调试方法:debugger 断点调试

    image.png

    • 第二种调试方法:

    image.png

    • scope 作用域(闭包)

    • Call Stack 调用堆栈

    image.png

    • XHR/fetch breakpoints XHR/提取断点

      一旦程序发生了网络请求,就会进入断点

    image.png

    • DOM breakpoints

      当HTML中某一个元素发生变化的时候,可以添加一个断点

    压缩后的代码如何调试?

    前端代码天生具有“开源”属性,出于安全考虑,上线之前JavaScript 代码通常会被压缩,压缩后的代码只有一行,整体变得不可阅读。

    开启source-map的方法:devtools: 'source-map'

    • 如果代码出错,点击console中error最右边,就可以跳转到源码。

    • 可以看到错误对应的源码位置,然后去进行修改。

    • 思考题:既然 Source Map 可以映射源码,那压缩后的代码带上 Source Map 上线不就又不安全了吗?

      是的,带上Source Map打包会产生2个文件,其中一个文件是包含源码的。可以把该文件上传到监控平台,然后把该文件从dist里面删掉,这样就可以安全上线了。

  • Network

    image.png

  • Application

清除缓存

image.png

image.png

image.png

FPS

image.png

  • Lighthouse

image.png

移动端

真机调试

image.png

VConsole

image.png

使用代理工具调试

image.png

常用代理工具

  • Charles:适合查看、控制网络请求,分析数据

image.png

  • Fiddler:与 Charles 类似, 适合 windows 平台
  • spy-debugger:远程调试手机页面,抓包
  • Whistle: 基于 Node 实现的跨平台 Web 调试代理工具

Nodejs调试

可以直接使用官方提供的方法

1.结合浏览器

image.png

2.VScode 运行->添加配置->启动调试->添加断点

常用开发调试技巧

线上即时修改 在调试DOM元素或样式的时候经常使用到的一个技巧

(现在更习惯用热更新,这种方法可能就不那么通过了

image.png

利用代理解决开发阶段的跨域问题

image.png

启用本地source map

线上不存在 source Map 时可以使用Charles中的 Map Local网络映射功能来访问本地的 source Map 文件。

  • 应用上线的时候由于我们删除了包含源代码的文件,不过我们本地还是可以再npm run build一下就又有该文件了

image.png

  • 再去访问运行代码,出错之后就可以找到哪里出错了。
  • 线上没有source Map,所以映射到本地,就可以进行访问了。

使用代理工具Mock数据

操作就是,点击Mock数据然后点Map local

image.png

构建Webpack知识体系

为什么要学习Webpack?

  • 理解前端“工程化”概念、工具、目标
  • 一个团队总要有那么几个人熟悉 Webpack,某种程度上可以成为个人的核心竞争力
  • 高阶前端必经之路

目标:

  • 理解 Webpack 的基本用法
  • 通过介绍 Webpack 功能、Loader 与 Plugin 组件设计,建立一个知识体系

什么是Webpack?

image.png

使用Webpack

  • 1.安装依赖->
  • 2.写配置文件->
  • 3.执行编译命令

image.png

1.入口处理 开始读entry文件,启动编译流程

2.依赖解析 从entry文件中开始找到依赖'require' 'import' (import bar from './bar'这就是依赖语句)

3.资源解析 根据module配置,把一些非js资源转成js

4. 第二步第三步都执行完之后,资源合并打包,最终再生成一个JS文件

2找到的新的资源 那么就要进行第3步,所以2,3是递归调用,知道所有资源处理完毕

模块化+一致性

模块化:支持对不同类型的资源都用import,require这些语句去管理,也支持多个资源的合并打包,从而减少http请求数。

image.png

配置文件

“配置”大致分为两类,

  • 流程类:作用于前面说的四个步骤的

image.png

  • 工具类:主流程之外,提供更多工程化能力的配置项

image.png

学习Webpack

eg1.start

image.png

console.log('hello ${bar}')会被编译成1行

image.png

因为mode会被设置成默认的"production",产物会做一个压缩,会简洁很多。

eg2.处理css

image.png

// index.js
import './index.css';
console.log('hello world')
​
​
// index.css
.main{
    font-size: 10px
}
​
// 需要定义一个loader
// 用module定义loader,用的时候更关注rules
module:{
    rules:[{ // 在rules会有一个数组,有test和use2个属性
        test:/.css$/, // 过滤条件,满足test规则的采用rules去处理
        use:['style-loader','css-loader'] // 用什么样的loader去处理满足test条件的文件
    }]
}

最后css会被转译成500多行

image.png

问题:

  • Loader 有什么作用?为什么这里需要用到 css-loader、style-loader
  • 与旧时代 -- 在 HTML 文件中维护 css 相比,这种方式会有什么优劣处?
  • 有没有接触过 Less、Sass、Stylus 这一类 CSS 预编译框架?如何在 Webpack 接入这些工具?

eg3.处理js

接入babel,用于js转译

image.png

// webpack.config.js
module:{
    rules:[{ 
        // 对js文件用babel-loader去处理,同时还有一个options,这个options最终会被传入babel-loader里
        // preset 规则集
        test:/.js$/, 
        use:[{
            loader : 'babel-loader',
            options:{
                presets:[
                    ['@babel/preset-env']
                ]
            }
        }]
    }]
}

image.png

问题:

  • Babel 具体有什么功能?
  • Babel 与 Webpack 分别解决了什么问题?为何两者能协作到一起了?

eg4.处理html

image.png

// index.js
console.log('hello world')
// 把index.js通过<script/>导入index.html
// 在webpack环境下,可以不用写html文件,直接生成。// webpack.config.js
const path = require('path')
// 通过HTMLWebpackPlugin插件自动的生成一个html文件
const HTMLWebpackPlugin = require('html-webpack-plugin')
​
modules.exports = {
    // 没有声明任何loader,直接用new HTMLWebpackPlugin()去调用
    entry : './src/index',
    mode : 'development',
    devtools : false,
    output : {
        filename : '[name].js',
        path : path.join(__dirname, './dist')
    },
    plugins : [new HTMLWebpackPlugin()]
}

image.png

问题:

  • 相比于手工维护 HTML 内容,这种自动生成的方式有什么优缺点?

使用Webpack—工具线

image.png

eg5.HMR: Hot Module Replacement-- 模块热替换

写的代码能够马上呈现在页面上,不需要刷新,直接就能应用新的代码。

还需要一个watch:true会持续监听文件的变化。

image.png

eg5.Tree-Shaking: 树摇,用于删除Dead Code

本质上是用来删除一些没有用到的代码。

开启tree-shaking:

  • mode:production

  • optimization:{

    usedExports:true

    }

image.png

至此,为期接近一个月的青训营结束,不过我的前端生活才正式步入正轨。明确了学习方向,在这一个月的时间里,着实做到了入门。感谢字节跳动提供的机会!!!寒假的青训营我还是会参加。以后在校期间只要有青训营,那么我就肯定不会缺席!!!

之后的时间先复习一下学过的这么多知识,然后尽量写一个复盘的笔记,能够让我以后再看的时候也能立马想到学了什么,怎么用等等。

复盘差不多之后开始做项目,本次项目是一个LLM对话框组件。还是很有意思的,如果能够做出来想必也会很实用,在日后的简历中也是一个亮点!加油!!!