模块化 手写实现webpack

news2025/1/12 3:45:19

模块化

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.coloradmin.cn/o/1623908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle 21 C 安装详细操作手册,并配置客户端连接

Oracle 21 C 安装详细操作手册 Win 11 Oracle 21C 下载&#xff1a; Database Software Downloads | Oracle 中国 云盘共享 链接&#xff1a;https://pan.baidu.com/s/12XCilnFYyLFnSVoU_ShaSA 提取码&#xff1a;nfwc Oracle 21C 配置与登陆&#xff1a; 开始菜单 NetMa…

一线实战,一次底层超融合故障导致的Oracle异常恢复

背景概述 某客户数据由于底层超融合故障导致数据库产生有大量的坏块&#xff0c;最终导致数据库宕机&#xff0c;通过数据抢救&#xff0c;恢复了全部的数据。下面是详细的故障分析诊断过程&#xff0c;以及详细的解决方案描述&#xff1a; 故障现象 数据库宕机之后&#xff0c…

重要!!!涉及huggingface和kaggle的深度学习各种(文本图像视频音频)任务及其对应模型和案例代码总结

可以到hugging face官网&#xff0c;里面有对应的各种学习任务&#xff0c;数据集以及代码和预训练模型也可以到kaggle官网&#xff0c;里面有各种模型以及代码、数据集等。特色优势是&#xff1a;里面对应的数据集和模型都会有超过3个的代码&#xff0c;是用户发布的。 https…

如何批量跟踪京东物流信息

随着电商行业的快速发展&#xff0c;快递业务日益繁忙&#xff0c;无论是商家还是消费者&#xff0c;都需要一种高效、便捷的快递查询工具。快递批量查询高手软件应运而生&#xff0c;以其强大的功能和便捷的操作体验&#xff0c;赢得了广大电商、微商精英们的青睐。 快递批量…

4.25 C高级

思维导图 作业 2.输入两个数&#xff0c;实现两个数的排序 3.输入一个数&#xff0c;计算是否是水仙花 if ((g*g*gs*s*sb*b*bnum)) then echo YES else echo no fi 4.输入一个成绩实现登记判断 90-100A 80-89B 70-79C 60-69D 0-59E

第二证券|光通信概念拉升,吴通控股、胜蓝股份涨停,新易盛等大涨

光通信概念24日盘中强势拉升&#xff0c;截至发稿&#xff0c;吴通控股、胜蓝股份“20cm”涨停&#xff0c;新易盛涨超10%&#xff0c;四川九洲亦涨停&#xff0c;源杰科技、铭普光磁、立昂技能等涨超5%。 吴通控股昨日晚间披露的一季度报告显示&#xff0c;公司完成营业收入1…

CTF网络安全大赛详情

网络安全已成为现代社会的一个关键挑战&#xff0c;随着互联网技术的飞速发展&#xff0c;从个人隐私保护到国家安全&#xff0c;网络安全的重要性日益突显。为了应对这一挑战&#xff0c;CTF&#xff08;Capture The Flag&#xff0c;中文&#xff1a;夺旗赛&#xff09;应运而…

Clickhouse离线安装教程

https://blog.51cto.com/u_15060531/4174350 1. 前置 1.1 检查服务器架构 服务器&#xff1a;Centos7.X 需要确保是否x86_64处理器构架、Linux并且支持SSE 4.2指令集 grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 …

java-spring 06 图灵 getBean方法和 doGetBean方法

01.一般的流程是&#xff0c;这里是从上一章的preInstantiateSingleton方法顺序过来的。 getBean() -> doGetBean() -> createBean() -> doCreateBean() -> createBeanInstance() -> populateBean() -> initializeBean() 02.getBean方法&#xff0c;一般就…

网络安全中的加密与解密技术:全面指南及实验

引言 在当今数字时代&#xff0c;加密技术是保护数据安全的重要工具。从个人通讯到企业数据保护&#xff0c;加密帮助确保信息在存储和传输过程中的机密性和完整性。本文旨在全面介绍加密和解密的原理、常见算法以及实验&#xff0c;以帮助读者深入理解其在网络安全中的应用。…

自然资源调查监测评价系统:守护绿色地球的先锋

随着人类对自然资源的日益依赖&#xff0c;如何合理、可持续地利用这些资源成为了全球关注的焦点。自然资源调查监测评价系统&#xff0c;作为守护绿色地球的重要工具&#xff0c;正发挥着越来越重要的作用。本文将带您了解这一系统的内涵、功能及其在现代社会中的意义。一、自…

【SpringBoot】00 Maven配置及创建项目

一、Maven配置 1、下载Maven 进入官网下载&#xff1a;Maven – Welcome to Apache MavenMaven – Download Apache Maven 本文以最新版为例&#xff0c;可按需选择版本 Maven – Welcome to Apache Maven 2、解压下载好的安装包 将安装包解压到自己设置的空文件夹中 3、…

Pytorch学习之路 - CNN

目录 理论预热 实践 构建卷积神经网络 卷积网络模块构建 实战&#xff1a;基于经典网络架构训练图像分类模型 数据预处理部分&#xff1a; 网络模块设置&#xff1a; 网络模型保存与测试 实践 制作好数据源&#xff1a; 图片 标签 展示下数据 加载models中提供的模…

基于Spingboot+vue协同过滤音乐推荐管理系统

项目演示视频效果&#xff1a; 基于Spingbootvue协同过滤音乐推荐管理系统 基于Spingbootvue协同过滤音乐推荐管理系统 1、项目介绍 基于Springboot的音乐播放管理系统总共两个角色&#xff0c;用户和管理员。用户使用前端前台界面&#xff0c;管理员使用前端后台界面。 有推荐…

【A-025】基于SSH的房屋中介管理系统(含论文)

【A-025】基于SSH的房屋中介管理系统&#xff08;含论文&#xff09; 开发环境&#xff1a; Jdk7(8)Tomcat7(8)MySQLIntelliJ IDEA(Eclipse) 数据库&#xff1a; MySQL 技术&#xff1a; SpringStruts2HiberanteJquery 适用于&#xff1a; 课程设计&#xff0c;毕业设计&am…

python课后习题四

题目&#xff1a; 1. 2. 解题过程&#xff1a; 1. 单独创建一个MyTriangle模块 def isvalid(side1, side2, side3):return area(side1, side2, side3)def area(side1, side2, side3):if side1 side2 < side3 or side3 side2 < side1 or side3 side1 < side2:pr…

Spring Boot 如何实现缓存预热

Spring Boot 实现缓存预热 1、使用启动监听事件实现缓存预热。2、使用 PostConstruct 注解实现缓存预热。3、使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热。4、通过实现 InitializingBean 接口&#xff0c;并重写 afterPropertiesSet 方法实现缓存预热。 1、使用…

使用逆滤波算法deconvwnr恢复图像回复图像时,产生了很多横竖条纹。解决办法

使用逆滤波算法deconvwnr恢复图像回复图像时&#xff0c;产生了很多横竖条纹。解决办法 原来的代码 % 清除工作空间并关闭所有图形窗口 clear; clc; close all;% 读取原始图像 original_image imread(pic3.jpg);% 显示原始图像 subplot(131); imshow(original_image); title…

(mac)Prometheus监控之Node_exporter(CPU、内存、磁盘、网络等)

完整步骤 1.启动 Prometheus 普罗米修斯 prometheus --config.file/usr/local/etc/prometheus.yml 浏览器访问 http://localhost:9090/targets 2.启动Node_exporter node_exporter 访问&#xff1a;http://localhost:9100 3.启动grafana brew services start grafana 访问…

FlashSpeech、ID-Animator、TalkingGaussian、FlowMap、CutDiffusion

本文首发于公众号&#xff1a;机器感知 FlashSpeech、ID-Animator、TalkingGaussian、FlowMap、CutDiffusion Gradient Guidance for Diffusion Models: An Optimization Perspective Diffusion models have demonstrated empirical successes in various applications and ca…