如何在Webpack中正确地向jQuery对象添加jQuery插件?

19

TL;DR 如何使用webpack扩展jQuery对象,将其全局暴露并在ES6模块中使用外部AMD库?对于重构遗留应用程序到ES6模块,webpack是否是正确的工具,或者SystemJs更适合这种情况?

我正在尝试理解如何使用webpack和ES6模块。我有一个遗留的主要使用jquery的应用程序,现在正在进行转换。我面临以下挑战:

  1. 查找webpack/babel-loader工作流程的最佳实践
  2. 弄清楚为哪个目的使用哪个loader/plugin
  3. 使像jquery和jquery插件这样的AMD资源与其他模块兼容。
  4. 将扩展了所有插件和jquery-ui的jquery全局暴露

我依赖于以下资源: 这个很好的答案解释了很多,虽然它没有提到exports loader,但我主要依赖它: https://dev59.com/bF4b5IYBdhLWcg3wiiV4#28989476

http://webpack.github.io/docs/shimming-modules.html - 这份文档列出了许多可能性,但我缺乏经验来决定哪一个是正确的。似乎使用ProvidePlugin比expose-loader更受欢迎。不幸的是,我没有用扩展jQuery对象使其工作。它也不能用于在<script>标记中调用模块函数。

我仍然在努力寻找编程解决方案,并决定哪个webpack插件是正确的选择。非常感谢有经验的webpack用户提供一些建议或示例。

在我的webpack.config.js中,我有以下的加载器来暴露jquery并使用babel进行转译:

module: {
    loaders: [
        { 
            test: /\.js$/, 
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {modules: 'common'}
        },
        {
            test: /jquery\.js$/,
            exclude: /node_modules/,
            loader: 'expose?jQuery',
        },
        {
            test: /jquery\.js$/,
            exclude: /node_modules/,
            loader: 'expose?$',
        },
        {
            test: /[\/\\]vendor[\/\\]jquery.sparkline\.js$/,
            loader: "imports?define=>false"
        }
    ]
},
amd: { jQuery: true },
// plugins: [
//     new webpack.ProvidePlugin({
//        $: 'jquery',
//        jQuery: 'jquery',
//        'window.jQuery': 'jquery',
//        'root.jQuery': 'jquery'
//    })
// ], ...

在我的entry.js文件中,我以以下方式包含jquery:
import 'expose?jQuery!expose?$!./vendor/jquery';
import './jquery/jquery-ui';
import './vendor/jquery.sparkline';

我不得不将ProvidePlugin注释掉,使用它时,jQuery不再与自定义插件扩展,有任何想法是什么原因? 这与插件使用ES6模块语法有关吗?
我不得不添加loader: "imports?define=>false"来识别jquery.sparkline.js。这真的是必要的吗?还是有更好的方法?
关于jquery-ui,我不得不找到一个旧版本,它没有使用AMD define来使其添加到jquery对象中。什么是正确的做法?
非常感谢您的帮助和建议,切换到SystemJs和Jspm也可能是一种解决方案。

3
有什么想法为什么会这样?--- 因为它会创建另一个 jQuery 实例。我目前在调试器中,ProvidePlugin 会创建模块别名,这些别名实际上指向不同的对象。 - zerkms
好的,这也是我认为的情况。只是希望提供的jQuery也包含之前制作的所有扩展。此外,我想知道为什么鼓励使用ProvidePlugin,好吧,如果您不需要在window对象上使用“真正”的全局变量,那么这很好。只是不适合我的用例。 - RemEmber
为了使事情更加美好,您可以将imports loader config推送到webpack.config.js中。在我看来,这可能是适合您的方式。 - Juho Vepsäläinen
1个回答

3

我曾经遇到过这个问题,似乎是因为一些插件假定使用$,而其他插件则使用jQuery,但以下方法最终对我有效,尽管它看起来相当丑陋:

修改,请注意,我正在测试名为jquery.xyz.js的插件,您需要相应地调整正则表达式。 此外,我不确定两个不同的暴露加载器是否会导致问题,但目前这个方法可行。

// webpack.config.js
...
"module": {
    "loaders": [
        {
            test: require.resolve("jquery"),
            loader: "expose?$!expose?jQuery"
        },
        {
            test:   /jquery\..*\.js/,
            loader: "imports?$=jquery,jQuery=jquery,this=>window"
        }
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接