ASP.NET MVC4 捆绑(Bundle)技术下的 JavaScript

简介:

说到 Web 应用中 JavaScript 的模块化,很容易想到 RequireJS、SeaJS 和 ECMAScript 6。ES6 要全面应用还得有段时间,RequireJS 和 SeaJS 的模块化在实际应用中又有两个分支:一是通过按需加载的方式加载并创建模块,二是通过工具打包成单一文件,一次性加载,按需创建模块。ASP.NET MVC4 的捆绑(Bundle)技术类似后者。


MVC4 Bundle 主要用于优化 JavaScript 和 CSS 资源的加载。关于这个技术的介绍,可以参考《ASP.NET Mvc4 Bunlde 捆绑压缩技术》,或者《CSS编程:捆绑和缩小》。其特点很鲜明,主要有两点:


  1. 在开发环境,加载原文件,便于定位和 Debug;

  2. 在生产环境,按配置将所有资源分类打包压缩,优化浏览器对资源加载。


也正是由于它的这两个特点,如果要使用 Bundle 技术,就很难使用现有的 JavaScript 模块化工具来进行开发。翻了下百度和 Google,没找到合适的解决方案,于是决定自己写个简单的模块加载器,主要实现如下目标:


  1. 模块化开发

  2. 大部分 JavaScript 文件由 MVC4 一次性加载,但模块按需创建

  3. 部分页面的脚本,可以按页面需要单独加载,但同样是模块化的


分析目标,归整一下,大概有如下要点需要实现


  1. 由于 Bundle 之后模块不能以文件为单位,所以需要重用的模块都应该是命名模块。考虑到具体页面自己的模块不需要重用,所以这种情况下可以定义为匿名模块。所以模块定义函数要像这样:

    1
    2
    3
    4
    5
    6
    7
    funciton define(name, factory) {
         if  (isFunction(name)) {
             factory = name
             name = undefined
         }
         // ......
    }

    模块名称唯一性由人来控制,但是应提供检查机制,所以如果出现重复定义的情况,抛出异常。由是在一个项目中,命名冲突这种情况应该不是主要矛盾。如果不幸命名冲突成为了主要矛盾,基本上也可以通过定义命名空间来解决。最简单的命名空间就是在模块名中加入命名空间部分,比如 "app.core.codec.hexcode"


  2. 按需加载,使用 require 函数

    1
    2
    3
    function  require(moduleName) {
         // ......
    }


  3. 执行模块的入口。虽然可以用 require 作为入口,但是 require 需要一个模块名称作为参数,不能用于匿名模块作为入口的情况。假想如下应用场景:

    1
    2
    3
    define( function () {
         // ......
    }).use()

    要实现这种应用场景,就需要 define 返回一个对象,该对象拥有 use 方法,可以通过 use 方法一次性调用当前模块的 factory 函数。比较简单直接的方式就是在内部定义一个 Module 类来装载模块配置,在 define 的时候生成 Module 对象,并返回出来。

    1
    2
    3
    4
    5
    6
    function  define(name, factory) {
         // ......
         var  module =  new  Module(factory)
         // ......
         return  module
    }


  4. 内部模块管理。通过一个 map<name, module> 来管理所有模块定义,这在实现上就是一个普通的 JavaScript 对象。匿名模块因为是立即使用,所以不需要进行管理。模块管理的核心其实是 Module 类,需要通过它完成创建模块、缓存导出对象和提供导出对象等。而且除了 use 方法需要暴露出来之后,其它方法都应该隐藏起来。

    经过参考、推敲和实验,得出了如下的一个代码框架

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 这是所有命名模块保存的地方
    var  modules = {}
     
    function  Module(name, factory) {
         // 创建模块对象,保存 factory 函数
    }
     
    Module.prototype.use =  function () {
         // 执行 factory 函数
         // 处理 exports 和 isExported 等状态
         return  exports
    }
     
    function  define(name, factory) {
         // 定义并保存模块
         modules[name] =  new  Module(name, factory)
    }
     
    function  require(name) {
         // 按名称找到模块,并执行之
         return  modules[name].use()
    }


在最终实现的时候,还需要处理容错,以及若干细节问题。最终代码命名为 js-modular.js,在附件中可以下载。在使用的时候只需要注意一点,页面上加载脚本的时候,记得把 js-modular.js 放在所有模块定义脚本之前即可。



目前已经建立了开源项目 jNs,基于命名空间的模块管理工具,是在 js-modular.js 的基础之上发展而来的。如果有兴趣的话,请关注一下这个项目。



本文转自边城__ 51CTO博客,原文链接:http://blog.51cto.com/jamesfancy/1598533,如需转载请自行联系原作者

相关文章
|
29天前
|
开发框架 JavaScript 前端开发
揭秘:如何让你的asp.net页面变身交互魔术师——先施展JavaScript咒语,再引发服务器端魔法!
【8月更文挑战第16天】在ASP.NET开发中,处理客户端与服务器交互时,常需先执行客户端验证再提交数据。传统上使用ASP.NET Button控件直接触发服务器事件,但难以插入客户端逻辑。本文对比此法与改进方案:利用HTML按钮及JavaScript手动控制表单提交。后者通过`onclick`事件调用JavaScript函数`SubmitForm()`来检查输入并决定是否提交,增强了灵活性和用户体验,同时确保了服务器端逻辑的执行。
34 5
|
19天前
|
数据采集 JavaScript 前端开发
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
爬虫技术是数据采集的关键手段。针对动态加载的网页,传统HTTP请求及HTML解析难以满足需求。本文章介绍如何利用ClearScript V8库在.NET环境中执行复杂的JavaScript逻辑,以提高爬虫对动态内容的抓取效率。文章首先概述了ClearScript V8的功能,如何处理如微博这类含有大量动态加载内容的网站。通过使用代理IP、设置cookie和user-agent等方式模拟真实用户访问,确保了爬虫的稳定性和隐蔽性。提供了一个具体的C#爬虫示例,演示如何结合ClearScript V8和HTTP客户端来实现上述功能。这种方法不仅增强爬虫的灵活性,也极大地提高数据采集的效率和可靠性。
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
|
12天前
|
前端开发 安全 Java
技术进阶:使用Spring MVC构建适应未来的响应式Web应用
【9月更文挑战第2天】随着移动设备的普及,响应式设计至关重要。Spring MVC作为强大的Java Web框架,助力开发者创建适应多屏的应用。本文推荐使用Thymeleaf整合视图,通过简洁的HTML代码提高前端灵活性;采用`@ResponseBody`与`Callable`实现异步处理,优化应用响应速度;运用`@ControllerAdvice`统一异常管理,保持代码整洁;借助Jackson简化JSON处理;利用Spring Security增强安全性;并强调测试的重要性。遵循这些实践,将大幅提升开发效率和应用质量。
39 7
|
18天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的图像识别技术深入理解Node.js事件循环及其在后端开发中的应用
【8月更文挑战第27天】本文将介绍深度学习中的图像识别技术,包括其原理、应用领域及未来发展。我们将探讨如何通过神经网络实现图像识别,并分析其在医疗、交通等领域的应用。最后,我们将展望图像识别技术的发展前景。
|
18天前
|
运维 Cloud Native JavaScript
云端新纪元:云原生技术深度解析深入理解Node.js事件循环及其在异步编程中的应用
【8月更文挑战第27天】随着云计算技术的飞速发展,云原生已成为推动现代软件开发和运维的关键力量。本文将深入探讨云原生的基本概念、核心价值及其在实际业务中的应用,帮助读者理解云原生如何重塑IT架构,提升企业的创新能力和市场竞争力。通过具体案例分析,我们将揭示云原生技术背后的哲学思想,以及它如何影响企业决策和操作模式。
|
1月前
|
存储 JSON 监控
JavaScript 逆向基础篇:浏览器调试与 Hook 技术
JavaScript 逆向基础篇:浏览器调试与 Hook 技术
48 1
|
1月前
|
存储 JavaScript 前端开发
使用Vue.js构建交互式用户界面的技术探索
【8月更文挑战第9天】Vue.js以其简洁的API、高效的性能、灵活的架构和强大的组件系统,成为了构建现代Web应用交互式用户界面的理想选择。通过掌握Vue.js的核心概念和最佳实践,开发者可以轻松地构建出既美观又实用的Web应用。随着Vue.js生态的不断发展和完善,相信它将在未来继续引领前端开发的潮流
|
15天前
|
JavaScript 开发者 UED
Vue.js 错误处理与调试:跟上技术潮流,摆脱开发困扰,成为代码大神不是梦!
【8月更文挑战第30天】在 Vue.js 开发中,错误处理与调试至关重要。本文将对比 Vue 的全局错误捕获机制 `Vue.config.errorHandler` 和组件内 `watch` 监听数据变化的方式,并介绍 Vue 开发者工具、控制台打印 (`console.log`) 以及代码断点 (`debugger`) 等调试方法。此外,还将探讨如何通过自定义错误页面提升用户体验。通过这些技巧的对比,帮助开发者灵活选择适合的策略,确保应用稳定性和开发效率。
37 0
|
15天前
|
JavaScript 前端开发 开发者
Vue.js 响应式变革来袭!结合热点技术,探索从 Object.defineProperty 到 Proxy 的奇妙之旅,触动你的心
【8月更文挑战第30天】在 Vue.js 中,响应式系统自动追踪并更新数据变化,极大提升了开发体验。早期通过 `Object.defineProperty` 实现,但存在对新旧属性处理及数组操作的局限。Vue 3.0 引入了 `Proxy`,克服了上述限制,提供了更强大的功能和更好的性能。实践中,可根据项目需求选择合适的技术方案,并优化数据操作,利用懒加载等方式提升性能。
27 0
|
29天前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
29 0