我在应用程序中使用Webpack,我在其中创建了两个入口点——bundle.我的所有JavaScript文件/代码和供应商的js.jQuery和React等所有库的js.我该怎么做才能使用那些依赖jQuery的插件,我希望这些插件也能在供应商中使用.js?如果这些插件有多个依赖项呢?

目前我正在try 使用这个jQuery插件-https://github.com/mbklein/jquery-elastic.网页文档提到providePlugin和导入加载器.我使用了providePlugin,但jQuery对象仍然不可用.以下是我的网页包.配置.js看起来像-

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;

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

未捕获的ReferenceError:未定义jQuery

类似地,当我使用导入加载程序时,它会抛出一个错误,

"需求未定义"

在这方面:

var jQuery = require("jquery")

然而,当我不把它添加到我的供应商时,我可以使用相同的插件.js文件,而是以正常的AMD方式要求它,就像我包含其他JavaScript代码文件一样,比如-

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

});

但这不是我想做的,因为这意味着jquery.有弹力的来源js与我的JavaScript代码Bundle 在一起.js,我希望我所有的jQuery插件都在供应商那里.js包.那么,我该如何实现这一目标呢?

推荐答案

您混合了不同的方法来包含遗留供应商模块.以下是我如何应对的:

1. Prefer unminified CommonJS/AMD over dist

大多数模块在其package.jsonmain字段中链接dist版本.虽然这对大多数开发人员很有用,但对于webpack来说,最好是给src版本取别名,因为这样webpack就能更好地优化依赖关系(例如,当使用DedupePlugin时).

// webpack.config.js

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

然而,在大多数情况下,dist版本也运行得很好.


2. Use the ProvidePlugin to inject implicit globals

大多数遗留模块都依赖于特定全局变量的存在,就像jQuery插件在$jQuery上所做的那样.在此场景中,您可以配置webpack,使其在每次遇到全局$标识符时预先添加var $ = require("jquery").

var webpack = require("webpack");

    ...

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

3. Use the imports-loader to configure this

一些传统模块依赖this作为window对象.当模块在CommonJS上下文中执行时,this等于module.exports,这就成了一个问题.在这种情况下,可以用imports-loader替代this.

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

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

Imports-Loader还可以用于手动注入所有类型的变量.但在大多数情况下,当涉及到隐式全局变量时,ProvidePlugin更有用.


4. Use the imports-loader to disable AMD

有些模块支持不同的模块样式,比如AMD、CommonJS和legacy.然而,大多数时候,他们首先判断define,然后使用一些奇怪的代码导出属性.在这些情况下,设置define = false有助于强制使用CommonJS路径.

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

5. Use the script-loader to globally import scripts

如果您不关心全局变量,只想让遗留脚本工作,您也可以使用脚本加载器.它在全局上下文中执行模块,就好像您通过<script>标记包含了它们一样.


6. Use noParse to include large dists

如果你不想把这个模块的JS/dist作为通用标志,你可以把它包括进go .然后webpack将只包含模块而不解析它,这可以用来提高构建时间.这意味着任何需要AST的功能,比如ProvidePlugin,都无法工作.

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

Javascript相关问答推荐

橡皮擦完全让画布变成白色

如何在表格上拥有水平滚动条,在正文页面上拥有垂直滚动条,同时还对html表格的标题使用位置粘性?

微软Edge Select 间隙鼠标退出问题

传递一个大对象以在Express布局中呈现

将状态向下传递给映射的子元素

在JavaScript中声明自定义内置元素不起作用

WebRTC关闭navigator. getUserMedia正确

CheckBox作为Vue3中的一个组件

在react JS中映射数组对象的嵌套数据

使用GraphQL查询Uniswap的ETH价格

如何解决useState错误—setSelect Image不是函数''

保持物品顺序的可变大小物品分配到平衡组的算法

对路由DOM嵌套路由作出react

为什么这个.add.group({})在教程中运行得很好,但在我的游戏中就不行了?

在画布中调整边上反弹框的大小失败

在不删除代码的情况下禁用Java弹出功能WordPress

如何限制显示在分页中的可见页面的数量

无法避免UV:flat的插值:非法使用保留字"

JavaScript&;Reaction-如何避免在不使用字典/对象的情况下出现地狱?

如何在Reaction中设置缺省值, Select 下拉列表,动态追加剩余值?