走近Webpack 23-11-24 11:41 3125 13031 juejin.cn 为什么需要webpack? 在回答这个问题之前,我们先看个例子 xml复制代码html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> head> <body> <div id="parent">parentdiv> <script src="./parent.js">script> <script src="./createChild.js">script> <script src="./setChildColor.js">script> <script src="./setChildBorder.js">script> body> html> 浏览器打开,显示结果: 这个例子很简单,先有一个div,叫parent,后面又生成了一个div,叫child parent.js,用于给parent加上 宽、高 、边框 createChild.js, 用于创建child setChildColor.js, 用于设置字体颜色 setChildBorder.js 用于设置边框 ini复制代码// parent.js const addParentStyle = () => { const dom = document.getElementById('parent'); dom.style.width = '100px'; dom.style.height = '100px'; dom.style.border = "1px solid black"; } addParentStyle(); js复制代码// createChild.js const insertContent = () => { const dom = document.getElementById('parent'); const child = document.createElement('div'); child.innerHTML = "child"; child.setAttribute('id', 'child'); dom.appendChild(child) } insertContent(); js复制代码// setChildColor.js const insertContent2 = () => { const dom = document.getElementById('child'); dom.style.color = "red"; } insertContent2(); js复制代码// setChildBorder.js const insertContent3 = () => { const dom = document.getElementById('child'); dom.style.border = "1px solid black"; } insertContent3(); 注意,createChild.js与setChildColor.js、setChildBorder.js加载顺序不能错 现在要为child,增加10个子节点,grandson1, grandson2...grandson10,重复跟child一样的操作,设置颜色和边框 xml复制代码html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> head> <body> <div id="parent">div> <script src="./createChild.js">script> <script src="./setChildColor.js">script> <script src="./setChildBorder.js">script> <script src="./createGrandson1.js">script> <script src="./setGrandson1Color.js">script> <script src="./setGrandson1Border.js">script> <script src="./createGrandson2.js">script> <script src="./setGrandson2Color.js">script> <script src="./setGrandson2Border.js">script> // ... <script src="./createGrandson10.js">script> <script src="./setGrandson10Color.js">script> <script src="./setGrandson10Border.js">script> body> html> 这个时候问题来了: 我们需要手动维护js加载顺序 createChild.js一定要在setChildColor.js等之前 文件一多,命名就容易冲突,比如: createChild.js里有个insertContent方法,setChildColor.js、setChildBorder.js只能改成insertContent2,insertContent3 一个js,就是一次请求,增大网络开销 重写例子(webpack) 现在我们用webpack重写上面例子,看看有什么不一样 准备工作 webpack 是基于node,为了便于开发,再安装一个IDE工具vscode(也可以使用自己熟悉的) node安装 vscode安装 ruby复制代码$ node -v v16.16.0 # node安装,会自带一个包管理器npm $ npm -v 8.11.0 初始化webpack项目 项目结构 初始化目录webpack-demo,安装webpack yaml复制代码 $ mkdir webpack-demo && cd webpack-demo # 初始化项目 $ npm init -y # 安装webpack核心包及命令工具 $ npm i webpack webpack-cli # webpack版本 $ webpack -v System: OS: macOS 12.6 CPU: (8) x64 Apple M1 Memory: 25.01 MB / 16.00 GB Binaries: Node: 16.16.0 - /usr/local/bin/node Yarn: 1.22.5 - ~/.yarn/bin/yarn npm: 8.11.0 - /usr/local/bin/npm Browsers: Chrome: 119.0.6045.123 Safari: 15.6.1 Global Packages: webpack-cli: 5.0.1 webpack: 5.75.0 新建webpack配置文件 lua复制代码// webpack.config.js const path = require('path'); module.exports = { entry: './index.js', output: { path: path.resolve(__dirname, './dist'), filename: 'bundle.js' } } 增加webapck打包命令: "build": "webpack" json复制代码# package.json { "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "webpack": "^5.89.0", "webpack-cli": "^5.1.4" } } 新建index.js, 引入parent.js、createChild.js、setChildColor.js、setChildBorder.js js复制代码 import { insertContent as setChildColor } from './setChildColor'; import { insertContent as setChildBorder } from './setChildBorder'; import { addParentStyle } from './parent'; import { insertContent as createChild }from './createChild'; addParentStyle(); createChild(); setChildColor(); setChildBorder(); 新建 index.html, 引入 html复制代码html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> head> <body> <div id="parent">parentdiv> <script src="./dist/bundle.js">script> body> html> 执行打包命令 js复制代码npm run build 浏览器打打开index.html 结果与之前例子一样 对比 回头看在webpack例子中的index.js parent.js、createChild.js、setChildColor.js、setChildBorder.js,引入顺序是打乱的 createChild.js、setChildColor.js、setChildBorder.js,文件中方法名可以重复 减少了js的请求,都打包进了bundle.js文件中 尾声 上面webpack例子,并没有引入css,其实webpack本身也不支持,在不进行额外配置时,自身只支持js及json文件的处理。 要处理非js文件,比如html、css、图片、字体等,就得使用对应的loader,这也是webpack强大之处。 在后面webpack的分享中,我会用简单的例子,来记录我对webpack的理解。 欢迎同样感兴趣的程序猿(媴),在评论区分享自己的理解和总结。 PS:世界这么大,何时才能躺平┑( ̄。。 ̄)┍\color{blue}{PS:世界这么大,何时才能躺平 ┑( ̄。。 ̄)┍}PS:世界这么大,何时才能躺平┑( ̄。。 ̄)┍ id="article_content" class="article_content clearfix" style="height: 2000px; overflow: hidden;"> id="content_views" class="markdown_views prism-atom-one-dark"> class="toc"> 目录 1、前言2、FT601芯片解读和时序分析FT601功能和硬件电路FT601读时序解读FT601写时序解读 3、我这儿的 FT601 USB3.0通信方案4、详细设计方案5、vivado工程详解6、上板调试验证7、福利:工程代码的获取 1、前言 目前USB3.0的实现方案很多,但就简单好用的角度而言,FT601应该是最佳方案,因为它电路设计简单,操作时序简单,软件驱动简单,官方甚至提供了包括FPGA驱动在内的丰富的驱动源码和测试软件; 本设计用FPGA驱动FT601芯片实现USB3.0数据通信,使用同步245模式通信,提供vivado工程源码,用笔记本电脑模拟HDMI摄像头,HDMI视频输入到FPGA开发板板载的ADV7611解码芯片,将HDMI视频解码为RGB视频,FPGA将RGB视频数据经过图像三帧缓存至DDR3后读出,图像给到FT601发送出去,PC机读取FT601发来的视频,并用QT上位机接收视频并显示出来; 本设计完全可以模拟和实现USB3.0相机的功能;代码编译通过后上板调试验证,可直接项目移植,适用于在校学生做毕业设计、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的USB3.0通信和图像传输领域; 提供完整的、跑通的工程源码和技术支持; 工程源码和技术支持的获取方式以及上板调试的演示视频放在了文章末尾,请耐心看到最后; 2、FT601芯片解读和时序分析 FT601功能和硬件电路 FT600/601Q 的技术参数如下: FT600&601Q 芯片是 FT 最新推出的 USB3.0 to FIFO interface IC,实现 USB3.0 与 16/32bit 并行 IO 接口之间的数据传输。 整个 USB 通信协议全部由芯片驱动自行完成,开发者无须考虑 USB 底层固件的编程。 兼容支持 USB3.0(5Gbps),向下兼容 USB2.0(480Mbps and 12Mbps)传输。 高达 8 个可配置 Endpoint. >>支持 2 种 FIFO 传输协议,最大传输可达 400MB/s。 芯片内部有 16K 字节的缓冲区,可以进行数据的大吞吐量操作。 支持远程唤醒功能。 芯片支持多种 IO 电压:1.8V,2.5V.3.3V。 通过 16bit D[O:15]或 32bit D[0:31]并行数据线和读写状态/控制线 RXF、TXE、RD、WR,加上时钟 CLK,使 能 OE 信号线就可实现与 CPU/FPGA 的数据交换。 该芯片内部集成 1.0V LDO,可提供给芯片核心部分使用。 工业级芯片,工作温度范围-40 to 85℃。 芯片框架如下: 外围电路设计参考如下: FT600/601Q 支持的多种传输模式,其中 245 Synchronous FIFO 模式和 Multi-Channel FIFO 模式是我们最常用的模式。我们这里介绍的 demo 以 245 Synchronous FIFO 模式为例;传输模式通过GPIO引脚高低电平配置,配置真值表如下: FT601读时序解读 245 Synchronous FIFO 模式读时序如下: RXF_N为读数据状态信号,RXF_N为低电平期间FPGA可以读取FT601数据; 检测到RXF_N低电平后,拉低OE_N和RD_N,然后开始读数据; 检测到RXF_N高电平后,拉高OE_N和RD_N,然后退出读数据状态; FT601写时序解读 245 Synchronous FIFO 模式写时序如下: TXF_N为读数据状态信号,RXF_N为低电平期间FPGA向FT601写入数据; 检测到TXF_N低电平后,拉低WR_N,然后开始向FT601写入数据; 检测到TXF_N高电平后,拉高WR_N,然后退出写数据状态; 3、我这儿的 FT601 USB3.0通信方案 我这儿现有的FPGA基于FT601和FT602的USB3.0通信方案主要有简单的测速方案、图像传输方案,图像传输方案包括简单的彩条传输采集、OV5640摄像头传输采集、HDMI视频采集,HDMI视频采集抓拍、USB3.0 UVC视频等等,所有工方案均包括FPGA工程和QT上位机源码;感兴趣的可以去我的FT601 USB3.0通信专栏阅读,专栏地址如下: https://blog.csdn.net/qq_41667729/category_12339160.html?spm=1001.2014.3001.5482 4、详细设计方案 详细设计方案框图如下: HDMI视频输入和采集: 用笔记本电脑模拟HDMI摄像头,HDMI视频输入到FPGA开发板板载的ADV7611解码芯片,将HDMI视频解码为RGB视频,ADV7611解码芯片需要i2c配置才能使用,例程里提供了纯verilog代码的i2c配置; FDMA图像缓存: FDMA图像三帧缓存,经常看我文章的兄弟都知道,这是我惯用的图像缓存套路,它由FDMA控制器和FDMA构成,作用是将输入的视频缓存到DDR3里做三帧缓存后再读出来,目的是使得图像数据的输入输出跨时钟域读写,输出图像平稳无撕裂等现象;关于FDMA的详细设计说明,请参考我之前的文章:点击直接前往 FT601 模块: 就是FT601的verilog驱动代码,根据FT601芯片读写时序实现接口对接,这里很简单;关于FT601驱动的详细设计说明,请参考我之前的文章:点击直接前往 FT601 驱动: 这是官方给的FT601 驱动,文件已包含在了我提供的资料包里; QT上位机: 基于c++的QT,调用官方API,实现USB3.0接口的视频数据实时采集并显示,我提供的资料包里有QT上位机软件和QT源码,做嵌入式软件开发的兄弟可以拿去参考; 5、vivado工程详解 开发板FPGA型号:xc7k325tffg900-2; 开发环境:vivado2022.2; 输入:HDMI; 输出:FT601–USB3.0接口; 应用:模拟和实现USB3.0相机的功能; 工程Block Design如下: 综合后的工程代码架构如下: 综合编译完成后的FPGA资源消耗和功耗预估如下: 6、上板调试验证 先连接板子和电脑,然后打开QT上位机软件,资料包里的目录如下: QT接收结果: 7、福利:工程代码的获取 福利:工程代码的获取 代码太大,无法邮箱发送,以某度网盘链接方式发送, 资料获取方式1:私,或者文章末尾的V名片。 网盘资料如下:
id="article_content" class="article_content clearfix" style="height: 2000px; overflow: hidden;"> id="content_views" class="markdown_views prism-atom-one-dark"> class="toc"> 目录 1、前言2、FT601芯片解读和时序分析FT601功能和硬件电路FT601读时序解读FT601写时序解读 3、我这儿的 FT601 USB3.0通信方案4、详细设计方案5、vivado工程详解6、上板调试验证7、福利:工程代码的获取