透过实现小型打包工具理解webpack
面试经常有问到 webpack,偶遇一篇比较有实用价值的且有利于理解的文章,现总结如下:
本篇文章中要实现的这个迷你打包工具,它主要能实现如下两个功能:
①、将 ES6 转换成 ES5;
②、支持在 JS 文件中 import css 文件;
下面我们跟随这个工具的具体实现,来理解打包工具的原理,come on~
实现
因为涉及到 ES6 转 ES5,所以我们首先需要安装一些 Babel 相关的工具:
接下来我们将这些工具引入文件中:
接下来,我们先来实现如何使用 Babel 转换代码:
①.首先我们传入一个文件路径参数,然后通过 fs 将文件中的内容读取出来;
②.接下来我们通过 babylon 解析代码获取 AST,目的是为了分析代码中是否还引入了别的文件;
③.通过 dependencies 来存储文件中的依赖,然后再将 AST 转换为 ES5 代码
④.最后函数返回了一个对象,对象中包含了当前文件路径、当前文件依赖和当前文件转换后的代码;
接下来我们需要实现一个函数,这个函数的功能有以下几点:
I、调用 readCode 函数,传入入口文件;
II、分析入口文件的依赖;
III、识别 JS 和 CSS 文件;
I、首先我们读取入口文件,然后创建一个数组,该数组的目的是存储代码中涉及到的所有文件;
II、接下来我们遍历这个数组,一开始这个数组中只有入口文件,在遍历中,如果入口文件有依赖其他的文件,那么就会被 push 到这个数组中;
III、在遍历的过程中,我们先获得该文件对应的目录,然后遍历当前文件的依赖关系;
IV、在遍历当前文件依赖关系的过程中,首先生成依赖文件的绝对路径,然后判断当前文件是 CSS 文件还是 JS 文件
①.如果是CSS文件的话,我们就不能用 Babel 去编译了,只需要读取 CSS 文件中的代码,然后创建一个 style 标签,将代码插入进标签并且放入 head 中即可;
②.如果是JS文件的话,我们还需要分析JS文件是否还有别的依赖关系;
③.最后将读取文件后的对象 push 进数组中;
Now,我们已经获取到了所有的依赖文件,接下来就是实现打包的功能了:
这段代码需要结合着 Babel 转换后的代码来看,这样大家就能理解为什么需要这样写了
Babel 将我们 ES6的模块化代码转换为了 CommonJS 的代码,但是浏览器是不支持 CommonJS 的,所以如果这段代码需要在浏览器环境下运行的话,我们需要自己实现 CommonJS 相关的代码,这就是 bundle 函数做的大部分事情;
接下来我们再来逐行解析 bundle 函数
I、首先遍历所有依赖文件,构建出一个函数参数对象;
II、对象的属性就是当前文件的相对路径,属性值是一个函数,函数体是当前文件下的代码,函数接受三个参数 module、exports、require;
①.module 参数对应 CommonJS 中的 module;
②.exports 参数对应 CommonJS 中的 module.export;
③.require 参数对应我们自己创建的 require 函数;
III、接下来就是构造一个使用参数的函数了,函数做的事情很简单,就是内部创建一个 require 函数,然后调用 require(entry),也 就是 require('./entry.js'),这样就会从函数参数中找到 ./entry.js 对应的函数并执行,最后将导出的内容通过 module.export 的方式让外部获取到;
IV、最后再将打包出来的内容写入到单独的文件中
可以阅读下打包后的部分简化代码来帮助理解:
综上可知,打包工具的核心原理就是:
1、webpack是把项目当做一个整体,通过给定的一个主文件,webpack将从这个文件开始找到你的项目的所有依赖文件;
2、然后使用 loaders 处理它们,最后打包成一个或多个浏览器可识别的 js 文件;
透过实现小型打包工具理解webpack的更多相关文章
- 简单理解 Webpack,以及Web前端使用打包工具的原因
Java 中的模块 传统的前端开发就是 JS.HTML.CSS 三件套.Web 没有像 Java 一样拥有优秀的模块机制,就是类与类之间可以分装在不同的包下,不同包下的类互相引用时通过import导入 ...
- 细说前端自动化打包工具--webpack
背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...
- webpack打包和gulp打包工具详细教程
30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解ba ...
- vue 之webpack打包工具的使用
一.什么是webpack? webpack是一个模块打包工具.用vue项目来举例:浏览器它是只认识js,不认识vue的.而我们写的代码后缀大多是.vue的,在每个.vue文件中都可能html.js.c ...
- Vue学习【第四篇】:Vue 之webpack打包工具的使用
什么是webpack webpack是一个模块打包工具.用vue项目来举例:浏览器它是只认识js,不认识vue的.而我们写的代码后缀大多是.vue的,在每个.vue文件中都可能html.js.css甚 ...
- 前端打包利器:webpack工具
一.什么是WebPack,为什么要使用它? 1.为什要使用WebPack 现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包.为了简化开发的复杂度,前端 ...
- vue之webpack打包工具的使用
vue之webpack打包工具的使用 一.什么是webpack? webpack是一个模块打包工具.用vue项目来举例:浏览器它是只认识js,不认识vue的.而我们写的代码后缀大多是.vue的,在每个 ...
- 好用的打包工具webpack
<什么是webpack> webpack是一个模块打包器,任何静态资源(js.css.图片等)都可以视作模块,然后模块之间也可以相互依赖,通过webpack对模块进行处理后,可以打包成我们 ...
- Webpack实战(一):Webpack打包工具安装及参数配置
为什么要模块化 javascript跟其他开发语言有很多的区别,其中一个就是没有模块化概念,如果一个项目中有多个js文件,我们只能通过script标签引入的方式,把一个个js文件插入到页面,这种做法会 ...
随机推荐
- jdbc连接sqlserver,mysql,oracle
class xxx{ private static String port = "1433"; private static String ip = "192.168.2 ...
- pip install psycopg2出现python setup.py egg_info failed with error code 1 in /tmp/pip-build-YtLeN3/psycopg2错误处理
折腾了一上午flask部署,到最后访问域名还是出现Application Error错误提示.估计是程序还有问题,想着直接clone书中作者的代码先试试能不能部署成功.结果在执行pip install ...
- 11、Grafana 5.0 新功能特性(译文)
Grafana v5.0的新功能 这是Grafana有史以来最重大的更新. 本文将详细介绍主要的新功能和增强功能. New Dashboard Layout Engine enables a mu ...
- SpringBoot系列三:SpringBoot自定义Starter
在前面两章 SpringBoot入门 .SpringBoot自动配置原理 的学习后,我们对如何创建一个 SpringBoot 项目.SpringBoot 的运行原理以及自动配置等都有了一定的了解.如果 ...
- Codeforces Round #443 (Div. 1) C. Tournament
题解: 思路挺简单 但这个set的应用好厉害啊.. 我们把它看成图,如果a存在一门比b大,那么a就可以打败b,a——>b连边 然后求强联通分量之后最后顶层的强联通分量就是能赢的 但是因为是要动态 ...
- Aspnet Mvc 前后端分离项目手记(一) 关于跨域问题(还有前言)
前言,最近的项目使用前后端分离的模式,记录其中一些知识点.经过这个项目,也对前后端分离有了更多理解,尤其是在技术之外的方面. 越来越多的项目采用前后端分离的原因,有两点: 1,技术方面的原因 ...
- SpringCloud使用Nacos服务发现实现远程调用
本文使用SpringCloud结合Nacos服务发现,Feign远程调用做一个简单的Demo. 1 Nacos 关于Nacos之前写了两篇文章关于SpringBoot对它的使用,感兴趣可以查看一下. ...
- 2017-11-4—稳态和暂态/瞬态(对运放积分电路的思考)[待仿真]
先直接截图了,暂态或者说瞬态都是暂时的状态,是从一个稳定态到另一个稳定态的过程. 之所以要了解这个概念是因为对于使用运放搭建的模拟PID有很多的疑惑,比如负反馈没有电阻满不满足"虚短&quo ...
- Chapter 1 An Overview of Computers and Programming Languages
Babylon巴比伦 loom织布机 weaver, WHO uses loom to work census: to count the population tabulate: make into ...
- node.js官方文档解析 01—assert 断言
assert-------断言 new assert.AssertionError(options) Error 的一个子类,表明断言的失败. options(选项)有下列对象 message < ...