文章目录
老马webpack 入门教程
有哪些打包工具(以发布时间为顺序)
前端的打包工具
1、grunt(14-16)
最老牌的打包工具,它运用配置的思想来写打包脚本,一切皆配置,所以会出现比较多的配置项,诸如option,src,dest等等。而且不同的插件可能会有自己扩展字段,认知成本高,运用的时候需要明白各种插件的配置规则
2、gulp
基于 nodejs 的 steam 流打包。运用相当简单。更易于学习和使用,使用gulp的代码量能比grunt少一半左右。
3、webpack
目前最强大的打包工具,但是过于臃肿,如果单纯打包js不推荐
4、Roleup
tree-shaking特性(针对es6,按需打包,多余的不要,目前(2018,vuex,react主流使用)
选择:
如果你一个都不熟悉的话,那么我直接推荐 webpack,官方文档非常详细,更新频率很高。而且在其他的打包工具在处理非网页文件(比如svg, png, vue等)基本还是需要借助它来实现。最关键现在的脚手架主流依旧是它。
webpack理解
1、什么是webpack:
webpack是一个JavaScript应用程序的静态模块打包器(module bundle)
,在处理应用程序是,它会递归地构建一个模块依赖关系图,其中包含了应用程序需要的每一个模块,然后将这些模块打包成一个或多个bundle
2、webpack3.0到4.0有什么变化:
webpack4 增加了 更多的 个性化插件plugin
和 loader
( 转换器),对 es 6 模块更加支持,在前端的框架中广泛使用(Vue/ Angular React 的脚手架都是由 webpack 来开发和管理的 )
3、webpack的优点:
- 支持CMD和AMD,同时拥有丰富的plugin和loader,webpack逐渐得到广泛应用。
- 支持ES Module,分析ESModule之间的依赖关系,webpack1必须将ES,Module转换成CommonJS模块,2支持tree sharking
- 新的特性大都围绕ES Module提出,如Scope Hoisting和Magic Comment;webpack3以上基本上都可以解决es6提出的模块化
- 解决es6模块化,更多个功能性 ,pulgin 和 loader, 前端框架中广泛使用: Angular Vue React 的脚手架都是由webpack来进行开发、管理
4、webpack的工作流程(加载-编译-输出)
- 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler。
- 编译:从 Entry 发出,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理。
- 输出:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统。
- 初始化参数:读取配置文件,按命令初始化配置参数,创建
Compiler
对象 - 加载插件并调用插件的
apply
方法挂载插件监听,然后从entry
入口文件开始执行编译 - 模块编译:按文件类型,调用相应的loader对模块进行编译,并在合适的时机点触发对应的事件,调用Plugin执行,最后再根据该模块找出所依赖的模块,递归执行第3步
- 将编译后的所有代码包装成一个一个代码块(Chuck),并按照依赖和配置确定输出内容。这个步骤,任然可以通过Plugin进行文件的修改
- 最后,根据
Output
把文件内容一一写入到指定的文件夹,完成整个过程
5、loader和plugin的区别(原理与实现)
- loader:让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块
- plugin:loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
6、热更新原理HotModuleReplacement(webpack-dev-server)
- 启动webpack,生成
compiler
实例。compiler上有很多方法,比如可以启动 webpack 所有编译工作,以及监听本地文件的变化。 - 使用
express
框架启动本地server
,让浏览器可以请求本地的静态资源。 - 本地server启动之后,再去启动
websocket
服务,通过websocket,可以建立本地服务和浏览器的双向通信。这样就可以实现当本地文件发生变化,立马告知浏览器可以热更新代码啦!
热模块替换的好处是只替换更新的部分,而不是页面重载。webpack-dev-server启动了一个使用express的Http服务器,这个服务器与客户端采用websocket通信协议,当原始文件发生改变,webpack-dev-server会实时编译
7、babel(语法转换器)和AST(抽象语法树)
babel其实就是一个语法转换器,比如将ES6代码转换为ES5语法,就可以使用它来实现。在实现语法转换时有3个步骤:
- 解析:将代码(其实就是字符串)转换成抽象语法树AST
- 转换:将AST进行变换操作生成新的AST(通过遍历器)
- 生成:根据新的AST生成新的代码
在生成AST时,需要经过两个步骤:
- 词法分析:将代码(字符串)分割成一个个语法单元并形成一个数组(token流)
- 语法分析:分析token流(上面生成的数组)并生成 AST
可以举个例子
const add = (a, b) => a + b
经过babel转换后为function add(a,b) {return a + b}
babel-polyfill
《babel-polyfill 将ES6代码转为ES5代码》
Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise
等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。
转换新的API需要用插件Babel-polyfill
。Polyfill 指的是用于实现浏览器并不支持的原生 API 的代码
8、webpack优化
常用的webpack优化方法
1、提高它的打包速度
2、减少webpack打包后的文件体积