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等等,下次再聊那种状况。

相关文章
相关标签/搜索