link822 link823 link824 link825 link826 link827 link828 link829 link830 link831 link832 link833 link834 link835 link836 link837 link838 link839 link840 link841 link842 link843 link844 link845 link846 link847 link848 link849 link850 link851 link852 link853 link854 link855 link856 link857 link858 link859 link860 link861 link862 link863 link864 link865 link866 link867 link868 link869 link870 link871 link872 link873 link874 link875 link876 link877 link878 link879 link880 link881 link882 link883 link884 link885 link886 link887 link888 link889 link890 link891 link892 link893 link894 link895 link896 link897 link898 link899 link900 link901 link902 link903 link904 link905 link906 link907 link908 link909 link910 link911 link912 link913 link914 link915 link916 link917 link918 link919 link920 link921 link922 link923 link924 link925 link926 link927 link928 link929 link930 link931 link932 link933 link934 link935 link936 link937 link938 link939 link940 link941 link942 link943 link944 link945 link946 link947 link948 link949 link950 link951 link952 link953 link954 link955 link956 link957 link958

History of web Front-end build tools

WEB前端为什么需要构建工具

WEB技术的发展和局限

TODO
C# dll: metadata, “data about data”

AJAX(gmail) - node.js 飞速发展期

当学习了一种前端技术的时候,同时会有几种新的前端技术诞生。

还有,你选择的那种前端技术,也许已经过时了。

前端构建工具的需求

预处理

JS/CSS/HTML在设计之初并未料及它们会这样流行,整个Web已经形成一个大的分布式文档。 低层语言的更换或升级都因兼容性问题而面临着巨大困难。 这催生了各种中间语言个预处理器,例如SASS,LESS,CoffeeScript,Babel等。
这些预处理工具可以将我们的中间代码转换为可运行的JavaScript。 这些预处理器使得我们可以预先使用ECMA Script6,以结构化的方式编写CSS,或者在CommonJS环境中编写JavaScript等等。

风格与测试

在一个典型的工作流中,每次Push主分支或npm发布都应首先运行代码风格检查和单元测试。 我们需要这些操作能够在合适的时候自动执行。

资源压缩

在开发网站代码时,我们希望模块化地进行编码。每个业务逻辑,通用工具,或者架构元素都需要组织在单独的文件中。 但是如果用户浏览网页时也载入这么多源文件,那么页面打开速度会大打折扣。
因此在网站发布时需要将源码合并压缩, JavaScript可能还会需要模块化(AMD,CommonJS等), CSS文件可能也需要合并、添加兼容性前缀(-webkit-, -moz-)等。 这些重复性工作我们也希望写成脚本。

自动刷新

监听本地源代码变化,自动重新构建、刷新浏览器。

静态资源替换

最为复杂的构建需求是静态资源的URL替换。 因为生产环境中的资源地址可能和开发环境中很不一样, 可能是由于JS合并、CSS合并,也可能是由于应用了CDN加速。
我们需要在部署时更改所有HTML文件中的静态资源地址。

模块合并

在采用模块化的项目里会有很多个模块和文件,需要通过构建功能将模块分类合并成一个文件。

自动发布

更新代码后,自动构建出线上发布代码并传输给发布系统。

构建其实是工程化、自动化思想在前端开发中的体现,将一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。构建为前端开发注入了更大的活力,解放了我们的生产力。

前端构建工具的发展

历史上先后出现了一系列构建工具,他们各有优缺点。由于前端工程师很熟悉 JavaScript,Node.js 又可以胜任所有构建需求,所以大多数构建工具都是用 Node.js 开发的。

Npm Scripts

在 Npm Scripts 和 Grunt 时代,Web 开发要做的事情变多,流程复杂,自动化思想被引入,用于简化流程;

Grunt

Gulp

在 Gulp 时代,开始出现一些新语言用于提高开发效率,流程处理思想的出现是为了简化文件转换的流程,例如将ES6转换为ES5;

语法太简洁了。感觉一句多余的代码都没有。或者说它只让你写必要的代码。用gulp官网的话说,这个叫做“代码优于配置”

构建项目的时间速度快。它充分利用了node流,优化(缩减)了很多对IO的操作。这样做的好处是你会发现gulp构建的时候每个Tast几乎都是ms级的,用了这个以后你会感觉grunt构建时候的速度原来那么慢。

FIS 3

Fis3是一个来自百度的优秀国产构建工具。相对于 Grunt、Gulp 这些只提供了基本功能的工具。Fis3集成了开发者常用的构建功能,如下所述。
读写文件:通过 fis.match 读文件,release 配置文件输出路径。
资源定位:解析文件之间的依赖关系和文件位置。
文件指纹:在通过 useHash 配置输出文件时为文件 URL加上 md5 戳,来优化浏览器的缓存。
文件编译:通过 parser 配置文件解析器做文件转换,例如将 ES6 编译成 ES5。
压缩资源:通过 optimizer 配置代码压缩方法。
图片合并:通过 spriter 配置合并 CSS 里导入的图片到一个文件中,来减少 HTTP 请求数。

Webpack

在Webpack时代,由于单页应用的流行,网页的功能和实现代码变的复杂、庞大,Web开发向模块化改进
(本地模块化工具)
Webpack 是一个打包模块化的JavaScript的工具,在Webpack里一切文件皆模块,通过 loader 转换文件,通过Plugin 注入钩子,最后输出由多个模块组合成的文件。Webpack 专注于构建模块化项目。

Rollup

Rollup 是一个和 Webpack 很类似但专注于ES6的模块打包工具。它的亮点在于,针对ES6源码进行 Tree Shaking,以去除那些已经被定义但没被使用的代码并进行 Scope Hoisting,以减少输出文件的大小和提升运行性能。然而 Rollup 的这些亮点随后就被 Webpack 模仿和实现了。由于 Rollup 的使用方法和 Webpakc 差不多,所以这里就不详细介绍如何使用 Rollup 了,而是详细说明他们的差别:
Rollup 是在Webpack 流行后出现的替代品;
Rollup 生态链不完善,体验还不如Webpack;
Rollup 的功能不如 Webpack 完善,但其配置和使用更简单;
Rollup 不支持 Code Spliting, 但好处是在打包出来的代码中没有 Webpack 那段模块的加载、执行和缓存的代码。
Rollup 在用于打包JavaScript库时比 Webpack 更有优势,因为其打包出来的代码更小、更快。但他的功能不够完善,在很多场景下都找不到现成的解决方案。

Overview

  • 在 Npm Scripts 和 Grunt 时代,Web 开发要做的事情变多,流程复杂,自动化思想被引入,用于简化流程;
  • 在 Gulp 时代,开始出现一些新语言用于提高开发效率,流程处理思想的出现是为了简化文件转换的流程,例如将ES6转换为ES5;
  • 在Webpack时代,由于单页应用的流行,网页的功能和实现代码变的复杂、庞大,Web开发向模块化改进。

Web 前端项目的演进

从简单到复杂
从多页到单页
前后端的分离
前端模块化/组件化/工程化

具体的演进过程如下

多页

后端直接输出 Web 内容, 没有异步请求后端接口数据

多页 + Ajax + 拼字符串输出 HTML

静态页面变成”动态”页面, 需要调用后端接口获取数据, 在前端渲染出页面的内容

多页 + Ajax + 前端模版引擎(artTemplate)

拼字符串难以维护, 引入前端模版引擎来实现数据层与展现层的分离
多页 + Ajax + 前端 MVVM 框架(Vue)
引入前端 MVVM 框架来取代前端模版引擎, 数据与视图同步更新, 更彻底的分离出展现层

多页 + Ajax + 前端 MVVM 框架(Vue) + (模块化)依赖管理(RequireJS)

前端的依赖混乱难以管理一直是前端的毒瘤, 项目变大后团队的协作是个问题, 很容易就发生 JS(全局) 和 CSS(全局) 的冲突
JS 和 CSS 本身在语言层次上没有提供模块化解决方案
JS 一般通过闭包导出命名空间到全局来规避冲突, 实现简易的模块化
CSS 一般通过命名规范来规避冲突, 例如 BEM 命名规范
如果只是简单的项目, 可以引入历史技术 AMD 来实现模块化和依赖管理
一旦有了模块化管理, 势必会慢慢涉及到前端构建方案(Grunt/Gulp), 来做前端的打包和发布

单页 + Ajax + 前端 MVVM 框架(Vue) + (模块化)依赖管理(webpack/ES2015) + 前端路由(vue-router)

单页的复杂度是前端的一个转折点, 你会遇到越来越多前端工程化方面的问题, 首先需要了解的就是前端路由的实现原理(hashchange/HistoryAPI)
因为实现单页的基础就是引入前端路由来模拟出”多个页面视图”的逻辑切换
模块化之后, 为了模块的重用, 一般会定义出公共模块和各个页面视图模块, 模块的数量会越来越多, 首次需要加载的文件也就会越来越多, 你肯定不想浏览器首次加载的时候需要发送几十个请求吧, 因此我们需要前端构建工具来打包我们的模块
然而你肯定也不想所有的模块都打包成一个文件(all in one), 这样肯定会拖慢页面首屏加载的速度, 因此迫切的需要代码分隔和模块懒加载(一般是根据路由的懒加载)
那么既然已经引入了前端工程化构建的过程, 那么前端一些最新的规范(例如 ES2015), 我们也就可以用起来了, 让我们面向未来编程

单页 + Ajax + 前端 MVVM 框架(Vue) + (模块化)依赖管理(webpack/ES2015) + 前端路由(vue-router) + 状态管理(Redux)

页面视图上需要控制的状态越来越多, 多个页面视图的状态又有依赖, 到底是哪里触发了某个状态的改变, 哪个视图又会受到这个状态改变的影响?
你是不是通过全局事件做过组件之间的通信? 你能够预测到状态与视图之间的对应关系吗? 是不是越发地难以控制难以调试了?
引入前端状态管理的架构方案让代码结构标准化可控
view = f(state)

前端模块化/组件化/工程化

将前端项目当成一项系统工程进行分析、组织和构建从而达到项目结构清晰、分工明确、团队配合默契、开发效率提高的目.

模块化和组件化一个最直接的好处就是复用,同时我们也应该有一个理念,模块化和组件化除了复用之外还有就是分治,我们能够在不影响其他代码的情况下按需修改某一独立的模块或是组件,因此很多地方我们及时没有很强烈的复用需要也可以根据分治需求进行模块化或组件化开发。