Webpack multi page Application Architecture Series (4): old jQuery plug-ins can not be lost, how compatible?

::::::: 2020-11-06 01:22:59
webpack multi page application architecture

This article was first published in Array_Huang Technology blog —— Practical first , Without the consent of the author , Do not reprint . Original address :https://segmentfault.com/a/1190000006887523 If you are interested in this series of articles , Welcome to subscribe here :https://segmentfault.com/blog/array_huang


At present, although the front end is in the stage of blooming flowers ,angular/react/vue Competing for , But after all, it is not yet fully mature , Some needs still depend on our big brother jQuery Of .

Personally, I am right jQuery It's not against , But I am jQuery Ecological stagnation is quite helpless , For example, the famous bootstrap( especially 3 generation ), stay webpack You have to rely on a loader Of , I can't keep up with the times . Besides, ,bootstrap It's not bad , There are some jquery The plug-ins haven't been updated for a year or two , even NPM They're not on the shelves , But they just can't find a substitute for them , The project is in a hurry again , What can I do ?

Don't worry. , Today I'll teach you how to adapt to the old style jQuery plug-in unit .

old-fashioned jQuery Plug ins are and cannot be used directly webpack pack ?

If you put jQuery As a common js Module to load ( Want to use jQuery All the modules of the first require Reuse later ), that , When you load the old jQuery When the plug-in , It often indicates that you can't find jQuery example ( Sometimes it's a hint that you can't find $), Why is this ?

Explain the problem , You have to explain it a little bit jQuery Plug in mechanism :jQuery Plug in is through jQuery Provided jQuery.fn.extend(object) and jQuery.extend(object) These two methods , To mount the methods implemented by the plug-in itself to jQuery( That is to say ) On this object . Traditional citation jQuery And the way to plug-in is to use <script> load jQuery In itself , Then use the same method to load its plug-in ;jQuery Will be able to jQuery Object set as global variable ( Of course, it also includes

and webpack As a build tool that follows the principle of modularity , Naturally, it is necessary to separate the context of each module to reduce the influence between them ; and jQuery It's already adapted to AMD/CMD And so on , let me put it another way , We are require jQuery When , It doesn't actually put jQuery Object set as global variable . Speaking of this , The problem is also obvious ,jQuery Plugins can't find jQuery Object , Because in their respective contexts , There are no local variables jQuery( Because there's no fit AMD/CMD, So there's no corresponding require Statement ), There are no global variables jQuery.

How to be compatible with the old jQuery Plugins ?

There are many ways , Let's take a look at one by one .

ProvidePlugin + expose-loader

First of all, I would like to introduce my most recommended method :ProvidePlugin + expose-loader, Projects in my company , And my personal open source scaffolding project webpack-seed It's all in this way .

ProvidePlugin The configuration of is as follows :

 var providePlugin = new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',

ProvidePlugin The mechanism is : When webpack Load to some js In the module , There is an undefined name that matches ( The string exactly matches ) Configuration in progress key Of variables , automatically require Configuration in progress value As specified by the js modular .

As in the example above , When an old plug-in uses jQuery.fn.extend(object), that webpack It will automatically introduce jquery( Here I use NPM Version of , I also recommend using NPM Version of ).

in addition , Use ProvidePlugin There's another benefit , Namely , In your own code , Again ! also ! No ! use !require!jQuery! La ! After all, one less sentence is one sentence. Ha ha .

Next up expose-loader, This loader The role of is , Will specify js modular export The variable of is declared as a global variable . Let's take a look expose-loader Configuration of :

Obviously this is a loader Configuration item for , Only a limited amount of space is available
If you don't understand, go to another article in this series 《webpack Multi page application architecture series ( Two ):webpack What are the common parts of configuration ?》:https://segmentfault.com/a/1190000006863968
test: require.resolve('jquery'), // this loader The goal of the configuration item is NPM Medium jquery
loader: 'expose?$!expose?jQuery', // The first jQuery Objects are declared as global variables `jQuery`, It is further declared as a global variable through the pipeline `$`

You might ask , With ProvidePlugin Why do you need to expose-loader? Good question. , If you have all jQuery Plug ins all use webpack To load , It works ProvidePlugin That's enough ; But the ideal is full , The reality is bone feeling , There are always some needs that can only be used <script> To load the .


externals yes webpack An item in the configuration , Used to put a global variable “ camouflage ” Into some js Modular exports, Like the following configuration :

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

that , When a js The module explicitly calls var $ = require('jquery') When , It will window,jQuery Back to it .

With the above ProvidePlugin + expose-loader On the contrary , The plan is to use <script> Loaded jQuery Satisfy the old-fashioned jQuery The need for plug-ins , Re pass externals Convert it to something that meets the requirements of modularity exports.

I personally don't think much of this practice , After all, that means jQuery Out of the NPM Management of , But some children's shoes have other considerations , For example, in order to speed up the time of each packing jQuery These larger third-party libraries are separated ( Call public directly CDN Third party library ?), It can be regarded as having certain value .


This program is equivalent to the manual version of ProvidePlugin, I used to use requireJS It's the same thing you do when you're doing it , So I started with requireJS Migrate to webpack It's the same way when you use it , Later I learned that there was ProvidePlugin It changed right away .

I won't go into details here , Let's take an example and you can see :

// ./webpack.config.js
module.exports = {
module: {
loaders: [
test: require.resolve("some-module"),
loader: "imports?$=jquery&jQuery=jquery", // amount to `var $ = require("jquery");var jQuery = require("jquery");`


All of the above plans are actually shimming, Not specifically for jQuery, Please draw inferences from one instance and use . in addition , The above scheme is not only for shimming, For example, use ProvidePlugin To write less require, Dig more for yourself , It's fun ~~


misuse externals(2016-10-17 to update )

I have children's shoes. I'm , Said that used my article's plan still prompt $ is not a function, After my careful analysis , Find out :

  1. He used what I recommended ProvidePlugin + expose-loader programme , in other words , He has jquery Packed in .
  2. But he didn't know what to do with it externals:
 externals: {
jquery: 'window.jQuery',
  1. But in fact he didn't use it directly <script> To quote jQuery, therefore window.jQuery It's a null.
  2. result , His jquery Plug ins get $ That's it. null 了 .

In this we can see that ,externals It will cover up ProvidePlugin Of .

But there's a problem here ,expose-loader The purpose of this is to set up window.jQuery and window.$, that window.jQuery How could it be null Well ? My guess is :externals stay expose-loader Set it up window.jQuery I've taken it before window.jQuery Value (null) 了 .

Said so much , In fact, the key meaning is , Don't be cheap. Don't be cheap. Don't be cheap ( Important things are to be repeated for 3 times )!

Sample code

Look at this series of articles , With me in Github It's better to eat the scaffold project on ( laugh ):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed).

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .


  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云