之前一直对前端构建工具的理解不深,通过几天的研究特地来总结一下,第一次写博客,有写错的请多多见谅,该文章我也从其余博客拷了一些内容,若是有冒犯之处,请指出。php
现在,网页再也不是本身编写各类功能了,而是如何把各类不一样功能的模块组合起来。
之前使用script引用不但增长网络请求,还会时页面更加臃肿,为了解决这类问题,前端的模块管理应运而生,最先提出解决方法的是AMD,其实践方案是requireJs和curlJs.它不只实现了js文件的异步加载,还管理了模块之间的倚赖性,(相似于面向对象的Module模式)css
main就是主模块,省略了.js后缀,在main.js里面能够配置模块的加载,在其头部写require.config前端
在实际应用中,每每还须要在服务端,将全部模块合并后,再统一加载,这多出了不少工做量java
AMD 经过将模块的实现代码包在匿名函数(即AMD 的工厂方法,factory)中实现做用域的隔离,经过文件路径做为自然的模块ID 实现命名空间的控制,将模块的工厂方法做为参数传入全局的define(由模块加载器事先定义),使得工厂方法的执行时机可控,也就变相模拟出了同步的局部require,于是AMD 的模块能够不经转换地直接在浏览器中执行。 所以,在开发时,AMD 的模块能够直接以原文件的形式在浏览器中加载执行并调试,这也成为RequireJS 方案很少的优势之一。node
注意:webpack
然而基于AMD 规范的非JavaScript 资源加载有着本质的以下缺陷。
1.加载与构建的分离致使plugin 须要分别实现两套逻辑。
2.在构建产物,r.js构建的结果是define(function(){...})的几何,文件的执行倚赖页面上事先引入一个amd模块加载器(如requireJs自身),因此常见的AMD项目线上页面每每存在两个Javascript文件:loader.js及bundle.js。而browserify和webpack的构建结果 是能够执行的js代码,它们都支持经过配置生成符合格式的结果文件,如以umd形式暴露 库的exports,以便其余页面代码调用。后者的这种形式更符合js库的构建
3.浏览器的安全策略决定了绝大多数须要读取文本内容进行解析的静态资源没法被跨域加载(即便是JavaScript 模块自己,也要依靠define 方法包裹,相似于JSONP 原理实现的跨域加载)。es6
其本事不是模块管理器,只是让CommondJs格式的模块能够运行在浏览器端,这意味着它可使用nodeJs的npm模块管理器。因此,实际上,它等于间接为浏览器提供了npm的功能web
上面这个代码使用的是CommondJs格式,没法在浏览器中运行,这是须要用到browserify,将上面代码编译为浏览器脚本npm
注意:(1). requirejs/seajs: 是一种在线“编译”模块的方案,至关于在页面上加载一个CommonJS/AMD模块格式解释器。这样浏览器就认识了define, exports,module这些东西,也就实现了模块化。gulp
(2).browserify/webpack:是一个预编译模块打包的方案,相比于第一种方案,这个方案更加智能。因为是预编译的,不须要在浏览器中加载解释器。你在本地直接写JS,不论是AMD/CMD/ES6风格的模块化,它都能认识,而且编译成浏览器认识的JS。注意: browerify打包器自己只支持Commonjs模块,若是要打包AMD模块,则须要另外的plugin来实现AMD到CMD的转换!!
browserify不支持异步加载,非js文件加载(img src打包路径问题)
这里插入一下es6和CommonJs的区别:
* 运行时加载: CommonJS 模块就是对象;即在输入时是先加载整个模块,生成一个对象,而后再从这个对象上面读取方法,这种加载称为“运行时加载” * *
编译时加载: ES6 模块不是对象,而是经过 export 命令显式指定输出的代码,输入时采用静态命令的形式。即在输入时能够指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载”
正如咱们在前面提到的define 函数的做用,没有define 函数的CommonJS 模块是没法直接在浏览器中执行的——浏览器环境中没法实现同Node.js 环境同样同步的require 方法。一样也由于没有define 与工厂方法,CommonJS 模块书写起来要更简单、干净。在这个显而易见的好处下,愈来愈多的前端项目开始采用CommonJS 规范的模块书写方式。
Gulp / Grunt 是一种工具,可以优化前端工做流程。好比自动刷新页面、combo、压缩css、js、编译less等等。简单来讲,就是使用Gulp/Grunt,而后配置你须要的插件,就能够把之前须要手工作的事情让它帮你作了。
gulp相比grunt简便,借助unix的流操做思想,经过管道pipe来管理task任务,实现前端的优化,例如把Js和css融合在一块儿并压缩
webpack只是在Loader里面加载的时候,帮咱们默认实现了操做,没有gulp操做得透明,gulp只是构建工具,因此若是开发SPA单页面应用的时候,须要用到模块化开发,这时就须要用到模块化的概念,若是想用CommondJs风格,就须要借助browserify来做为转换工做,也许你会发如今gulp使用时就有require('gulp')这样的引用风格,这是npm包管理的模块,是CommondJs的node的风格,是编写gulp这些构建工具时用的,不是咱们编写本身的前端模块代码的。因此使不使用模块方案要看项目工程是否庞大决定,若是简单,作个多页面应用,不须要把js或各类资源打包处理,只须要简单的合并,压缩,在页面中引用就好,那就不须要Browserify,webpack。用gulp就够了。使用es6模块规范时,经过babel转之后造成commondJs这样的代码,通常还不能使用,由于浏览器不识别commondJs,因此须要browserify或者webpack将其打包到一个js文件中。
可是相比于npm , grunt和gulp缺点是至关倚赖插件的开发,若是出现新技术时,须要相关人开发插件,如gulp-eslint,当使用时,须要在gulp-eslint文档和eslint文档来回切换,不得不在插件和所抽象的工具之间来回切换上下文。相比于npm这个更大的插件社区,缺点教为明显
构建工具完成的目标基本是:
fis也属于前端构建工具,它的本质是基于静态资源标记和动态解析静态资源表,在模版,js里面使用特殊的标记方法引用前端资源,构建的时候生成一张资源倚赖表,浏览器或者后端模版语言在解析的过程当中经过查表获得某个静态资源在不一样环境下的引用路径,因此不论是纯前端渲染仍是服务端渲染,都容易获得支持,
fis实际上是一种静态资源表的思想,在这种思想下,对于php的smarty产生了fis-plus,基于java的即是 jello,
后来fis3都将其归入了其中
fis3的功能和webpack相似,其优势是静态资源表
fis3设计之初是用在网页构建上,因此后端的文件操做之类不适用,fis3的模块化开发主要是AMD,CMD和自定义扩展commonJs的modJs,三个分别对应于三个插件来实现,因为本身葛璐开发了一种模式,因此致使贡献也少了,fis能够作到完美的解决方案还须要后端的配合,因此也使得其不了了之。
webpack比较黑盒,用起来很方便,十分适合开发SPA项目,可是却不适合服务端渲染,webpack目前的功能已经很是齐全,也相应的会带来首次加载,打包时间慢,须要对其打包进行优化
它既吸收了大量已有方案的优势与教训,也解决了不少前端开发过程当中已存在的痛点,如代码的拆分与异步加载、对非JavaScript 资源的支持等。强大的loader 设计使得它更像是一个构建平台,而不仅是一个打包工具。
考虑到AMD 规范与CommonJS 规范各有各的优势,且都有着可观的使用率,webpack 同时支持这两种模块格式,甚至支持两者混用。并且经过使用loader,webpack也能够支持ES6 module(这一特性在即将到来的webpack 2 中原生支持),能够说覆盖了现有的全部主流的 JavaScript 模块化方案。经过特定的插件实现 shim 后,在webpack 中,甚至能够把以最传统全局变量形式暴露的库看成模块require 进来。
webpack.config.js实在node.js中运行的,所以不支持es6的import语法
其实webpack是个大boss,我就不在本文细说了,网上对webpack的使用已经有不少案例了。
感谢你的捧场,有什么错误能够指出,你们多多探讨...
***未完待续***