webpack進階教程(二)——webpack引入jquery多種方法探究

對於webapck的初學者來說,最受挫的就是引入jQueryjQuery插件時,老是會遇到各類問題。在網上一搜,總能發現多種解決方案,什麼externalsprovidePluginvendor,export-loader等等。咱們搞不清楚,爲何會有那麼多的引用方法,我只是想引用一個jQuery插件而已。其實,webpack引用jQuery困難,是由於jQuery插件衆多,有的插件提供了模塊化支持,好比支持UMD,有的則沒有支持模塊化,直接引用全局的jQuerywindow.jQuery。下面,咱們來分幾中狀況,來討論一下webpack引入jQuery的幾種方法和它們的區別,來方便你們在實際項目中取捨。javascript

1.cdn引用jQuery

網上不少問,"怎樣在webpack裏全局引用jQuery"。我對"全局引用"的理解,就是把jQuery暴露到全局(瀏覽器是window)。雖然把jQuery暴露到全局是不推薦的,可是不少插件,尤爲早期的插件,是依賴全局的jQuery變量的。cdn引用jQuery,大可能是全局的引用。咱們來看個例子
注:如下例子源碼在github上,可經過相應的連接打開,clone下來後,能夠直接運行webpack-dev-server看效果,個人webpackwebpack-dev-server是全局安裝,你的若是不是全局安裝,運行前請自行安裝)。css

例子源代碼,能夠點擊這裏html

jqGreen.jsjava

//沒有模塊化
(function($){
    $.fn.green = function(){
        $(this).each(function(){
            $(this).css('color','green');
        })
    }
})(jQuery);

index.jsjquery

require('./jqGreen');
$('#green').green();

index.htmlwebpack

<!DOCTYPE html>
<html>
<head>
    <title>webpack引入jQuery(一)</title>
</head>
<body>
<div id="green">該段文字應該爲綠色</div>
<script src='http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js'></script>
</body>
</html>

webpack.config.jsgit

var htmlPlugin = require('html-webpack-plugin');
module.exports = {
    entry:{
        index:'./src/index.js'
    },
    output:{
        path:'builds',
        filename:'[name].js',
        chunkFilename:'chunk.[name].js'
    },
    plugins:[
        new htmlPlugin({
            filename:__dirname+'/builds/index.html',
            template:'./index.html'
        })
    ],
    devServer:{
        contentBase:'./builds',
        inline:true
    }
}

jqGreen.js是一個簡單的插件,功能是把選中的元素的color屬性設置爲green。咱們在index.js引用了這個插件。須要重點說明的是,jqGreen這個插件,沒有采用任何模塊化的方案,不少早期的jQuery插件都是這種寫法。上面的例子,沒有用externals,可是也能正常跑起來。關鍵就是這個插件jqGreen沒有任何模塊化方案。github

咱們運行webpack命令,編譯後的文件輸出到builds文件下,再運行webpack-dev-server,程序是能夠直接跑起來的。我例子裏的代碼是編譯過的,你們clone下來後,能夠直接在命令行運行webpack-dev-server把demo跑起來,而後打開http://localhost:8080查看效果。web

結論:若是jquery插件沒有采用任何模塊化方案,直接引用cdn上的jQuery,而後正常引用插件並打包就能夠正常使用。npm

那麼,若是個人jQuery插件,有模塊化方案呢?
咱們來改一下上面的jqGreen.js

//UMD模塊方案
(function(window,factory){
    if(typeof exports === 'object'){
        module.exports = factory(require('jquery'));
    }else if(typeof define === 'function' && define.amd){
        define(['jquery'],factory);
    }else{
        factor();
    }
})(window,function($){
    $.fn.green = function(){
        $(this).each(function(){
            $(this).css('color','green');
        });
    }
});

注意,這個時候,咱們的jQuery插件採用了UMD模塊化的方案。你們能夠直接把jqGreen改爲上面的這種UMD形式但不修改webpack.config.js文件。在example1運行webpack命令,會報錯,會提示找不到jquery。咱們查看builds文件夾下面的index.js文件時候,會發現
if(typeof exports === 'object')被webpack替換成了if(true),就是說,webpack編譯後的代碼,會執行module.exports = factory(require('jquery'));這段代碼。注意這裏面的require('jquery'),咱們並無在本地安裝jquery(沒有npm install jquery --save-dev),而是引用的cdn上的jquery,因此,require('jquery')是找不到'jquery'的,由於他不知道咱們是引用cdn上的jquery。那麼,怎麼才能讓webpack不報錯,能爭取引用呢?答案是externals

externals引用'jquery'

咱們只須要在webpack.config.js文件裏添加

externals:{
        'jquery':'window.jQuery'
    }

你們能夠看個人例子源碼,例子是能夠直接跑起來的。
上面的externals配置,告訴webpack,在編譯時,看到require('jquery'),就把它替換成window.jQuery。這樣,就實現了引用全局上的jQuery,咱們的例子,也能正常跑起來啦。
這裏多說一下,對於剛纔咱們的第一個例子,就是沒有采用任何模塊化方案的例子,用externals配置也是能夠的,那樣externals什麼也不會作,可是程序也能跑起來。

總之,若是要全局引用jQuery,無論你的jQuery有沒有支持模塊化,用externals就對了。

.IgnorePlugin引用jQuery

IgnorePlugin的示例代碼
IgnorePlugincnd引用jQuery,都是引用的未處理的jquery源碼文件。cdn上的jquery是無法打包(除非下載下來),而本地的jquerywebpack默認會對其打包,因此要用IgnorePlugin來告訴webpack不要打包。因此這種引用方式,也須要用externals來暴露全局變量,你們經過上面貼出來的連接,看看示例代碼就ok。

注意,咱們上面的例子,都是不對jquery打包的,因此頁面上的jquery.js都是一個單獨的文件。webpack固然也能把jquery打包在內,那樣就會用到CommonChunksvendor等等,下次再聊那種狀況。

相關文章
相關標籤/搜索