angular中使用了webpack作为依赖管理器,相较于之前在html
中使用<script type="text/javascript" src="xxxx"
的方式,使用webpack能够实现使在须要某些依赖的时候才进行加载。性能虽然好,但在使用一些历史的依赖于jquery的依赖时每每会出现找不到jquery
的问题。javascript
假设当前项目须要iCheck
插件,此插件依赖于jquery
。html
在javascript
中,能够经过向window
对象上添加属性的方式来实现全局变量。好比:java
var a = 'hello'; window.test = a; console.log(test);
jquery
能够经过npm
来进行安装,安装完成后可使用import
语句将其引入到当前的项目中。想到项目中随处使用$
、jQuery
的关键字,则须要将$
、jquery
声明为全局变量。打开angular中启动模块app.moudle.ts
并向其中加入如下代码:jquery
import * as jq from 'jquery'; ➊ declare var window: any; ➋ window.jQuery = jq; ➌ window.$ = jq; ➍
if ( !noGlobal ) { ➊ window.jQuery = window.$ = jQuery; } return jQuery; ➋ }));
如此一来即可以在项目中使用$
或jQuery
了。但因为typeScript是强类型的,因此在其它使用到$
的地方还须要声明$
的类型为任意类型。webpack
declare var $: any; console.log($);
iCheck
官方未给出使用npm安装的方法。咱们下载js文件后放到项目的任意文件中。iCheck
并未像jquery
同样进行相应的return
,因此也就不能像使用引入jquery
同样来进行引用了。这种状况则可使用require
方法来解决。假设当前icheck
文件的存储地址为:./../bower_components/iCheck/icheck
,则能够在成功引用jquery后使用如下代码引用icheck
。web
import * as $ from 'jquery'; declare var window: any; declare var require: any; ➊ window.jQuery = $; window.$ = $; require('./../bower_components/iCheck/icheck'); ➋
有些依赖已经能够经过npm进行安装,则引用起来就很简单了。只须要使用如下语句则能够完成引用:npm
require('依赖名');
在angular中使用jquery时,主要解决的是向window中添加全局变量的问题。当window中存在$
全局变量后,即可以在其它须要jquery
功能的地方使用$()
方法。当window中存在jQuery
全局变量后,其它依赖于该jQuery
的第三方依赖即可以成功的执行。app
大多依赖于jquery
的库会有如下格式:函数
(function($★) { // 功能代码 })(window.jQuery || window.Zepto);
这种写法还有一个好处是:此时$
变量为局部变量,不会对全局的$
形成影响
若是在执行到该代码时未引入window.jQuery
,则window.jQuery、window.Zepto的值均为undefined
,此时执行function($){ 依赖于$的功能代码 }
的功能代码时便会发生在undefined上调用xxx的错误。解决该错误的方法是在执行这段代码前将jQuery添加到window中。也就是本文的解决的方案。性能
那么为何引入jquery时使用的是import,而引用iCheck使用的是require呢。这是由jquery与iCheck的功能特色以及require及import的特色所决定的:
名称 | 功能特色 | 示例代码 |
---|---|---|
jquery | 定义对象,返回对象 | return jQuery |
iCheck | 执行了匿名函数 | (function(){ 这里是功能代码 })() |
名称 | 功能 | 必然执行 | 做用域 | 执行时机 |
---|---|---|---|---|
require('icheck') | 将icheck的代码复制到当前位置 | 是 | 应用上下文 | 当即执行 |
import * as $ from 'jquery'; | 声明变量$的来源 | 否 | jquery.js文件内部 | 使用$ 时执行 |
以示例代码为例:咱们须要jquery中的返回的jQuery对象,因此须要import
来进行引入(import * as $ from 'jquery';
)此时$的值为jQuery
。对于iCheck
而言咱们须要执行该匿名函数,因此使用require('iCheck')
。
简单来讲:require等于复制一份相同的js代码放在require
代码所在的位置上,因此js代码的做用域为上下文;import
等于建立一个js文件的引用(快捷方式),只有使用该引用时才会尝试找js文件要内容,此时js文件执行的做用域为此js文件内部。