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,如需转载请自行联系原作者

相关文章
|
3月前
|
前端开发 JavaScript 测试技术
深入 JavaScript:理论和技术(下)
深入 JavaScript:理论和技术(下)
|
3月前
|
存储 JavaScript 前端开发
深入 JavaScript:理论和技术(上)
深入 JavaScript:理论和技术(上)
|
3月前
|
数据可视化 前端开发 JavaScript
数据可视化技术的较量:D3.js与Tableau的比较与选择
在当今信息爆炸的时代,数据可视化成为了帮助我们理解和传达数据的重要工具。本文将重点对比并评估两个主流的数据可视化技术和工具,即D3.js和Tableau。我们将探讨它们的优势、适用场景以及选择的关键因素,以帮助读者在选择合适的数据可视化工具时做出明智的决策。
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
38 0
|
28天前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
28 0
|
1月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
95 5
|
1月前
|
Rust 前端开发 JavaScript
前端技术的未来:WebAssembly与JavaScript的融合之路
【2月更文挑战第12天】本文旨在探讨WebAssembly(以下简称Wasm)与JavaScript(以下简称JS)的结合如何为前端开发带来革命性变化。传统上,JS一直是前端开发的核心,但随着Wasm的出现,我们看到了前端性能和功能的新天地。文章首先介绍Wasm的基本概念,然后分析其对前端开发的影响,包括性能提升、新功能实现以及开发模式的变化。最后,探讨了Wasm与JS融合的未来趋势,以及这种融合如何推动前端技术的进步。
|
1月前
|
Rust 前端开发 JavaScript
探索前端技术的未来:WebAssembly与JavaScript的融合之路
【2月更文挑战第12天】 随着Web技术的不断进步,前端开发正迎来一场革命性变革。本文将深入探讨WebAssembly(以下简称Wasm)与JavaScript(以下简称JS)的结合如何为前端开发带来前所未有的性能提升与新的编程模式。我们将从两者的基本概念入手,探索它们各自的优势与局限,然后深入分析Wasm和JS协同工作时能够解锁的潜力,最后展望这一技术趋势如何塑造未来的前端开发生态。本文旨在为前端开发者提供洞见,帮助他们理解并准备好迎接这一即将到来的技术浪潮。
|
1月前
|
Rust 前端开发 JavaScript
前端技术的未来演进:WebAssembly与JavaScript的深度融合
【2月更文挑战第11天】 在数字化时代,前端技术的迅速发展不仅推动了用户体验的革新,也促进了Web应用的性能提升。本文将探讨WebAssembly(以下简称Wasm)与JavaScript(以下简称JS)之间的深度融合如何成为前端技术发展的关键转折点。不同于传统的技术文章摘要,我们将通过一种叙事式的预览引导读者进入这一技术领域的探索之旅,揭示Wasm和JS结合后为前端开发带来的无限可能性和挑战。
|
2月前
|
前端开发 JavaScript API
JavaScript中的异步编程技术及应用
【2月更文挑战第2天】传统的JavaScript编程方式在处理异步操作时存在诸多不足,为了解决这一问题,近年来涌现出了一系列异步编程技术,本文将深入探讨Promise、async/await等异步编程解决方案,并结合实际案例展示其在前端开发中的应用。