【问题标题】:How to Access jQuery Plugin From A Separate Webpack Bundle如何从单独的 Webpack 包访问 jQuery 插件
【发布时间】:2019-01-30 10:19:29
【问题描述】:

我将 JS 和 CSS(从 SCSS 编译)捆绑到两个单独的包中,一个用于第 3 方 (vendor),另一个用于项目代码 (company) .我可以通过 $ 成功地从公司捆绑包中的脚本作为全局访问 jQuery,例如来自 some-other-script.js,没有任何问题。但是,当尝试从 table-headers.js 中的 StickyTableHeaders plugin 调用 stickyTableHeaders 函数时:Uncaught TypeError: $(...).stickyTableHeaders is not a function。我没有收到有关加载脚本等的任何其他错误,我可以看到 vendor.bundle.js 包含插件代码。

另外,我从plugin source 的底部看到,该函数应按如下方式添加到 $ 中:

$.fn[name] = function ( options ) {
    return this.each(function () {
        var instance = $.data(this, 'plugin_' + name);
        if (instance) {
            if (typeof options === 'string') {
                instance[options].apply(instance);
            } else {
                instance.updateOptions(options);
            }
        } else if(options !== 'destroy') {
            $.data(this, 'plugin_' + name, new Plugin( this, options ));
        }
    });
};
  1. 知道为什么它在 $ (jQuery) 对象上找不到函数吗?
  2. This question 看起来很相似,但是在这种情况下,发布者遇到了插件无法找到 jQuery 的问题。此外,我不确定根据其中一项建议使用import-loader 是否是我的正确方法,或者我是否在做一些根本错误的事情。您可以在下面的 webpack.config.js 中看到注释掉的行,我尝试将 sticky-table-headers 注册为带有 webpack 的插件但没有成功 - 结果相同.

我的webpack.config.js如下:

var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var extractSass = new ExtractTextPlugin({
    filename: "[name].bundle.css",
    disable: process.env.NODE_ENV === "development"
});

module.exports = function (env) {

env = env || {};
var isProd = env.NODE_ENV === 'production';

// Setup base config for all environments
var config = {
    entry: {
        vendor: './Client/js/vendor',
        company: './Client/js/company'    // Includes all SCSS, which ends up in company.bundle.css via extract-text-webpack-plugin.
    },
    output: {
    // ReSharper disable once UseOfImplicitGlobalInFunctionScope
        path: path.join(__dirname, 'wwwroot/dist'),
        filename: '[name].bundle.js'
    },
    devtool: 'eval-source-map',
    mode: "development",
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
        alias: {
            "jquery.validation": "jquery-validation/dist/jquery.validate.js",
            //"sticky-table-headers": "sticky-table-headers/js/jquery.stickytableheaders.js"
        }
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            Popper: ['popper.js', 'default'],
            //"sticky-table-headers": ["sticky-table-headers", "default"]
        }),
        extractSass
    ],
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: extractSass.extract({
                    use: [{
                        loader: "css-loader"
                    }, {
                        loader: "sass-loader"
                    }],
                    // use style-loader in development
                    fallback: "style-loader"
                })
            }
        ]
    }
}

// Alter config for prod environment
if (isProd) {
    config.devtool = 'source-map';  // SourceMap emitted as a separate file. 
    //Normally disallow access on webserver or use (none) instead. Internal 
    //app so leaving them accessible for easier support.
    config.mode = "production";
    }
   return config;
};

然后在 vendor.js 我有:

import 'jquery';
import 'popper.js';
import 'bootstrap';
import "jquery-validation";
import "jquery-validation-unobtrusive";
import "sticky-table-headers";

company.js 我有:

import '../scss/site.scss';
import './site';
import './some-other-script';
import './table-headers';

最后在 table-headers.js 我有:

(function () {
    $(function () {
        if ($(".my-sticky-table-header").length === 0) return;        
        var offset = $('.navbar').height();
        $(".my-sticky-table-header").stickyTableHeaders({ 
fixedOffset:offset});        
    });
})();

谢谢。

【问题讨论】:

  • 如果我安装 import-loader 并将 vendor.js 的最后一行更改为 (yuck): import exec from 'script-loader!../../node_modules /sticky-table-headers/js/jquery.stickytableheaders.min.js';然后我得到这个错误: webpack-internal:///./node_modules/script-loader/addScript.js:8 [Script Loader] ReferenceError: jQuery is not defined at eval (eval at module.exports (webpack-internal:/ //./node_modules/script-loader/addScript.js), ... 在 eval (webpack-internal:///./node_modules/script-loader/index.js!./node_modules/sticky-table-headers/ js/jquery.stickytableheaders.min.js:1)

标签: javascript jquery webpack


【解决方案1】:

看起来这种设置存在根本缺陷。我最终添加了:

import './vendor'; 

company.js 的顶部,然后使用 here 提到的 SplitChunks 插件来避免 vendor 包中的所有内容被复制.这允许从 company 包中调用库函数。

(像this 这样的东西可能有效,但看起来很乱)。

【讨论】:

  • 仅供参考:这似乎破坏了依赖于 popper.js 的 Bootstrap 4 下拉菜单。没有错误,只是没有做任何事情。其他 Bootstrap 功能仍然有效。在为此苦苦挣扎后,决定现在转移到单个捆绑包。
猜你喜欢
  • 2023-04-10
  • 2021-06-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 2011-09-30
相关资源
最近更新 更多