模块化 手写实现webpack

模块化

common.js 的导入导出方法: require \ export 和 module.exports
export 和 module.export
nodejs 内存1.4G -> 2.8G

cjs

在这里插入图片描述在这里插入图片描述

ESModule

主要区别: require属于动态类型:加载执行 同步
esmodul是静态类型:引入时并不会真的去执行文件 而是先分析依赖关系 再再实例化 最后执行 异步
import 是promise的语法糖 沙箱机制
外链 软链 link
在这里插入图片描述
在这里插入图片描述
python php 解释型语言
js 编译型语言

前端三件事:

  1. 设计:
    webpack的设计:
    文件加载:
    1)从什么地方加载,入口文件,以参数形式写入 ’./index.js‘
    2) 文件加载方法名:getFileInfo(file) - file 文件路径 index.js
    分析方法名 parseFile(Filecontent) - Filecontent 文件内容
    加载完成文件,文件上下文,require,import, 写入dist、bundle.js
    3) 收集依赖
    npm install @babel/traverse
    4)收集完依赖,加载所有⽂件
    内部的文件加载情况,依赖关系
    根据依赖关系加载文件
    - parseModules⽅法:
    - 1. 我们⾸先传⼊主模块路径
    - 2. 将获得的模块信息放到temp数组⾥。
    - 3. 外⾯的循坏遍历temp数组,此时的temp数组只有主模块
    - 4. 循环⾥⾯再获得主模块的依赖deps
    - 5. 遍历deps,通过调⽤getModuleInfo将获得的依赖模块信息push到 temp数组⾥。`
    5) 使得引⼊的代码可以被执⾏最终需要处理require和exports
  2. 注释
  3. 测试

npm init 初始化项目得到package.json 和 package-lock.json文件
npm install 安装依赖
npm install @babel/parser 安装解析器babel
npm install @babel/traverse 收集完依赖,怎么加载所有⽂件
@babel/preset-env es6的代码转成es5的(import es7的语法 浏览器不认识 转成es5)
在这里插入图片描述

引⼊的代码可以被执⾏最终需要处理require和exports

babel里的每个stage代表什么内容: 核心原理是什么
能转义和兼容的范围
低阶段兼容范围更广
高阶段能兼容最新的语法
低阶段包含高阶段

use strict: 严格模式
作用:避免js灵活性造成的问题
用法:文件开头标识 use strict
不能干的事:严格使用js的语法

  1. 全局this
  2. 变量重复定义:为了避免掉js的灵活性造成的问题 避免歧义
  3. eval函数 string变成函数去执行的情况
    在这里插入图片描述

webpack 原生加载器能加载哪些文件: js 和 json
webpack不具备这些功能 通过插件完成

手写实现webpack

webpack的核心概念

1. sourcemap 
2. 文件指纹技术
3. babel 与 AST
4. TreeShaking 
5. 优化
    - 构建速度
    - 提高页面性能
6. 原理
    - webpack
    - plugin
    - loader
7. 核心配置
    - entry: 编译入口,webpack编译的起点
    - Compiler: 编译管理器, webpack启动后会创建compiler对象,知道结束退出
    - compilation: 单次编辑过程的管理器 
    - dependence: 依赖对象 webpack基于该类型记录模块间依赖关系 
    - Module: 内部资源都以module形式存在 所有关于资源的操作,转译,合并都是以module为单位进行的
    - Chunk:百年已完成准备输出是 webpack会将module按照特定的规则组织称一个个chunk 跟最终输出一一对应 
    - Loader: 资源内容转换器 
    - Plugin: webpack构建过程中,会在特定的时机⼴播对应的事件,插件监听这些事件,在特定时间点介⼊编译过程

在这里插入图片描述
在代码里debug
在这里插入图片描述
vscode里debug

  1. 执行完 按语句执行 单步调试:进入到语句里去 单步跳出 刷新 暂停
  2. 代码里写 debugger然后启动
    在这里插入图片描述

手写实现webpack 理解原理完整代码

//  src下创建 add.js⽂件和minus.js⽂件, 在index.js中引⼊,再将index.js⽂件引⼊index.html
// add.js
export default ( a, b ) => {
    return a + b
}
// minus.js
export const minus = ( a, b ) => {
    return a - b
}
// index.js
import add from './add.js'
import { minus } from './minus.js'
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script src="./src/index.js" type="module"></script>
</body>
</html>

// 创建bundle.js文件
// 获取主入口文件
// 解决内部文件循环引用的问题  npm install @babel/parser 解析器
// 收集依赖
// 根据收集的依赖关系 加载所有文件
// 执行加载的文件:浏览器处理不了es67的语法 require、import需要被处理

const fs = require('fs')
const path = require('path')
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const babel = require('@babel/core')
const getmoduleInfo = (file) => {
    // 读取文件
    const body = fs.readFileSync(file, 'UTF-8')
    const ast = parsesr.parse(body, {
        sourceType: 'module' // 表示我们要解析的是ES模块
    })
    const deps = {} 
    // 
    traverse(ast, {
        // 处理路径
        ImportDeclaration({node}){
            const dirname = path.dirname(file)
            const abspath = "./" + path.join(dirname, node.source.value)
        }
    })
    // 转成ast树
     const { code } = babel.transformFromAst(ast, null,{
         presets: ["@babel/preset-env"]
     })
     const moduleInfo = { file, deps, code}
     return moduleInfo
}

// 解析模块
const parseModules = (file) => {
    // 入口文件
    const entry = getModuleInfo(file)
    const temp = [entry]
    const depsGraph = {}
    for(let i=0;i<temp.length;i++>){
        const deps = temp[i].deps
        if(deps){
            for(const key in deps){
                if(deps.hasOwnProperty(key)){
                    temp.push(getModuleInfo(deps[key]))
                }
            }
        }
    }
    temp.forEach(moduleInfo => {
        depsGraph[moduleInfo.file] = {
            deps: moduleInfo.deps,
            code: moduleInfo.code,
        }
    })
}

// 生成最终bundle文件
const bundle = (file) => {
    const depswGraph = JSON.stringify(parseModules(file))
    return `
        (
            function(graph){
                function require(file) {
                    function absRequire(relPath){
                        return require(graph[file].deps[realPath])
                    }
                    var exports = {}
                    (function (require,exports,code){
                        eval(code)
                    })(absRequire, exportsgraph[file].code)
                    return exports
                }
                require('$file')
            }
        )($depsGraph)
    `
}

const content = bundle('./src/index.js')
// 写入到dist目录下
fs.mkdirSync('./dist')
fs.writeFileSync('./dist/bundle.js',content)

webpack5.0优化

  1. 增加持久化存储能力,提升构建性能(核心)
  2. 提升算法能力来改进长期缓存(降低产物缓存资源的失效率)
  3. 提升treeshaking的能力未降低产物大小和代码生成逻辑
  4. 提升web平台的兼容性能力
  5. 清除了内部结构中在webpack4没有重大更新二引入的一些新特性时留下来的一些奇怪的state
  6. 引入一些重大的变更为未来的一些特性做准备,使得能长期稳定在webpack版本上
    在这里插入图片描述
    如何优化
    在这里插入图片描述

vite

rollup: 编译工具
esbuilder:go语言
为什么vite在开发时用 esbuild, 生产环境用打包 rollup

  1. esbuild不支持es5 不会降级
  2. 不支持render
  3. 不支持split chunk
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以把一些包放到npm上
    CICD: shell 的命令

控制并发请求数量

// 并发控制: 10条数据 控制请求的数量不大于三条 
    request(url, maxNum){
      return new Promise(resolve,reject=>{
        if(urls.length){
          resolve([])
          return
        }
        const result= []
        let index = 0 // 下一个请求的下标
        let count = 0 // 当前请求完成的数量
        // 发送请求
        async function request(){
          if(index === urls.length){
            // 当前下标等于最后一个 结束
            return 
          }
          const i = index 
          // 保存序号 使result和urls对应
          const url = urls[index]
          index ++ 
          console.log(url)
          try {
            const resp = await fetch(url)
            result[i]=resp
          } catch (err){
            result[i] = err
          } finally {
            // 判断所有请求是否都完成了
            if(count === urls.length) {
              resolve(result)
            }
            request()
          }
        }
        // maxNum 和 urls。length去最小进行调用
        const times = Math.min(maxNum, urls.length)
        for(let i=0;i<times.length;i++){
          request()
        }
      })
    },
    requestSum(){
    }
  },

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/572375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql事故复盘: 单行字节最大阈值65535字节(原创)

背景 记得还在银行做开发&#xff0c;投产上线时&#xff0c;项目发版前&#xff0c;要提DDL的sql工单&#xff0c;mysql加1个字段&#xff0c;因为这张表为下游数据入湖入仓用的&#xff0c;长度较大。在测试库加字段没问题&#xff0c;但生产库字段加不上。 先说结论 投产…

[前端]NVM管理器安装、nodejs、npm、yarn配置

NVM管理器安装、nodejs、npm、yarn配置 NVM管理器安装 nvm(Node.js version manager) 是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 nvm下载地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 1.全部…

手撕sql面试题:根据分数进行排名,不使用窗口函数

分享一道面试题&#xff1a; 有一个分数表id 是该表的主键。该表的每一行都包含了一场考试的分数。Score 是一个有两位小数点的浮点值。 以下是表结构和数据&#xff1a; Create table Scores ( id int(11) NOT NULL AUTO_INCREMENT, score DECIMAL(3,2), PRIMARY KEY…

Linux shell编程学习笔记47:lsof命令

0 前言 今天国产电脑提示磁盘空间已耗尽&#xff0c;使用用df命令检查文件系统情况&#xff0c;发现/dev/sda2已使用100%。 Linux shell编程学习笔记39&#xff1a;df命令https://blog.csdn.net/Purpleendurer/article/details/135577571于是开始清理磁盘空间。 第一步是查看…

LeetCode_链表的回文结构

✨✨所属专栏&#xff1a;LeetCode刷题专栏✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 题目描述&#xff1a; 对于一个链表&#xff0c;请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法&#xff0c;判断其是否为回文结构。给定一个链表的头指针A&#xff0c;请返回一个bo…

【telnet 命令安装】centos8 linux下安装telnet命令

在CentOS 8上安装Telnet服务&#xff0c;您需要分别安装Telnet客户端和服务器端。以下是安装步骤的概述&#xff1a; 检查是否已安装Telnet&#xff1a; 您可以使用rpm命令来检查系统是否已经安装了Telnet客户端或服务器端。例如&#xff1a; rpm -qa | grep telnet-client rpm…

标准 数字化

政策法规&#xff1a; 标准化建设相关政策&#xff0c;包括《国家标准化发展纲要》&#xff0c;《重庆市的标准化条例》 标准数字化转型路线&#xff1a;标准数字化转型的白皮书、发展跟踪报告之类 相关文献&#xff1a;标准数字化转型发展现状与工作路线(大多是电力方面)、数…

uni-app canvas 签名

调用方法 import Signature from "/components/signature.vue" const base64Img ref() //监听getSignImg uni.$on(getSignImg, ({ base64, path }) > {base64Img.value base64//console.log(签名base64, path >, base64, path) //拿到的图片数据// 之后取消…

基于51单片机的矩阵按键扫描的proteus仿真

文章目录 一、按键按键按键消抖 二、独立按键仿真图仿真程序 三、矩阵按键仿真图仿真程序 四、总结 一、按键 按键 按键通常指的是电子设备上的一种输入装置&#xff0c;用于在按下时发送信号&#xff0c;以便设备执行相应的操作。按键可以分为独立按键和矩阵按键两种类型。 …

无人机GB42590接收端 +接收端模组,同时支持2.4G与5.8G双频

严格按照GB42590的协议开发的发射端&#xff0c;通过串口和模块通讯&#xff0c;默认波特率 921600。 http://www.doit.am/深圳四博智联科技有限公司https://shenzhendoit.taobao.com/category-1734422372.htm?spma1z10.1-c-s.0.0.560c74d77eT01G&searchy&catNameGB4…

Qt开发(二)打包发布

注意qt6生成的exe不能再win7&#xff08;包含win7&#xff09;以下运行 1、编译程序 编译程序不演示 2、找到exe文件 在这个路径下找到该exe文件 3、打包 新建一个文件夹 将exe放在该文件夹下除了exe开始这里面没有其他文件 找到安装目录下 在cmd中运行 把这个文件和编…

【Java】文件大小转换工具类(B,KB,MB,G,TB,PB)

说明 使用方法&#xff1a;FileMemoryUtil.prettyByteSize(35871)&#xff0c;参数为字节个数 返回结果&#xff1a;保留一位小数的自适应结果&#xff08;例如&#xff1a;4.1KB&#xff09;。可以留意在浏览器上下载的文件&#xff0c;会根据文件大小展示不同的单位&#xff…

Docker创建redis容器

Docker运行Redis 一&#xff1a;Docker安装Redis docker search redis二&#xff1a;Docker拉取镜像 下面两个命令看自己的需求 docker pull <镜像名称>&#xff1a;<版本号> #需要自己清楚自己需要什么般本的redisdocker pull redis #这个命令会自动下载最新…

C语言入门课程学习笔记3

C语言入门课程学习笔记3 第12课 - if 语句编程练习第13课 - switch 多分支选择语句第14课 - 程序中的循环结构第15课 - while 语句编程练习第16课 - do...while 与 for第17课 - break 与 continue 本文学习自狄泰软件学院 唐佐林老师的 C语言入门课程&#xff0c;图片全部来源于…

BUUCTF-Misc21

[GXYCTF2019]SXMgdGhpcyBiYXNlPw1 1.打开附件 是一个文本文档 里面有很多字符串 2.PuzzleSolver 用PuzzleSolver工具进行多组base64解码 3.得到flag 间谍启示录1 1.打开附件 是一个.iso文件 2.foremost 用foremost 分离文件 查看分离的文件 发现一个压缩包 3.运行 解压之…

Python | Leetcode Python题解之第47题全排列II

题目&#xff1a; 题解&#xff1a; class Solution:def permuteUnique(self, nums: List[int]) -> List[List[int]]:def dfs(x):if x len(nums) - 1:res.append(list(nums)) # 添加排列方案returndic set()for i in range(x, len(nums)):if nums[i] in dic: continue …

历史遗留问题-Oracle 19c RAC 安装时节点连接性问题

测试服务器的二节点数据库宕掉了&#xff0c;原因不明&#xff0c;需要产环境重新安装。我想上次在自己虚拟机安装实验过一次&#xff0c;应该一天能搞定&#xff0c;事实证明&#xff0c;你永远有学不完的bug&#xff01;&#xff01;&#xff01;&#xff01; 首先查看一下系…

算法基础:并查集详解

并查集 并查集&#xff0c;在一些有N个元素的集合应用问题中&#xff0c;我们通常是在开始时让每个元素构成一个单元素的集合&#xff0c;然后按一定顺序将属于同一组的元素所在的集合合并&#xff0c;其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学…

Web前端开发之HTML_2

HTML5简介与基础骨架标题标签标签之段落、换行、水平线标签之图片标签之超文本链接标签之文本列表标签之有序列表列表标签之无序列表 1. HTML5简介与基础骨架 1.1 HTML5简介 HTML5是用来描述网页的一种语言&#xff0c;被称为超文本标记语言。用HTML5编写的文件&#xff0c;后…

伴游平台搭建重点,会用到哪些三方服务?

伴游平台搭建的重点在于确保用户的安全与体验&#xff0c;提供便捷的服务&#xff0c;同时维护平台的稳定运营。在搭建过程中&#xff0c;可能会用到以下三方服务&#xff1a; 身份验证与背景调查服务&#xff1a;由于伴游服务涉及到用户的个人安全和信任问题&#xff0c;因此需…
最新文章