वेबपैक में jQuery प्लगइन निर्भरता का प्रबंधन


451

मैं अपने एप्लिकेशन में वेबपैक का उपयोग कर रहा हूं, जिसमें मैं अपने सभी जावास्क्रिप्ट फ़ाइलों / कोडों के लिए दो एंट्री पॉइंट्स- बंडल-जेएस बनाता हूं, और jQuery और रिएक्ट जैसे सभी पुस्तकालयों के लिए वेंडर्स.जेएस। मैं प्लगइन्स का उपयोग करने के लिए क्या करता हूं जिसमें उनकी निर्भरता के रूप में jQuery है और मैं उन्हें वेंडर्स.जेएस में भी रखना चाहता हूं? क्या होगा अगर उन प्लगइन्स में कई निर्भरताएं हैं?

वर्तमान में मैं यहां इस jQuery प्लगइन का उपयोग करने की कोशिश कर रहा हूं - https://github.com/mbklein/jquery-elasticवेबपैक डॉक्यूमेंट में प्रोपलगिन और आयात-लोडर का उल्लेख है । मैंनेPPugugin का उपयोग किया था, लेकिन अभी भी jQuery ऑब्जेक्ट उपलब्ध नहीं है। यहाँ मेरा webpack.config.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;

लेकिन इसके बावजूद, यह अभी भी ब्राउज़र कंसोल में एक त्रुटि फेंकता है:

बिना संदर्भित संदर्भ: jQuery परिभाषित नहीं है

इसी तरह, जब मैं आयात-लोडर का उपयोग करता हूं, तो यह एक त्रुटि फेंकता है,

आवश्यकता परिभाषित नहीं है '

इस पंक्ति में:

var jQuery = require("jquery")

हालाँकि, मैं उसी प्लगइन का उपयोग कर सकता हूं जब मैं इसे अपने वेंडर्स.जेएस फाइल में नहीं जोड़ता हूं और इसके बजाय सामान्य एएमडी तरीके से इसकी आवश्यकता होती है जैसे कि मैं अपनी अन्य जावास्क्रिप्ट कोड फ़ाइलों को शामिल करता हूं, जैसे-

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

});

लेकिन यह वह नहीं है जो मैं करना चाहता हूं, क्योंकि इसका मतलब होगा कि jquery.elastic.source.js को बंडल में मेरे जावास्क्रिप्ट कोड के साथ बंडल किया गया है। और मैं चाहता हूं कि मेरे सभी jQuery प्लगइन्स विक्रेताओं के .j बंडल में हों। तो मैं इसे कैसे प्राप्त करूं?


3
निश्चित नहीं है कि यह आपकी समस्या है, लेकिन आपको निश्चित रूप से windows.jQuery को "window.jQuery": "jquery" में बदलना होगा। वेबपैक की वेबसाइट पर एक टाइपो है जहां मैं मान रहा हूं कि आपको वह कोड मिल गया है।
एलेक्स हॉकिन्स

@AlexHawkins ओह, हाँ, मैंने उस पर ध्यान दिया और इसे ठीक किया। इस पर ध्यान दिलाने के लिए धन्यवाद!
बूलियनहंटर

जवाबों:


771

आपने लीगेसी विक्रेता मॉड्यूल को शामिल करने के विभिन्न तरीकों को मिलाया है। मैं इसे कैसे निपटाऊंगा:

1. कॉमन जेजेएस / एएमडी को प्राथमिकता दें dist

अधिकांश मॉड्यूल उनके क्षेत्र distमें संस्करण को लिंक mainकरते हैं package.json। जबकि यह अधिकांश डेवलपर्स के लिए उपयोगी है, वेबपैक के लिए srcसंस्करण को अन्य नाम देना बेहतर है क्योंकि इस तरह से वेबपैक निर्भरता को बेहतर रूप से अनुकूलित करने में सक्षम है (उदाहरण के लिए उपयोग करते समय DedupePlugin)।

// webpack.config.js

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

हालाँकि, ज्यादातर मामलों में distसंस्करण ठीक काम करता है।


2. ProvidePluginअंतर्निहित ग्लोबल्स को इंजेक्ट करने के लिए उपयोग करें

अधिकांश लीगेसी मॉड्यूल विशिष्ट ग्लोबल्स की उपस्थिति पर निर्भर करते हैं, जैसे कि jQuery प्लग इन $या jQuery। इस परिदृश्य में आप वेबपैक को कॉन्फ़िगर कर सकते हैं, var $ = require("jquery")हर बार इसे प्रस्तुत करने के लिए वैश्विक $पहचानकर्ता से सामना करता है ।

var webpack = require("webpack");

    ...

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

3. कॉन्फ़िगर करने के लिए आयात-लोडर का उपयोग करेंthis

कुछ विरासत मॉड्यूल वस्तु thisहोने पर भरोसा करते हैं window। यह एक समस्या बन जाती है जब मॉड्यूल को कॉमनजस संदर्भ में निष्पादित किया जाता है जहां thisबराबर होता है module.exports। इस मामले में आप आयात-लोडर केthis साथ ओवरराइड कर सकते हैं ।

दौड़ो npm i imports-loader --save-devऔर फिर

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

आयात-लोडर का उपयोग सभी प्रकार के चर को मैन्युअल रूप से इंजेक्ट करने के लिए भी किया जा सकता है। लेकिन ज्यादातर समय ProvidePluginअधिक उपयोगी होता है जब यह अंतर्निहित ग्लोबल्स की बात आती है।


4. एएमडी को निष्क्रिय करने के लिए आयात-लोडर का उपयोग करें

ऐसे मॉड्यूल हैं जो विभिन्न मॉड्यूल शैलियों का समर्थन करते हैं, जैसे कि एएमडी, कॉमनजेस और विरासत। हालाँकि, ज्यादातर समय वे पहली बार जांच करते हैं defineऔर फिर कुछ quirky कोड का उपयोग गुणों को निर्यात करने के लिए करते हैं। इन मामलों में, यह सेटिंग के द्वारा कॉमनजेस पथ को मजबूर करने में मदद कर सकता है define = false

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

5. विश्व स्तर पर आयात स्क्रिप्ट के लिए स्क्रिप्ट-लोडर का उपयोग करें

यदि आप वैश्विक चर के बारे में परवाह नहीं करते हैं और सिर्फ विरासत की लिपियों को काम करना चाहते हैं, तो आप स्क्रिप्ट-लोडर का भी उपयोग कर सकते हैं। यह मॉड्यूल को वैश्विक संदर्भ में निष्पादित करता है, जैसे कि आपने उन्हें <script>टैग के माध्यम से शामिल किया हो ।


6. noParseबड़े डिस्ट को शामिल करने के लिए उपयोग करें

जब मॉड्यूल का कोई AMD / CommonJS संस्करण नहीं है और आप इसे शामिल करना चाहते हैं dist, तो आप इस मॉड्यूल को इस रूप में फ़्लैग कर सकते हैं noParse। फिर वेबपैक केवल मॉड्यूल को बिना पार्स किए शामिल करेगा, जिसका उपयोग बिल्ड समय को बेहतर बनाने के लिए किया जा सकता है। इसका मतलब यह है कि किसी भी तरह की एएसटी की आवश्यकता वाली सुविधा ProvidePlugin, काम नहीं करेगी।

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

3
ProvidePluginसभी फाइलों में दी गई पहचानकर्ता की सभी घटनाओं पर लागू किया जाता है। imports-loaderकेवल विशिष्ट फ़ाइलों पर लागू किया जा सकता है, लेकिन आप एक ही चर / निर्भरता के लिए दोनों का उपयोग नहीं करना चाहिए।
जोहान्स इवाल्ड

5
मैं इससे भ्रमित हूं। वास्तव में जक्वरी कहां से आ रही है? स्थानीय रूप से या एक सीडीएन? इसके बाद का 3. सब कुछ स्पष्ट नहीं है कि क्या यह आवश्यक है। वेबपैक का उपयोग करके अपनी परियोजना में jquery को एकीकृत करने के लिए वास्तविक कदम क्या हैं। क्या यह CDN के माध्यम से उपलब्ध संस्करण को बायपास करता है?
HelpMeStackOverflowMyOnlyHope

2
सीडीएन से सब कुछ वेबपैक के दायरे से बाहर है, इसलिए यह एक स्थानीय jquery स्थापना को संदर्भित करता है। जक्वेरी बस आवश्यक हो सकती है, इसे एकीकृत करने के लिए कोई विशेष कदम आवश्यक नहीं हैं। यह सवाल यह है कि jquery प्लगइन्स को कैसे एकीकृत किया जाए जो वैश्विक पर निर्भर करता है$ चर ।
जोहान्स इवाल्ड

8
क्या यह सब, अभी भी काम नहीं कर रहा है; फिर जोड़ा गया: "module": { "loaders": [ { test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" },और यह ठीक काम किया।
म्यूज़फ़ॉर्मेलन

5
यह सब करें, बस एक जेकरी पैकेज शामिल करने के लिए?, क्या दर्द है। मैं अपने गल्प बिल्ड
राहुल गुप्ता में

89

Jquery की वैश्विक पहुंच के लिए तब कई विकल्प मौजूद हैं। मेरी सबसे हालिया वेबपैक परियोजना में, मुझे jquery पर वैश्विक पहुंच चाहिए थी, इसलिए मैंने अपने प्लगइन्स घोषणाओं में निम्नलिखित को जोड़ा:

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

इसका मतलब यह है कि jquery जावास्क्रिप्ट स्रोत कोड के भीतर वैश्विक संदर्भ $ और jQuery के माध्यम से सुलभ है।

बेशक, आपको npm के माध्यम से jquery भी स्थापित करना होगा:

$ npm i jquery --save

इस दृष्टिकोण के एक कामकाजी उदाहरण के लिए कृपया मेरे ऐप को जीथब पर फोर्क करने के लिए स्वतंत्र महसूस करें


2
यदि आप किसी कारण को समझाते हुए वोट डाउनग्रेड करते हैं तो कृपया टिप्पणी छोड़ सकते हैं। उपरोक्त जानकारी सटीक है। ऊपर दिए गए दृष्टिकोण का उपयोग करके कृपया मेरा काम करने वाला ऐप देखें: github.com/arcseldon/react-babel-webpack-starter-app
आर्केल्डन

मैं नीच नहीं हूं, लेकिन शायद यह इसलिए है क्योंकि ProvidePluginआपके द्वारा सुझाए गए समाधान पहले से ही प्रस्तावित थे?
लेओ लैम

@ LéoLam - आपकी टिप्पणी के लिए धन्यवाद। अपनी बात की सराहना करते हैं - मैंने अलग-अलग पूछताछ के माध्यम से उत्तर को काट दिया था, और यहां स्निपेट साझा किया था मुझे लगा कि मैं दूसरों के लिए सबसे अधिक प्रासंगिक था जो कि मैंने जो किया था, उसका अनुकरण करना चाहता था। हालांकि आप सही हैं, आधिकारिक जवाब इस विकल्प को कवर करता है।
आर्केल्डन

1
यह काम कर रहा है, लेकिन मुझे 2 चेतावनी मिलती हैं: ./~/jQuery/dist/jquery.js There is another module with an equal name when case is ignored.और उसी के साथ./~/jquery/dist/jquery.js
पिस्तौ

7
'window.jQuery': 'jquery'एमएस-सिग्नलर-क्लाइंट एनपीएम पैकेज लोड करने के लिए मुझे उस सूची में जोड़ना होगा। मैंने भी 'window.$': 'jquery'अच्छे उपाय के लिए :) :)
सममी

57

मुझे नहीं पता कि मैं बहुत अच्छी तरह से समझता हूं कि आप क्या करने की कोशिश कर रहे हैं, लेकिन मुझे jQuery प्लगइन्स का उपयोग करना था, जिसके लिए jQuery को वैश्विक संदर्भ (विंडो) में होना चाहिए और मैंने निम्नलिखित को अपने पास रखा entry.js:

var $ = require('jquery');
window.jQuery = $;
window.$ = $;

मुझे सिर्फ जहाँ मैं चाहता हूँ की आवश्यकता है jqueryplugin.min.jsऔर window.$प्लगइन के साथ बढ़ाया जा सकता है।


2
मूल रूप से मैं noParse शर्त के साथ ProvPlugin का उपयोग करने की गलती कर रहा था। यदि हम NoParse करते हैं तो ProvPlugin जैसे प्लगिन काम नहीं करते हैं, जैसा कि उत्तर के बिंदु संख्या 6 में कहा गया है। आप उस गलती को कोड में देख सकते हैं
बूलियनहंटर

हाँ, मैंने पाया है कि प्लगइन्स प्रदान करने की तुलना में प्लगइन्स पर लगातार काम करता है ... अगर आप स्क्रिप्ट 1. लोडर के माध्यम से कोणीय 1.x में ला रहे हैं।
ट्रैकर 1

27

मुझे चीजों को उजागर करते समय अच्छी तरह से काम करना पड़ा $और jQueryवेबपैक 3.8.1 और निम्नलिखित के साथ वैश्विक चर के रूप में।

परियोजना निर्भरता के रूप में jQuery स्थापित करें। आप @3.2.1नवीनतम संस्करण को स्थापित करने या किसी अन्य संस्करण को निर्दिष्ट करने के लिए छोड़ सकते हैं ।

npm install --save jquery@3.2.1

expose-loaderयदि पहले से स्थापित नहीं है तो विकास निर्भरता के रूप में स्थापित करें ।

npm install expose-loader --save-dev

हमारे लिए jQuery को लोड और उजागर करने के लिए वेबपैक कॉन्फ़िगर करें।

// webpack.config.js
const webpack = require('webpack')

module.exports = {
  entry: [
    // entry bits
  ],
  output: {
    // output bits
  },
  module: {
    rules: [
      // any other rules
      {
        // Exposes jQuery for use outside Webpack build
        test: require.resolve('jquery'),
        use: [{
          loader: 'expose-loader',
          options: 'jQuery'
        },{
          loader: 'expose-loader',
          options: '$'
        }]
      }
    ]
  },
  plugins: [
    // Provides jQuery for other JS bundled with Webpack
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  ]
}

5
आप यह उल्लेख करना भूल गए कि आपको expose-loaderठीक से काम करने के लिए इसे स्थापित करने की आवश्यकता हैnpm install expose-loader --save-dev
पाउलो ग्रिएटेनर

4
इसने मेरे लिए काम किया 👍। jquery: 3.3.1, एक्सपोज-लोडर: 0.7.5, वेबपैक: 4.20.2
AKT

expose-loadedमेरे लिए यह किया था। मुझे संकलन समय पर त्रुटि नहीं मिली, लेकिन Chrome डेवलपर टूल में। यह अब हल है।
जोहान वेगर

धन्यवाद! इसने "jquery": "^ 3.4.1" और "webpack": "^ 4.41.5" के साथ काम किया। क्या यह सिर्फ मेरे लिए है या वेबपैक के साथ काम करने के लिए jQuery प्राप्त करना यह हास्यास्पद नहीं होना चाहिए?
कार्ल्स अल्कोली

18

इसे webpack.config.js में अपने प्लगइन्स ऐरे में जोड़ें

new webpack.ProvidePlugin({
    'window.jQuery': 'jquery',
    'window.$': 'jquery',
})

फिर सामान्य रूप से jquery की आवश्यकता होती है

require('jquery');

यदि दर्द इसे देखने के लिए अन्य लिपियों को प्राप्त करने में बना रहता है, तो इसे स्पष्ट रूप से वैश्विक संदर्भ में (प्रविष्टि js में) रखकर देखें।

window.$ = jQuery;

18

अपने webpack.config.js फ़ाइल में नीचे जोड़ें:

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

Npm का उपयोग करके jQuery स्थापित करें:

$ npm i jquery --save

App.js फ़ाइल में नीचे की पंक्तियों को जोड़ें:

import $ from 'jquery';
window.jQuery = $;
window.$ = $;

इसने मेरे लिए काम किया। :)


पूर्व के लिए है तो यह कैसे कार्य करेगा। app.js, और jquery-मॉड्यूल.js, कि दोनों के लिए jquery की आवश्यकता है ?, मेरे लिए jquery13981378127, और jquery12389723198 खिड़की पर उदाहरण के रूप में प्राप्त करें?
मार्टीका

8

मैंने कुछ दिए गए जवाबों की कोशिश की, लेकिन उनमें से कोई भी काम नहीं किया। फिर मैंने यह कोशिश की:

new webpack.ProvidePlugin({
    'window.jQuery'    : 'jquery',
    'window.$'         : 'jquery',
    'jQuery'           : 'jquery',
    '$'                : 'jquery'
});

कोई फर्क नहीं पड़ता कि मैं किस संस्करण का उपयोग कर रहा हूं


+1 यह गलतफहमी प्रतीत होती है कि यहां जोड़े गए ग्लोबल्स स्वचालित रूप से विंडो के खिलाफ सेट हो जाएंगे, ऐसा काम नहीं करता है जैसे आपको स्पष्ट होना चाहिए।
जेम्स

सही है, यह इसे विंडो ऑब्जेक्ट में नहीं जोड़ता है। यह वेबपैक के अंदर एक विंडो उर्फ ​​बनाता है। इसलिए यदि आप $किसी वेबपैक आवश्यक फ़ाइल के बाहर का उपयोग करने का प्रयास करते हैं , तो यह अपरिभाषित होगा।
कैम टुल्लोस

7

यह वेबपैक 3 में काम करता है :

webpack.config.babel.js फ़ाइल में:

resolve: {
    alias: {
         jquery: "jquery/src/jquery"
    },
 ....
}

और ProvPlugin का उपयोग करें

new webpack.ProvidePlugin({
        '$': 'jquery',
        'jQuery': 'jquery',
    })

1
दूसरों के लिए जो वेबपैक पर सुपर नए हैं (मेरी तरह!) "समाधान" आपके webpack.config.js में मॉड्यूल.exports = {} में प्रवेश, आउटपुट, प्लगइन्स, मॉड्यूल, आदि की तरह ही जाता है।
DavGarcia

1
और नया webpack.ProvidePlugin प्लगइन्स ऐरे के अंदर जाता है।
दावजरिया

2

सबसे अच्छा समाधान मैंने पाया है:

https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059

मूल रूप से, आपको टाइपिंग.d.ts पर एक डमी वैरिएबल को शामिल करने की आवश्यकता है, अपने कोड से 'jquery' से $ "के रूप में किसी भी" आयात * को हटा दें, और फिर मैन्युअल रूप से अपने एसपीए html में jQuery स्क्रिप्ट में एक टैग जोड़ें। इस तरह, वेबपैक आपके रास्ते में नहीं होगा, और आपको अपनी सभी लिपियों में एक ही वैश्विक jQuery चर का उपयोग करने में सक्षम होना चाहिए।


2

यह मेरे लिए webpack.config.js पर काम करता है

    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery'
    }),

किसी अन्य जावास्क्रिप्ट या HTML ऐड में:

global.jQuery = require('jquery');

0

संपादित करें: कभी-कभी आप एक सरल वेब प्रोजेक्ट के लिए मॉड्यूल बंडलर के रूप में वेबपैक का उपयोग करना चाहते हैं - अपने स्वयं के कोड को व्यवस्थित रखने के लिए। निम्नलिखित समाधान उन लोगों के लिए है जो सिर्फ एक बाहरी पुस्तकालय को अपने मॉड्यूल के अंदर अपेक्षित रूप से काम करना चाहते हैं - वेब सेटअप में बहुत अधिक समय का उपयोग किए बिना। (-1 के बाद संपादित)

त्वरित और सरल (es6) समाधान यदि आप अभी भी संघर्ष कर रहे हैं या बाहरी कॉन्फ़िगरेशन / अतिरिक्त वेबपैक प्लग इन कॉन्फ़िगरेशन से बचना चाहते हैं:

<script src="cdn/jquery.js"></script>
<script src="cdn/underscore.js"></script>
<script src="etc.js"></script>
<script src="bundle.js"></script>

एक मॉड्यूल के अंदर:

const { jQuery: $, Underscore: _, etc } = window;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.