为什么需要web模块

这是原文的地址:why web modules?

这篇文章是摘自requirejs官网里的一篇文章,个人觉的从这里可以找出前端为什么需要引入模块思想

我们先来看看,没引入模块之前,将要面临的问题:

  • web 站点向 web app发展
  • 代码越来越大
  • 构建越来越困难
  • 开发者想分离JS文件
  • 开发者想优化代码以提高http性能

解决方案

前端开发者可能需要以下的方案:

  • 类似于后端里的import/include/require 关键字语法
  • 加载依赖的能力
  • 一个容易使用的前端优化工具

先看看以有的第三方实现

脚本加载器

先整理出一些可选的第三方加载库

  • Dojo: dojo.require('some.module')
  • LABjs: $LAB.script('some/module.js')
  • CommonJS: require('some/module')

这些方法都可以加载指定的JS文件,理想情况下,我们可以使用commonJS语法来加载JS,因为以后越来越多的库使用它,而且我们想我们的代码可以重用.我们还需要某种语法,将允许装载今天存在纯JavaScript文件 - 开发人员不应该重写他们的JavaScript来获取脚本加载的好处。

但是我们需要一个在浏览器端运行的很好的加载库,commonJS require()是一个同步方法,默认是立即返回的,但是这个在浏览器内是不可能的.

异步与同步

下面的例子表明异步与同步的一个区别

var person = require('module/person');

function Manager(){
    this.reports = [];
}

Manager.prototype = new person; // --> browser is error

假如这个在NodeJS里运行是没问题的,模块会同步执行返回,但是在浏览器端,脚本显然会异步返回,这时候调用它的实例就会报错,那么我们怎么处理浏览器端的异步呢?

XHR 加载脚本

我们可以临时使用XMLHttpRequest(XHR)来加载脚本--通过正则获取到上面内容中的的模块,然后利用eval()或者script元素来把XHR返回的内容添充到text属性中或者eval执行它.

使用eval方法是不规范的:

  • 开发者从一开始就被教导不能使用eval
  • 有些执行环境不允许使用eval
  • eval很难调试,目前只有firbug,chrome提供的inspector有选项来指定eval文本的路径
  • eval上下文很难跨浏览器,也许只有在ie中使用execScript方法,这些就会导致代码块的差异

使用script标签来包含XHR的内容也是不对的:

  • 当调试出现bug的时候,出现的错误代码行号跟原始文件行号不一致

使用XHR来加载文件本身就有跨域的限制,虽然现在的浏览器已经支持跨域请求,但是IE是通过使用XDomainRequest对象,显然不规范导致的代码越多就越容易出问题;而且为了保证跨域访问被对允许,必须发送标准的请求头.

Dojo目前就是以XHR为基础然后使用eval来加载模块的,针对跨域使用xdomain来处理,所以XHR加上eval是可以用来加载模块的,只是这样对开发者来说负担太大了.

如果我们想创建一个模块加载器的话,其实我们可以做的更好的

Web Worker 加载脚本

web worker 有可能是加载JS模块的另一种方法, 但是:

  • 不能跨浏览器
  • web worker是以消息机制来通讯的,在worker线程内的JS是不能访问DOM的,所以只能通过eval或者script标签来解析内容,这样的话就会出现上面XHR方式带来的问题

Document.write 加载脚本

document.write能够用来加载脚本,因为它支持跨域,而且能够正常的显示脚本,方便调试

不过它不能立即执行,虽然理想情况下能保证依赖全部加载,但是只能在脚本执行完之后才能访问到里面的JS代码

而且document.write在页面加载完成之后就不会再执行,这样就不能实现按需加载,通常只在用户需要某个功能的时候再加载JS是能够有效的提高网站性能

Head.appendChild 加载脚本

先看下面的代码片段:

var script = document.createElement('script');
script.src = 'feenan.js';

document.getElementsByTagName('head')[0].appendChild(script);

head.appendChild相比于上面的方式来说有一点复杂,不过这只是基本的想法,跟document.write相比,它不会阻塞页面渲染而且页面加载完之后还能继续调用

不过也有一个致命的问题,跟同步相比不能立马执行完,理想的情况是,模块加载有保证所有的依赖在执行脚本之前就加载完毕.

函数包装

了解了上面的几种方案,都有几个相同的问题,所以我们需要自己构建模块加载,处理依赖关系,像下面这样的:

defind(
    // 模块名称
    'feenan',
    // 模块依赖
    ['zepto'],
    // 传递依赖参数
    function($){
        return {
            init: function(){
                console.log('hello feenan!');
            }
        }
    }
);

上面的是requirejs的语法,假如只是想请求简单的JS文件,可以像下面这样写,不需要define关键字.

require(['zepto'], function($){
    // 此处就可以调用zepto的方法了,$只是别名
})

选择这种语法是因为这比较简单,并且允许使用像head.appendChild那样来加载JS

浏览器端的commonJS跟上面不一样的是,需要额外对现有的代码包装一层,这个会影响调试

想了解更多的关于AMD规范的模块机制,可以参考这篇文章,why AMD 有空再来篇中文版的!

时间: 2024-09-10 13:04:33

为什么需要web模块的相关文章

Web模块测试过程(利用JMeter工具)

web|过程 关于性能测试软件Jmeter的简单使用(图示)1.  首先要下载jmeter这个软件,现在最新的是2.03版本的.要注意下载它的二进制版本,解压后,找到/bin/目录下的jmeter.bat.如下图:   2.  点击它.如下图:   以下步骤均为中文显示,比较简单,只要按步骤操作,就可以得到相应的结果.   线程组为模拟用户,可以设置模拟用户的数量,循环的测试.以及测试开始的时间,结束的时间(选中调试器配置单选框). 3.     添加测试结果监听器,并选择测试结果输出的样式.(

j2ee-服务器不支持3版本的J2EE Web模块规范

问题描述 服务器不支持3版本的J2EE Web模块规范 服务器不支持3版本的J2EE Web模块规范 提示我The server does not support version 3.0 of the J2EE Web module specification. 怎么办?怎么解决?我用的是tomcat6.0,是因为版本太低了么???

eclipse上搭建maven多模块Java Web项目

1.模块化需求及项目模块说明 手头上有个已上线的系统,但因老板的特殊要求,系统需要不断的修改.还有就是公司市场部不定期地在举行一些微信活动,每一个活动都是周期性的,活动完了这个功能就要在系统中移除. 系统中就有三种模块:已经在系统中正常运行不需要再变更的模块.经常性变更的模块.用完就要移除的活动模块. 所以,我们需要把项目分成了下面几个模块. 简单说明一下: timetable-common是常用工具包存放的模块. wechat-api是微信接口模块,此模块用到了timetable-common

maven分模块web项目的单元测试

问题描述 maven分模块web项目的单元测试 50C 最近几天搞了个maven分模块的web项目的小demo.springMVC+spring+mybatis.总配置文件写在web模块中.web模块依赖service模块,service模块依赖dao模块,dao模块中有实体类和maping配置文件和dao接口.现在想分层进行单元测试.求大神指导 .在线等. 解决方案 MAVEN WEB项目 单元测试 解决方案二: 已经分模块了,各个模块用各个模块的单元测试 . 解决方案三: 用 junit @

用C++ Builder开发Web程序

Web应用程序是运行在服务器端的可执行程序或动态链接库.它们可以响应用户要求,动态产生超文本页面,并将信息提供给客户浏览器. 由于Web应用程序的标准并不相同,程序的写法各异,这样就给开发者造成不小的困扰,因为开发人员不太可能了解每一种标准的写法.而C++ Builder可以很好地解决这个问题. C++ Builder将Web应用程序的开发封装成组件,使开发者面对一致的开发界面,使用一致的开发原理,惟一不同的地方在于开始产生程序时所选择的程序结构,至于程序的编写细节和方式都一模一样.本文通过两个

用Sun ONE Studio构造Web服务

Web服务使用一个复杂的体系结构为客户应用程序提供一个简单机制来从服务器应用程序调用方法和获取结果,而不用计较源代码使用的语言和主机平台有什么不同.Sun ONE Studio提供的工具让开发者能够使用包含在现有的Java类中的Web服务.方法--而不需要对这种体系结构有更深的了解.本文从一个基于servlet的Web模块中创建一个Web服务,演示如何使用现有的服务逻辑来生成新的客户应用程序. 介绍 回顾一下Web服务的核心技术--XML和简单对象访问协议( SOAP)--很明显这些技术实现已经

J2EE Web服务客户端质量报告(二)

服务器Web 服务软件包 服务器Web 服务软件包可自动生成.在Sun ONE Studio中,Web模块的创建只要选择一组EJB Java方法即可,并且Web服务软件包的类可由Web模块创建. 该软件包包含许多类和接口.这里最关键的一个就是<ServiceName>ServantInterface_Tie 类,在这个类中服务名就是<ServiceName> .类Tie是Web服务模块最上面的堆栈:它将引入的服务调用绑定到创建它的EJB组件上.我们只需修改类Tie就可以添加次数纪录

基于Struts 2开发Web应用

引言 作为 Java Web 应用的典型框架,Struts 一直受到 Java 开发者的青睐,Struts 2 作为 Struts 发展的又一个里程碑,以 WebWork 为基础,提供了更易于使用,功能更强的 MVC 框架.同时它可以帮助开发人员更快速.高效.方便地实现一个 Java Web 应用系统. 对于开发人员来讲,不同的项目可能需要不同的开发和运行 Struts 2 的平台,Struts 2 需要以下环境:Servlet API 2.4, JSP API 2.0, Java 5.IBM

Maven使用笔记(六)使用Maven进行多模块拆分

模块拆分是Maven经常使用的功能,简单梳理一下如何使用Maven进行多模块拆分, 只做归纳总结,网上资料很多,不再一步一步实际创建和部署. 1.建立Maven多模块项目 一个简单的Java Web项目,Maven模块结构是这样的: 上述示意图中,有一个父项目(parent)聚合很多子项目(mytest-controller,mytest-util, mytest-dao, mytest-service, mytest-web).每个项目,不管是父子,都含有一个pom.xml文件.而且要注意的是