如果有打开过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. Kinect for Windows V2.0 新功能

    系统要求: win8  or  win8.1 硬件要求: 64位(x64)处理器 i7 2.5-GHz或更快的处理器 内置USB 3.0总线 4 GB RAM DX11图形适配器 外观: 第二代Kin ...

  2. git简单教材

    0)初始化 $ git config --global user.name "xxx" $ git config --global user.email "xxx@gma ...

  3. HTML 速成

    html零基础者入. 记得学计算机网络的时候好像有学过一些HTML,但没运用起来都忘光了.近来想学学如何写网页.就从html(HyperText Markup Language超文本标记语言)入手了. ...

  4. 数据结构栈的java实现

    近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作“先进后出”表. 实现方式是这样的:首先定义了一个接口,然后通过这个接口实现了线 ...

  5. 网络tcp/ip资料

    1. Linux TCP/IP 协议栈分析,这是chinaunix.net论坛里的N人写的电子书,可以在这里下载PDF版本.http://blog.chinaunix.net/u2/85263/sho ...

  6. EntityFramework5提供的迁移工具

    目录 背景之前是如何做的?EntityFramework5提供了更好的选择备注 背景返回目录 刚毕业做项目的时候,没有用“迁移”这个概念,系统发布和更新的过程让人非常痛苦,在学习 Ruby On Ra ...

  7. Aspose.cells异步读写操作

    public class AsyncExcel : Excel { static readonly object _objForlock = new object(); //public List&l ...

  8. hdu1686

    题目意思:找到上串在下串中有多少个 Problem Description The French author Georges Perec (1936–1982) once wrote a book, ...

  9. 鸟哥的LINUX私房菜基础篇第三版 阅读笔记 一

    1. Linux的档案权限与目录配置      一.基础知识:             a.分为三类,拥有者(owner).群组(group).其他人(other)             b.三个核 ...

  10. json-smart 使用示例

    json-smart 使用示例 json是一种通用的数据格式.相比与protocal buffer.thrift等数据格式,json具有可读性强(文本).天生具备良好的扩展性(随意增减字段)等优良特点 ...