模块化概念——在进行项目分析或者编码时,先把项目进行拆分,拆分成很多的类,对象,很多的函数等等。能够提高代码的复用性。这些被拆分出来的类型,对象,函数就是模块。
1) 前端模块化
ES6之前,因为JavaScript不支持模块化,所以在前端里出现了第三方的解决方案 AMD和CMD。
-
AMD:Asynchronous Module Definition,中文名是异步模块定义的意思,需要加载require.js库;
- 对外导出使用return
- 主模块再使用其他模块:
require([引入的其它模块列表],function(其它模块对应的变量名列表){ });
- 引用路径相对HTML:
define(["js/dog.js"],function(d){})
- AMD 是提前执行,AMD 推崇依赖前置。AMD在加载模块完成后就会执行改模块,所有模块都加载执行完后会进入require的回调函数,执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不一定一致,看网络速度,哪个先下载下来,哪个先执行,但是主逻辑一定在所有依赖加载完成后才执行。用户体验好。
-
CMD:Common Module Definition,称为 通用模块加载规范 ,通常使用异步加载库 Sea.js 。
- 对外导出在define函数的第二个参数(回调函数)的exports参数。
- 主模块再使用其他模块:
seajs.use([引入的其它模块列表],function(其它模块对应的变量名列表){ });
- 引用路径相对js文件:
let d = require("dog_sea");
- CMD 是延迟执行,推崇依赖就近。CMD加载完某个依赖模块后并不执行,只是下载而已,在所有依赖模块加载完成后进入主逻辑,遇到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是完全一致的。因此性能比较好。
2) 后端模块化
在后端里(nodeJS)出现了commonJS规范。在CommonJS中,有一个全局性方法require(),用于加载模块。接口通过**module.exports**定义。
因为是本地执行,所以是同步读取的模块,加载速度就是硬盘读取的速度,所以这也是不支持前端的理由。
wepack采用的就是commonjs。
3) ES6模块化
导入用import,导出用export。
export default和export 有什么区别:
- export与export default均可用于导出常量、函数、文件、模块等
- 在一个文件或模块中,export可以有多个,export default仅有一个,而且export default在导出是不需要变量名,相当于匿名的。
- 通过export方式导出,在导入时要加 { } ,export default则不需要。
还有注意:在ES6中中输出的是值的引用,也就是说模块内部变化会影响输出。
4)webpack
当下最热门的前端资源模块化管理和打包工具
- 运行在浏览器端的seajs和requirejs模块框架,相当于在页面上加载一个CMD/AMD解释器,这样浏览器就认识了define、exports、module这些东西,也就实现了模块化。
- webpack和browserify它们是一个预编译模块的方案,它们遵循了不需要在浏览器中加载解释器。在本地直接写js,不管是AMD/CMD/ES6风格的模块化,它都能识别并编译成浏览器认识的js。
- 代码拆分: Webpack 有两种组织模块依赖的方式,同步(默认)和异步(高级)。异步依赖作为分割点,形成一个新的块。在优化了依赖树后,每一个异步区块都作为一个文件被打包。按需异步引入。
- loader:最初Webpack就是为前端js代码打包而设计的,但是 “loader 转换器”可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。
- plugin: plugin 用于扩展webpack的功能。它直接作用于 webpack,扩展了它的功能。虽然 loader也时变相的扩展了 webpack ,但是它只专注于转化文件这一个领域。
- chunk:webpack打包的过程种,生成的JS文件,每一个JS文件我们都把它叫做Chunk。第三方chunk被已有的chunk引用次数也是判断代码是否被分割的因素。