Web paketindeki jQuery eklentisi bağımlılığını yönetme


451

Tüm JavaScript dosyaları / kodları için bundle.js ve jQuery ve React gibi tüm kütüphaneler için vendle.js - iki giriş noktası oluşturduğum uygulamamda Webpack kullanıyorum. Bağımlılıkları olarak jQuery olan eklentileri kullanmak için ne yapmalıyım ve bunları vendors.js'de de kullanmak istiyorum? Bu eklentilerin birden fazla bağımlılığı varsa ne olur?

Şu anda burada bu jQuery eklentisini kullanmaya çalışıyorum - https://github.com/mbklein/jquery-elastic . Webpack belgelerinde, Plugin ve ithalat yükleyiciden bahsedilmektedir . ProvidPlugin kullandım, ancak yine de jQuery nesnesi mevcut değil. Webpack.config.js dosyam şöyle görünüyor:

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;

Ancak buna rağmen, tarayıcı konsolunda hala bir hata atıyor:

Yakalanmayan ReferenceError: jQuery tanımlanmamış

Benzer şekilde, ithalat yükleyiciyi kullandığımda bir hata veriyor,

ihtiyaç tanımlanmadı '

bu satırda:

var jQuery = require("jquery")

Ancak, vendors.js dosyama eklemediğimde aynı eklentiyi kullanabilirim ve bunun yerine, diğer AMD kod dosyalarımı nasıl eklediğimi,

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

});

Ama bu yapmak istediğim şey değil, çünkü bu jquery.elastic.source.js'nin bundle.js'deki JavaScript kodumla birlikte verildiği ve tüm jQuery eklentilerimin vendors.js paketinde olmasını istediğim anlamına geliyor. Peki bunu nasıl başarabilirim?


3
Bu sorunun olup olmadığından emin değilsiniz, ancak windows.jQuery'yi "window.jQuery": "jquery" olarak değiştirmeniz gerekir. Webpack'in web sitesinde, bu kodu aldığınızı varsaydığım bir yazım hatası var.
Alex Hawkins

@AlexHawkins Oh evet, bunu fark ettim ve düzelttim. Gösterdiğiniz için teşekkürler!
booleanhunter

Yanıtlar:


771

Eski tedarikçi modüllerini nasıl dahil edeceğiniz konusunda farklı yaklaşımlar karıştırdınız. Ben bu şekilde başardım:

1. Bitmemiş CommonJS / AMD'yi tercih edin dist

Çoğu modül distsürümü mainkendi alanında bağlar package.json. Bu, çoğu geliştirici için yararlı olsa da, webpack için srcsürümü takmalamak daha iyidir, çünkü bu şekilde webpack bağımlılıkları daha iyi optimize edebilir (örn. Kullanırken DedupePlugin).

// webpack.config.js

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

Ancak, çoğu durumda distsürüm de iyi çalışır.


2. ProvidePluginÖrtülü globalleri enjekte etmek için

Çoğu eski modülleri jQuery eklentileri yaptıkları gibi, belirli globaller varlığına güveniyor $veya jQuery. Bu senaryoda, web paketini var $ = require("jquery")genel $tanımlayıcıyla her karşılaştığında başa gelecek şekilde yapılandırabilirsiniz .

var webpack = require("webpack");

    ...

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

3. yapılandırmak için ithalat-yükleyici kullanınthis

Bazı eski modüller güveniyor thisolmanın windownesnesi. Bu modül thiseşit olduğunda bir CommonJS bağlamında yürütüldüğünde bir sorun haline gelir module.exports. Bu durumda this, ithalat yükleyiciyle geçersiz kılabilirsiniz .

Koş npm i imports-loader --save-devve sonra

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

İçe aktarma yükleyicisi, her türlü değişkeni manuel olarak enjekte etmek için de kullanılabilir. Ancak çoğu zaman ProvidePluginörtülü küreseller söz konusu olduğunda daha faydalıdır.


4. AMD'yi devre dışı bırakmak için ithalat yükleyiciyi kullanın

AMD, CommonJS ve eski gibi farklı modül stillerini destekleyen modüller vardır. Ancak, çoğu zaman ilk önce kontrol defineedip özellikleri dışa aktarmak için bazı ilginç kodlar kullanırlar. Bu durumlarda, ayarlayarak CommonJS yolunu zorlamak yardımcı olabilir define = false.

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

5. Komut dosyalarını global olarak içe aktarmak için kod yükleyiciyi kullanın

Global değişkenleri önemsemiyorsanız ve sadece eski komut dosyalarının çalışmasını istiyorsanız, komut dosyası yükleyiciyi de kullanabilirsiniz. Modülü, sanki <script>etiket üzerinden eklediğiniz gibi global bir bağlamda yürütür .


6. noParseBüyük dağıtımları dahil etmek için kullanın

Modülün AMD / CommonJS sürümü olmadığında ve dahil etmek istediğinizde dist, bu modülü olarak işaretleyebilirsiniz noParse. Daha sonra webpack, modülü ayrıştırmadan içerecektir, bu da derleme süresini iyileştirmek için kullanılabilir. Bu, AST gibi herhangi bir özelliğin ProvidePluginçalışmadığı anlamına gelir .

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

3
ProvidePluginTüm dosyaların verilen tanımlayıcıları geçtiği tüm uygulanır. imports-loaderSadece belirli dosyaları üzerinde uygulanabilir, ancak aynı değişkenler / bağımlılıkları için hem kullanmamalısınız.
Johannes Ewald

5
Bununla kafam karıştı. Jquery aslında nereden geliyor? Yerel olarak mı yoksa CDN mi? 3. sonrası her şey gerekli olup olmadığı belirsiz. Web paketini kullanarak jquery'yi projenize entegre etmenin gerçek adımları nelerdir? CDN aracılığıyla kullanılabilen sürümü atlıyor mu?
HelpMeStackOverflowMyOnlyHope

2
Bir CDN'den gelen her şey webpack için kapsam dışıdır, bu nedenle bu yerel bir jquery kurulumunu ifade eder. Jquery sadece gerekli olabilir, entegre etmek için gerekli özel adımlar yoktur. Bu soru, global $değişkene bağlı jquery eklentilerinin nasıl entegre edileceği ile ilgilidir .
Johannes Ewald

8
Bütün bunları yaptı, hala çalışmıyor; Sonra eklendi: "module": { "loaders": [ { test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" },ve iyi çalıştı.
musicformellons

5
Tüm bunları, sadece bir jquery paketi dahil etmek için mi?, Ne acı. Ben yutmak yapıma geri dönüyorum
Rahul Gupta

89

Jquery'ye küresel erişim için çeşitli seçenekler mevcuttur. En son webpack projemde jquery'ye global erişim istedim, bu yüzden eklenti bildirimlerime aşağıdakileri ekledim:

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

Bu, jquery'ye $ ve jQuery genel başvuruları aracılığıyla JavaScript kaynak kodu içinden erişilebileceği anlamına gelir.

Tabii ki, npm aracılığıyla jquery yüklemiş olmanız gerekir:

$ npm i jquery --save

Bu yaklaşımın çalışan bir örneği için lütfen github'daki uygulamamı çatallamaktan çekinmeyin


2
Nedeni açıklayan bir oyu düşürürseniz lütfen yorum bırakabilirsiniz. Yukarıdaki bilgiler doğrudur. Lütfen yukarıdaki uygulamayı kullanarak github.com/arcseldon/react-babel-webpack-starter-app adresindeki çalışan uygulamama bakın .
arcseldon

Ben downvoter değilim, ama belki de ProvidePluginönerdiğiniz çözüm zaten önerilmişti?
Léo Lam

@ LéoLam - yorumunuz için teşekkürler. Puanınızı takdir edin - yanıtı ayrı sorgulamalarla çıkardım ve sadece snippet'i burada paylaştım, muhtemelen yaptığım şeyi taklit etmek isteyen diğerleriyle en alakalı olduğunu düşündüm. Haklısın, resmi cevap bu seçeneği kapsamaktadır.
arcseldon

1
Çalışıyor ama 2 uyarı alıyorum: ./~/jQuery/dist/jquery.js There is another module with an equal name when case is ignored.ve aynı olanla./~/jquery/dist/jquery.js
pistou

7
'window.jQuery': 'jquery'Ms-signalr-istemci npm paket yük yapmak için bu listeye eklemek gerekiyordu . Ben de 'window.$': 'jquery'iyi bir önlem için koydu :)
Sammi

57

Ne yapmaya çalıştığınızı çok iyi anlıyorum bilmiyorum, ama jQuery küresel bağlamda (pencere) olmasını gerektiren jQuery eklentileri kullanmak zorunda kaldı ve ben benim aşağıdaki koymak entry.js:

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

Ben sadece nerede istiyorum istiyorum gerekir jqueryplugin.min.jsve window.$beklendiği gibi eklenti ile genişletilir.


2
Temelde noParse koşulu ile birlikte ProvidePlugin kullanma hatası yapıyordum. Yanıtın 6. maddesinde belirtildiği gibi, NoParse yaparsak ProvidePlugin gibi eklentiler çalışmaz. Bu hatayı kodda görebilirsiniz
booleanhunter

Evet, script-loader ile açısal 1.x getiriyorsanız, eklenti sağlama vb. eklentilerden daha tutarlı bir şekilde çalıştığını buldum.
Tracker1

27

Webpack 3.8.1 ve sonraki sürümler ile güzel değişkenler $ve jQueryglobal değişkenler olarak işlerim var.

JQuery'yi proje bağımlılığı olarak yükleyin. En @3.2.1son sürümü yüklemeyi ihmal edebilir veya başka bir sürüm belirleyebilirsiniz.

npm install --save jquery@3.2.1

expose-loaderHenüz yüklenmediyse geliştirme bağımlılığı olarak yükleyin .

npm install expose-loader --save-dev

Webpack'i bizim için jQuery'yi yükleyip gösterecek şekilde yapılandırın.

// 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-loaderDüzgün çalışması için yüklemeniz gerektiğini belirtmeyi unuttunuznpm install expose-loader --save-dev
Paulo Griiettner

4
Bu benim için çalıştı 👍. jquery: 3.3.1, açık yükleyici: 0.7.5, web paketi: 4.20.2
AKT

expose-loadedBenim için yaptı. Derleme zamanında bir hata almadım, ancak Chrome geliştirici araçlarında. Şimdi çözüldü.
Johan Vergeer

Teşekkür ederim! Bu, "jquery": "^ 3.4.1" ve "webpack": "^ 4.41.5" ile çalıştı. Sadece ben mi yoksa Web Pack ile çalışmak için jQuery almak bu kadar saçma olmamalı mı?
Carles Alcolea

18

Bunu webpack.config.js dosyasındaki eklenti dizinize ekleyin

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

sonra normalde jquery gerektirir

require('jquery');

Acı, onu görmek için diğer komut dosyalarını almaya devam ederse, (js girişinde) aracılığıyla açıkça genel bağlama yerleştirmeyi deneyin.

window.$ = jQuery;

18

Webpack.config.js dosyanıza aşağıdakileri ekleyin:

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

Npm kullanarak jQuery yükleyin:

$ npm i jquery --save

App.js dosyasına aşağıdaki satırları ekleyin:

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

Bu benim için çalıştı. :)


Örn. benim için jquery13981378127 ve pencerede örnekler olarak jquery12389723198 olsun?
Martea

8

Verilen cevaplardan bazılarını denedim ama hiçbiri işe yaramadı. Sonra bunu denedim:

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

Hangi sürümü kullandığım önemli değil


+1, buraya eklenen globallerin otomatik olarak pencereye ayarlanacağına dair bir yanlış anlama gibi görünüyor, açık olmanız gerektiği gibi çalışmıyor.
James

Doğru, bu onu pencere nesnesine eklemez. Web paketinin içinde bir pencere diğer adı oluşturur. Bu nedenle, web $paketinin gerekli dosyasının dışında kullanmaya çalışırsanız , tanımsız olur.
Cam Tullos

7

Bu webpack 3'te çalışır :

webpack.config.babel.js dosyasında:

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

Ve ProvidePlugin kullanın

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

1
Webpack'te (benim gibi!) Süper yeni olan diğerleri için "çözmek", webpack.config.js dosyasında module.exports = {} gibi giriş, çıkış, eklentiler, modül vb.
Gidiyor

1
Ve yeni webpack.ProvidePlugin, plugins dizisinin içine girer.
DavGarcia

2

Bulduğum en iyi çözüm:

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

Temel olarak, typings.d.ts dosyasına kukla bir değişken eklemeniz, "jquery" den herhangi bir "import *" kodunu "jquery" den kaldırmanız ve ardından jQuery betiğine SPA html'nize manuel olarak bir etiket eklemeniz gerekir. Bu şekilde, webpack sizin yolunuzda olmayacak ve tüm komut dosyalarınızda aynı global jQuery değişkenine erişebilmelisiniz.


2

Bu benim için webpack.config.js üzerinde çalışıyor

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

başka bir javascript veya HTML içine ekleyin:

global.jQuery = require('jquery');

0

Düzenleme: Bazen kendi paketinizi düzenli tutmak için web paketini basit bir web projesi için bir modül paketleyicisi olarak kullanmak istersiniz. Aşağıdaki çözüm, harici bir kütüphanenin modüllerinde beklendiği gibi çalışmasını isteyenler içindir - webpack kurulumlarına çok fazla zaman ayırmadan. (-1'den sonra düzenlendi)

Hala zorlanıyorsanız veya harici yapılandırma / ek web paketi eklenti yapılandırmasından kaçınmak istiyorsanız hızlı ve basit (es6) çözümü:

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

bir modülün içinde:

const { jQuery: $, Underscore: _, etc } = window;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.