前端模块化要解决的两个问题

前言

前端模块化,主要是解决两个问题——“命名空间冲突”,“文件依赖管理”。

坑___命名空间冲突

  1. 我自己测试好的代码和大家合并后怎么起冲突了?
  2. 页面脚本的变量或函数覆盖了公有脚本的。

坑___文件依赖管理

  1. 明明项目需要引入的包都引进来了怎么还报缺少包?
  2. 手动管理依赖,有天要更换某个插件,要深入代码内部进行修改
  3. 如下图,显示的代码加载,依赖关系复杂。在F.js中,分不清某个变量是来自C.js,还是E.js
  4. 两次加载同一个模块。比如引入了两遍JQ

其他的坑

  1. 为了实现脚本复用,将一个很大的公用public文件引入各个页面中,其中的某些函数,只有个别页面用到。
  2. 某个功能的函数群函数,与另一个功能的函数群摆在一起,使用注释来分隔。

目前解决的方法是:模块化

  1. 命名空间:各个模块的命名空间独立。A模块的变量x不会覆盖B模块的变量x。
  2. 模块的依赖关系:通过模块管理工具如webpack/requireJS/browserify等进行管理。

模块化的基本原理——解决命名空间冲突

JavaScript的缺陷,首当其冲就是全局变量。这使得每想命名一个变量的时候都要三思又三思,生怕上方无穷远的地方有一个同事些的代码和自己冲突。以下是一些防范方法

一、使用命名空间

代码如下:


  1. //定义 
  2. var module = { 
  3.     name: 'rouwan', 
  4.     sayName:function(){ 
  5.         console.log(this.name) 
  6.     } 
  7. //使用 
  8. var a = module.name; 
  9. console.log(a)  

总结:直接修改name不会影响module.name,一定程度保护了命名空间。有两个缺点,一,外部还是可以修改module的属性和方法。二,命名空间有时长起来超乎你的想象。适合一些小型的封装,如一些配置。

二、立即执行函数 + 闭包(实现模块的基本方法)

立即函数可以创建作用域,闭包则可以形成私有变量和函数


  1. //创建 
  2. var module = (function(){ 
  3.                 var privateName = 'inner';            //私有变量 
  4.                 var privateFunc = function(){        //私有函数 
  5.                     console.log('私有函数') 
  6.                 } 
  7.  
  8.                 return {                             
  9.                     name: 'rouwan',                    //公有属性 
  10.                     sayName:function(){                //公有函数 
  11.                         console.log(this.name) 
  12.                     } 
  13.                 } 
  14.             })() 
  15. //使用 
  16. module.sayName();    //'rouwan'  

总结:这是目前比较常用的模块定义方式,可以区分私有成员和公有成员。公有变量和方法,和之前一样可以直接通过module.name的方式修改。私有变量和方法,是无法访问的,除非给你个修改私有成员的公有方法。

三、在上述基础上,引入其他模块


  1. //定义 
  2. var module1 = (function(mod){ 
  3.                 var privateName = 'inner1'; 
  4.                 var privateFunc = function(){ 
  5.                     console.log('私有函数1') 
  6.                 } 
  7.  
  8.                 return { 
  9.                     name : 'rouwan1', 
  10.                     sayName: function(){ 
  11.                         console.log(this.name) 
  12.                     }, 
  13.                     anotherName:mod.name,            //另一个模块上的公有参数 
  14.                     sayAnotherName:mod.sayName       //另一个模块上的公有方法 
  15.                 } 
  16.  
  17.             })(anotherModule)                        //引入了另一个模块 
  18. //使用 
  19. module1.sayOtherName()  

总结:在一个模块中可以引入另一个模块。

四、其他的方式

放大模式等是以往用来管理大型模块,进行文件拆分的方法。现在webpack等模块化工具都很完善的情况下,已经显得有点落后了。就不介绍了。

告别刀耕火种的时代——模块化构建工具(解决依赖管理)

我了解js模块是从立即执行函数开始的。但是等到真正使用构建工具的时候,却发现业界采用的模块化方案,却并非是一个一个由立即函数+闭包形成的集群。

而是用了诸如AMD/CMD/CommonJS/ES6模块等等模块化实现。

这里面的原因可能有这几个,一,闭包的性能问题。二,当模块增多的时候,需要解决模块间的依赖管理问题。

关于依赖管理,目前项目里碰到了几个不舒服的地方:

  1. 仅此一图,无须多言
  2. HTML中引入了两遍的jq,导致脚本报错。
  3. 有一个公用脚本,包含了N多的公用模块。有些页面明明只用到了一个模块,也必须全部加载一遍。

因此,必须使用模块化管理工具!

几个概念

包管理工具: 安装、卸载、更新、查看、搜索、发布包。比如你需要安装个jq等,通过npm来安装。npm里有依赖管理,假如jq或者说express升级了,原来代码不能用了。帮助你解决这个问题的就是npm。

模块化构建工具:webpack/requireJS/seaJS,等是用来组织前端模块的构建工具(加载器)。通过使用模块化规范(AMD/CMD/CommonJS/es6)的语法来实现按需加载。举个栗子,如果有一天你不用维护一个很长很长的公用脚本文件,这得感谢它。

模块化规范::AMD/CMD/CommonJS/es6模块等等规范,规范了如何来组织你的代码。一般这种方式写的代码浏览器不认,需要用模块化构建工具来打包编译成浏览器可以识别的文件。

从我的表格里,可以看出我的推荐搭配———— npm +webpack + es6模块。

理由如下:

npm与bower比较:

  • 原来bower的使用优势就是适合前端模块管理,而npm被视为只适合后端的管理。但是随着webpack的流行,这个已经毫无疑问是npm胜出了。npm+webpack,可以实现良好的前端模块管理。

webpack和requireJS比较:



几种模块化规范比较:

所以就决定是你了! npm + webpack + es6模块。

作者:曾广营

来源:51CTO

时间: 2024-08-03 07:45:53

前端模块化要解决的两个问题的相关文章

干货|大数据应用:前端模块化开发的价值

随着大数据将各行各业的用户.方案提供商.服务商.运营商以及整个生态链上游厂商融合到一个大环境中,大数据应用前端开发变得越来越复杂.最早JS(javascript)需求简单,是一种面向过程的写法,也就是写函数,后来引入面向对象的开发思想,到现在写成类.随着应用程序的增多,JS代码复杂度越来越高,如何管理.组织.优化成为摆在企业技术部门面前的一个现实问题. 模块化开发并不新鲜,但在 国内Web 领域,无论是前端开发还是新生岗位,都保留着比较落后的编码习惯.直到近年,随着各种前端框架的推广和流行,模块

求助Windows底层高手解决在两个不同进程中打开的excel表格之间传输信息的问题

问题描述 求助Windows底层高手解决在两个不同进程中打开的excel表格之间传输信息的问题 如果在同一进程内开启的excel表格,是很容易在A表格跟B表格之间互相link内容随时更新的. 但是,如果C盘和D盘被严格地隔离了,在C盘开启的excel表格和D盘开启的excel表格不是同一个进程中的,那么就不能随时link内容了. 怎么样才能在excel表格内书写代码,从进程读取另一个表格的数据呢? 求解答! 还有好多出如此类的问题,希望能找到在Windows底层的编程高手长期合作啊~~ 解决方案

sql-求解决oracle两个表数据匹配的问题

问题描述 求解决oracle两个表数据匹配的问题 是这样,有两个表 A 和B 要求得出只要A_id的开头和B表中的A_num的数据匹配,就将B的value添加进去 结果应该是这样: 其中A标的数据量有十万多,B表的有四千多. 这个需求应该怎样高效的实现? 想了很久都没得思路,求大神帮助啊! 解决方案 select a.*,b.value from a,b where instr(a.a_id,a_num)=1 解决方案二: 排版乱了,应该这样 结果 解决方案三: select a.*, b.va

前端flex后台java的两个独立项目在myeclipse中如何部署到tomcat

问题描述 前端flex后台java的两个独立项目在myeclipse中如何部署到tomcat 我是刚接触前段用flex后台用java的项目,在Myeclipse中分别导入项目后,两个项目怎么编译?以及在deploy project,弹出来的窗口中选择框里没有我刚才导入的那个项目.请问这样的项目怎么部署到tomcat中,如果要手动部署怎么部署?我是新手菜鸟,希望大神能帮我指点详细一点,谢谢,谢谢,谢谢............快过年了,祝您,身体健康!阖家欢乐!财源广进! 解决方案 设置不同的端口即

前端模块化设计思路

模块化概念 模块化就是为了减少循环依赖,减少耦合,提高设计的效率.为了做到这一点,我们需要有一个设计规则,所有的模块都在这个规则下进行设计.良好的设计规则,会把耦合密集的设计参数进行归类作为一个模块,并以此划分工作任务.而模块之间彼此通过一个固定的接口(所谓的可见参数)进行交互,除此之外的内部实现(所谓的隐参数)则由模块的http://www.aliyun.com/zixun/aggregation/7434.html">开发团队进行自由发挥. 程序模块化的目的: 减 少循环依赖减少耦合提

C#向线程中传递多个参数的解决方法(两种)_C#教程

问题: 对于多线程编程,很多时候往往需要向线程中传递多个参数,而C#中的线程只接收1个object类型的参数(如下): Thread t = new Thread(new ParameterizedThreadStart(newthread)); t.start(参数); void newthread(object) { ............. } 而现在需要往线程中传递多个参数,比如method方法想用单独的线程来跑 void method(int begin,int end) { ...

移动广告有待解决的两大问题

硅谷网讯 6月17日消息,今年全球移动广告收入 预计将达到114亿美元,这一发展潜力巨大的市场引起了 Facebook等网络巨头和 众多初创企业的关注, 但是怎样才能做好移动广告呢?投身移动广告的初创企业应当 瞄准什么方向呢? 在日前发表于科技博客网站TechCrunch的一篇文章中,硅谷知名风投机构RedpointVentures的合伙人克里斯•摩尔(ChrisMoore) 提出了移动广告领域有待解决的两大问题和前景看好的三大发展方向: 一.两大有待解决的问题 目前的移动广告领域恰似1996到

django中使用jquery ajax post数据出现403错误的解决办法(两种方法)_AJAX相关

在django中,使用jquery ajax post数据,会出现403的错误 方法一: 如果用jQuery来处理ajax的话,Django直接送了一段解决问题的代码.把它放在一个独立的js文件中,在html页面中都引入即可.注意这个js文件必须在jquery的js文件引入之后,再引入即可 $(document).ajaxSend(function(event, xhr, settings) { function getCookie(name) { var cookieValue = null;

详解前端模块化工具-webpack

webpack是一个module bundler,抛开博大精深的汉字问题,我们暂且管他叫'模块管理工具 '.随着js能做的事情越来越多,浏览器.服务器,js似乎无处不在,这时,使日渐增多的js代码变得合理有序就显得尤为必要,也应运而生了很多模块化工 具.从服务器端到浏览器端,从原生的没有模块系统的`<script>`到基于Commonjs和AMD规范的实现到ES6 modules.为了模块化和更好的模块化,我们总是走在探索的路上. 但是这些实现模块化的方法或多或少都有他们的缺点.比如说使用`&