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文件內部。