CommonJs、AMD、CMD、Webpack

CommonJs:

        CommonJS是一个偏向于服务器端的规范。CommonJS的一个模块就是一个脚本文件。require命令第一次加载该脚本时就会执行整个脚本,然后在内存中生成一个对象。nodejs和webpack都采用这种规范编写代码。

 常用的属性:

{ id: '...',

    exports: { ... },

    loaded: true, ...

}

        id是模块名,exports是该模块导出的接口,loaded表示模块是否加载完毕。此外还有很多属性,这里省略了。

        以后需要用到这个模块时,就会到exports属性上取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存中取值。

             CommonJS模块规范主要分为三部分:模块引用、模块定义、模块标识。

       CommonJS模块规范的好处

            CommonJS模块规范很好地解决变量污染问题,每个模块具有独立空间,互不干扰,命名空间相比之下就不太好。

            CommonJS规范定义模块十分简单,接口十分简洁。

            CommonJS模块规范支持引入和导出功能,这样可以顺畅地连接各个模块,实现彼此间的依赖关系。

        node.js和webpack都是根据commonJs来编写代码的。


    优点:

        在后端,JavaScript的规范远远落后并且有很多缺陷,这使得难以使用JavaScript开发大型应用。比如:

  1. 没有模块系统
  2. 标准库较少
  3. 没有标准接口
  4. 缺乏包管理系统
  5. 列表内容

        CommonJS规范的提出,主要是为了弥补JavaScript没有标准的缺陷,已达到像Python、Ruby和Java那样具备开发大型应用的基础能力,而不是停留在开发浏览器端小脚本程序的阶段

缺点:        

没有并行加载机制

由于CommonJS是同步加载模块,这对于服务器端是很不好的,因为所有的模块都放在本地硬盘。等待模块时间就是硬盘读取文件时间,很小。但是,对于浏览器而言,它需要从服务器加载模块,涉及到网速,代理等原因,一旦等待时间过长,浏览器处于”假死”状态。

所以浏览器端不是很适合Common.Js,出现另一种规范AMD



AMD:

     是一个异步模块定义规范;是RequireJs推广过程中对模块定义的规范化产出;

        1、提前执行。

        2、AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块。

        3、AMD用户体验好,因为没有延迟,依赖模块提前执行了。

CMD:

    是一个通用模块定义规范;是SeaJs推广过程中对模块定义的规范化产出;

        1、延迟执行

        2、CMD推崇依赖就近,只有在用到某个模块的时候才会去require

        3、CMD性能好,因为只有用户需要的时候才执行。

        AMD在加载模块完成后就会执行更改模块,所有模块都加载执行完后会进入require的回调函数,执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不一定一致,看网络速度,哪个先下载下来,哪个先执行,但是主逻辑一定在所有依赖加载完成后才执行。

        CMD加载完某个依赖模块后并不执行,只是下载而已,在所有依赖模块加载完成后进入主逻辑,遇到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是完全一致的。

这也是很多人说AMD用户体验好,因为没有延迟,依赖模块提前执行了,CMD性能好,因为只有用户需要的时候才执行的原因。


API角度AMD和CMD的区别:

        AMD 的 API 是一个当很多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。



AMD和CommonJs的区别:

共同点:两者都是为了实现模块化编程而出现的,对于大型项目,参与人数多,代码逻辑复杂,是最适合使用模块化的思想来完成整个项目的。同时采用这种思想也很便于对整个项目进行管控。

区别:

        CommonJS是适用于服务器端的,其中Node执行环境就是采用的CommonJS模式。它是同步加载不同模块文件。之所以采用同步,是因为模块文件都存放在服务器的各个硬盘上,实际的加载时间就是硬盘的文件读取时间。

        然而AMDAsynchronous Module Definition,即异步模块定义。它是适用于浏览器端的一种模块加载方式。从名字可知,AMD采用的是异步加载方式(js中最典型的异步例子就是ajax)。浏览器需要使用的js文件(第一次加载,忽略缓存)都存放在服务器端,从服务器端加载文件到浏览器是受网速等各种环境因素的影响的,如果采用同步加载方式,一旦js文件加载受阻,后续在排队等待执行的js语句将执行出错,会导致页面的‘假死’,用户无法使用一些交互。所以在浏览器端是无法使用CommonJS的模式的。目前,主要有两个Javascript库实现了AMD规范:require.jscurl.js


刚刚说到了webpack是根据commonjs书写代码的讲讲webpack

Webpack:

        webpack是一个模块打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都一起打包变为静态文件。

        简单说就是模块加载器,通过使用Webpack,能够像Node.js一样处理依赖关系,然后解析出模块之间的依赖,将代码打包。

为什么需要打包?

  • 像sass,JSX等代码虽然极大的提高了开发效率,但是本身并不被浏览器所识别,需要我们对其进行编译和打包,变成浏览器识别的代码
  • 模块化(让我们可以把复杂的代码细化为小的文件)
  • 优化加载速度(压缩和合并代码来提高加载速度,压缩可以减少文件体积,代码合并可以减少http请求)
  • 使用新的开发模式

webpack主要特点:

  • 以CommonJS来编写,但也支持AMD、CMD模块(对于新项目,推荐直接使用CommonJS);
  • 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持;
  • 可以根据配置或者智能分析打包成多个文件,实现公共模块或者按需加载;
  • 支持对CSS,图片等资源进行打包,这样子就不用使用Grunt或Gulp(browserify只能打包JS文件);
  • 开发时在内存中完成打包,性能更快,完全可以支持开发过程的实时打包需求;
  • source map有很好的支持。

Source map(使调试更容易)

Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,除错工具就直接显示原始代码,而不是转换后的代码,这将给开发者带来了很大方便。 

配置

每个项目下都必须配置有一个 webpack.config.js ,它的作用如同常规的 gulpfile.js/Gruntfile.js ,就是一个配置项,告诉 webpack 它需要做什么。 



执行打包

如果通过npm install -g webpack方式安装webpack的话,可以通过命令行直接执行打包命令,比如: 
$ webpack –config webpack.config.js 
这样就会读取当前目录下的webpack.config.js作为配置文件执行打包操作

常用webpack命令: 
在开发环境构建一次 
webpack 
构建并生成源代码映射文件 
webpack -d 
在生成环境构建,压缩、混淆代码,并移除无用代码 
webpack -p 
快速增量构建,可以和其他选项一起使用 
webpack –watch 
progress 显示打包过程中的进度,colors打包信息带有颜色显示 
webpack –progress –colors

理解文件路径

require(‘lodash’) // 从模块目录查找 
require(‘./file’) // 按相对路径查找

CSS 及图片的引用

require(‘./bootstrap.css’); 
require(‘./myapp.less’);

var img = document.createElement(‘img’); 
img.src = require(‘./glyph.png’);










猜你喜欢

转载自blog.csdn.net/weixin_41143293/article/details/79662362