如果有打开过jQuery的源码(从1.11及以后),或者Vue.js、React.js的源码,都会在文件的前面看见这样一段代码:

( function( global, factory ) {

	"use strict";

	if ( typeof module === "object" && typeof module.exports === "object" ) {

		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "jQuery requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		factory( global );
	}

// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
  //...

  

以上是jQuery V3.1.0的一段代码。如果自己平时写的都是在浏览器上运行的js代码,又没有接触过Node.js的,可能就不知道 ‘module.exports’ 是什么,为什么要加以判断了。如果有接触过Node,就知道 ‘module.exports’ 其实就是一个js文件的出口,相当于ES6的export。

现在。从头介绍如何写一个兼容浏览器和Node环境的js代码。假设这个js文件名为export.js。

首页,为了避免污染全局作用域,立即执行函数是必须的。这个函数的参数,就像上面的代码那样,也传入一个函数吧。

export.js代码如下:

(function(factory) {
  //判断宿主环境
}(function() {
  //代码的核心
}));

  

接下来,就是判断宿主环境。在浏览器环境下,window这个变量是无需创建,自动生成的;在Node环境下,module同理。export.js代码如下:

(function(factory) {
  if (typeof module !== 'undefined') {
    module.exports = factory();
  } else {
    factory();
  }
}(function() {
  var vue = 30;
  //...
}));

  

判断了宿主环境后,现在我们需要获得已经定义了的变量vue。在浏览器环境下,用形如

window.vue = vue;

  

这样的语句让vue这个变量变成全局的;而在node环境下,export.js用

return vue;

  

而需要用到这个变量的文件加上这么一句:

var vue = require('./export.js');

  

这样的语句获得vue这个变量。export.js代码如下:

(function(factory) {
  if (typeof module !== 'undefined') {
    module.exports = factory();
  } else {
    factory();
  }
}(function() {
  var vue = 30;
  if (typeof window !== 'undefined') {
    window.vue = vue;
  } else {
    return vue;
  }
}));

  

其实,在看了Vue.js的这部分代码后,发现了一个更便捷的方式,就是把vue这个全局变量放在function(factory)里面,这样,下面只要写一个return vue; 就可以了。export.js代码如下:

(function(factory) {
  if (typeof module !== 'undefined') {
    module.exports = factory();
  } else {
    window.vue = factory();
  }
}(function() {
  var vue = 30;
  return vue;
}));

  

如何写兼容浏览器和Node.js环境的Javascript代码的更多相关文章

  1. 编写浏览器和Node.js通用的JavaScript模块

    长期以来JavaScript语言本身不提供模块化的支持, ES6中终于给出了 from, import等关键字来进行模块化的代码组织. 但CommonJS.AMD等规范已经被广为使用,如果希望你的Ja ...

  2. 手把手教你webpack、react和node.js环境配置(上篇)

    很多人刚学习react的时候,往往因为繁琐的配置而头疼,这里我将手把手教大家怎么用webpack配置react和redux的环境,这篇教程包括前端react和后台node整个网站的环境配置,对node ...

  3. 如何在 Windows 10 中搭建 Node.js 环境?

    [编者按]本文作者为 Szabolcs Kurdi,主要通过生动的实例介绍如何在 Windows 10 中搭建 Node.js 环境.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 在本文中 ...

  4. 认识Web前端、Web后端、桌面app和移动app新开发模式 - 基于Node.js环境和VS Code工具

    认识Web.桌面和移动app新开发模式 - 基于Node.js环境和VS Code工具 一.开发环境的搭建(基于win10) 1.安装node.js和npm 到node.js官网下载安装包(包含npm ...

  5. paip.最好的脚本语言node js 环境搭建连接mysql

    paip.最好的脚本语言node js 环境搭建连接mysql #====下载node...走十一个exe..容易的.. 1 #0----Hello world   .js 2 #---------模 ...

  6. 阿里云 CentOS7.2 配置FTP+Node.js环境

    本人小白,写下这篇博客意在记录踩过的坑,大神请绕道~ 准备工作 安装自己喜欢的连接软件(一般是putty或者xshell),本人选择的是xshell,软件如图 : 通过软件中的ssh连接连接上已经购买 ...

  7. 手把手教你webpack、react和node.js环境配置(下篇)

    上篇我介绍了前端下webpack和react.redux等环境的配置,这篇将继续重点介绍后台node.js的配置. 这里是上篇链接:手把手教你webpack.react和node.js环境配置(上篇) ...

  8. mac 上node.js环境的安装与测试

    如果大家之前做过web服务器的人都知道,nginx+lua与现在流行的Node.js都是可以做web服务器的,前者在程序的写法和配置上要比后者麻烦,但用起来都是差不多.在这里建议大家如果对lua脚本语 ...

  9. 【转载】Centos系统采用NVM安装Node.js环境

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...

随机推荐

  1. 用mysql dump 导入与导出的方法

    用mysql dump 导入与导出的方法 分类: 数据库2009-12-08 00:04 6825人阅读 评论(0) 收藏 举报 mysql数据库deleteinsertinternetdatabas ...

  2. 深入分析ENode的内部实现流程和关键地方的幂等设计

    ENode 2.0 - 深入分析ENode的内部实现流程和关键地方的幂等设计 前言 ENode架构图 ENode框架内部实现流程分析 Command的幂等处理 Domain Event持久化时的并发冲 ...

  3. Indenting source code

    Artistic Style 1.15.3 A Free , Fast and Small Automatic Formatterfor C , C++ , C# , Java Source Code ...

  4. 细节MARK

    在刷vijos1046的时候遇到了一些细节,MARK一下 1.哲学之前有告诫我说,输出long long的数的时候,最好用cout,不然容易出现编译器的问题,今天算是领教了 2.对于数组赋值问题 me ...

  5. c# 服务程序重启自身

    由于工作有这样的需求,于是各种寻找,但是都不满意,偶然间想起一个方法 1.修改服务的Program.cs文件如下 static void Main(string[] args) { //LoadFil ...

  6. Nginx+phpfastcgi下flush输出问题

    最近由于业务需要,需要使用php的flush输出缓存刷新,处理浏览器超时问题. 最初的测试代码如下: ob_start();//打开缓冲区 for ($i=10; $i>0; $i--) { e ...

  7. Forms Authentication in ASP.NET MVC 4

    原文:Forms Authentication in ASP.NET MVC 4 Contents: Introduction Implement a custom membership provid ...

  8. SQLSERVER利用FOR XML PATH实现分组拼接字符串

    首先看一下数据结构表 IF(OBJECT_ID('tempdb..#tProduct')IS NOT NULL) DROP TABLE #tProduct SELECT * INTO #tProduc ...

  9. jQuery Validation让验证变得如此容易(三)

    以下代码进行对jQuery Validation的简单演示包括必填项.字符长度,格式验证 一.引入文件 <script src="js/jquery-1.8.0.min.js" ...

  10. java正则表达式验证汉字

    统计指定内容的汉字个数: String str = "北京欢迎你 hello welcome!"; int count=0; Pattern pattern = Pattern.c ...