管理webpack中的jQuery插件依赖项 [英] Managing jQuery plugin dependency in webpack

查看:141
本文介绍了管理webpack中的jQuery插件依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用Webpack,我在其中创建了两个入口点 - 所有JavaScript文件/代码的bundle.js,以及jQuery和React等所有库的vendors.js。我怎么做才能使用jQuery作为依赖项的插件,我想在vendors.js中也有它们?如果这些插件有多个依赖项怎么办?

I'm using Webpack in my application, in which I create two entry points - bundle.js for all my JavaScript files/codes, and vendors.js for all libraries like jQuery and React. What do I do in order to use plugins which have jQuery as their dependencies and I want to have them also in vendors.js? What if those plugins have multiple dependencies?

目前我正在尝试使用这个jQuery插件 - https://github.com/mbklein/jquery-elastic 。 Webpack文档提到 providePlugin 和imports-loader。我使用了providePlugin,但仍然没有jQuery对象。以下是我的webpack.config.js的样子 -

Currently I'm trying to use this jQuery plugin here - https://github.com/mbklein/jquery-elastic. The Webpack documentation mentions providePlugin and imports-loader. I used providePlugin, but still the jQuery object is not available. Here is how my webpack.config.js looks like-

var webpack = require('webpack');
var bower_dir = __dirname + '/bower_components';
var node_dir = __dirname + '/node_modules';
var lib_dir = __dirname + '/public/js/libs';

var config = {
    addVendor: function (name, path) {
        this.resolve.alias[name] = path;
        this.module.noParse.push(new RegExp(path));
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jquery: "jQuery",
            "window.jQuery": "jquery"
        }),
        new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity)
    ],
    entry: {
        app: ['./public/js/main.js'],
        vendors: ['react','jquery']
    },
    resolve: {
        alias: {
            'jquery': node_dir + '/jquery/dist/jquery.js',
            'jquery.elastic': lib_dir + '/jquery.elastic.source.js'
        }
    },
    output: {
        path: './public/js',
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            { test: /\.js$/, loader: 'jsx-loader' },
            { test: /\.jquery.elastic.js$/, loader: 'imports-loader' }
        ]
    }
};
config.addVendor('react', bower_dir + '/react/react.min.js');
config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js');
config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js');

module.exports = config;

但是尽管如此,它仍然会在浏览器控制台中抛出错误:

But in spite of this, it still throws an error in the browser console:


未捕获的ReferenceError:jQuery未定义

Uncaught ReferenceError: jQuery is not defined

同样,当我使用imports-loader,它会抛出错误,

Similarly, when I use the imports-loader, it throws an error,


require is not defined'

require is not defined'

在这一行:

var jQuery = require("jquery")

但是,当我不将它添加到我的vendors.js文件中时,我可以使用相同的插件而是以正常的AMD方式需要它,因为我如何包含我的其他JavaScript代码文件,例如 -

However, I could use the same plugin when I don't add it to my vendors.js file and instead required it in the normal AMD way as how I include my other JavaScript code files, like-

define(
[
    'jquery',
    'react',
    '../../common-functions',
    '../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
    $("#myInput").elastic() //It works

});

但这不是我想做的,因为这意味着jquery.elastic.source。 js与我的JavaScript代码捆绑在bundle.js中,我希望我所有的jQuery插件都在vendors.js包中。那么我该如何实现呢?

But this is not what I want to do, as this would mean that jquery.elastic.source.js is bundled along with my JavaScript code in bundle.js, and I want all my jQuery plugins to be in the vendors.js bundle. So how do I go about achieving this?

推荐答案

您已经混合了不同的方法来包含传统的供应商模块。这就是我要解决的问题:

You've mixed different approaches how to include legacy vendor modules. This is how I'd tackle it:

大多数模块链接 dist c package.json 的 main 字段中的$ c>版本。虽然这对大多数开发人员都很有用,但对于webpack来说,最好别名 src 版本,因为这样webpack能够更好地优化依赖关系(例如,当使用 DedupePlugin )。

Most modules link the dist version in the main field of their package.json. While this is useful for most developers, for webpack it is better to alias the src version because this way webpack is able to optimize dependencies better (e.g. when using the DedupePlugin).

// webpack.config.js

module.exports = {
    ...
    resolve: {
        alias: {
            jquery: "jquery/src/jquery"
        }
    }
};

但是,在大多数情况下, dist 版本工作得很好。

However, in most cases the dist version works just fine as well.

大多数遗留模块都依赖于特定全局变量的存在,比如jQuery插件在 $ jQuery 。在这种情况下,您可以配置webpack,每次遇到全局 $ var $ = require(jquery) >标识符。

Most legacy modules rely on the presence of specific globals, like jQuery plugins do on $ or jQuery. In this scenario you can configure webpack, to prepend var $ = require("jquery") everytime it encounters the global $ identifier.

var webpack = require("webpack");

    ...

    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ]






< H2> 3。使用 imports-loader 配置

一些传统模块依赖这个作为窗口宾语。当模块在CommonJS上下文中执行时会出现问题,其中等于 module.exports 。在这种情况下,您可以使用 imports-loader覆盖


3. Use the imports-loader to configure this

Some legacy modules rely on this being the window object. This becomes a problem when the module is executed in a CommonJS context where this equals module.exports. In this case you can override this with the imports-loader.

运行 npm i imports-loader --save-dev 然后

module: {
    loaders: [
        {
            test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
            loader: "imports-loader?this=>window"
        }
    ]
}

也可以使用imports-loader手动注入各种变量。但大多数情况下, ProvidePlugin 在隐式全局变量时更有用。

The imports-loader can also be used to manually inject variables of all kinds. But most of the time the ProvidePlugin is more useful when it comes to implicit globals.

有些模块支持不同的模块样式,如AMD,CommonJS和legacy。但是,大多数情况下,他们首先检查定义,然后使用一些古怪的代码来导出属性。在这些情况下,可以通过设置 define = false 来强制CommonJS路径。

There are modules that support different module styles, like AMD, CommonJS and legacy. However, most of the time they first check for define and then use some quirky code to export properties. In these cases, it could help to force the CommonJS path by setting define = false.

module: {
    loaders: [
        {
            test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
            loader: "imports-loader?define=>false"
        }
    ]
}






5。使用脚本加载器全局导入脚本



如果您不关心全局变量并且只想使用旧脚本,那么您也可以使用脚本加载器。它在全局上下文中执行模块,就像您通过< script> 标记包含它们一样。


5. Use the script-loader to globally import scripts

If you don't care about global variables and just want legacy scripts to work, you can also use the script-loader. It executes the module in a global context, just as if you had included them via the <script> tag.

当模块没有AMD / CommonJS版本且你想要包含 dist ,您可以将此模块标记为 noParse 。然后webpack将包含模块而不解析它,这可用于改善构建时间。这意味着任何需要 AST 的功能,例如 ProvidePlugin ,将无效。

When there is no AMD/CommonJS version of the module and you want to include the dist, you can flag this module as noParse. Then webpack will just include the module without parsing it, which can be used to improve the build time. This means that any feature requiring the AST, like the ProvidePlugin, will not work.

module: {
    noParse: [
        /[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/
    ]
}

这篇关于管理webpack中的jQuery插件依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆