Tiếp xúc jQuery với đối tượng Window thực với Webpack


111

Tôi muốn hiển thị đối tượng jQuery với đối tượng cửa sổ chung có thể truy cập được bên trong bảng điều khiển dành cho nhà phát triển trong trình duyệt. Bây giờ trong cấu hình webpack của tôi, tôi có các dòng sau:

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

Những dòng này thêm các định nghĩa jQuery vào mỗi tệp trong mô-đun webpack của tôi. Nhưng khi tôi xây dựng dự án và cố gắng truy cập jQuery trong bảng điều khiển dành cho nhà phát triển như sau:

window.$;
window.jQuery;

nó nói rằng những thuộc tính này là không xác định ...

Có cách nào để sửa lỗi này?


1
Tôi cũng có thể đặt this: 'window'? Kể từ nhiều thư viện giả thisbiến là đối tượng Window
Abhinav Singi

Câu trả lời:


129

Bạn cần sử dụng bộ tải tiếp xúc .

npm install expose-loader --save-dev

Bạn có thể làm điều này khi bạn yêu cầu:

require("expose?$!jquery");

hoặc bạn có thể làm điều này trong cấu hình của mình:

loaders: [
    { test: require.resolve('jquery'), loader: 'expose?jQuery!expose?$' }
]

CẬP NHẬT : Kể từ webpack 2, bạn cần sử dụng trình tải tiếp xúc thay vì hiển thị :

module: {
    rules: [{
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: '$'
        }]
    }]
}

11
Chủ ProvidePluginyếu nên được sử dụng trong các tình huống mà các thư viện của bên thứ ba dựa vào sự hiện diện của một biến toàn cục.
Johannes Ewald

Tôi đã giả định không chính xác các câu hỏi đã sử dụng cung cấp plug-in cho các mục đích 'lười' mà tôi đã thấy rất nhiều trên mạng nhưng bạn là chính xác :)
Matt Derrick

8
Đây chính xác là những gì tôi đang tìm kiếm và chỉ để bổ sung thêm, đối với bộ tải, bạn cũng có thể làm điều đó trong một dòng:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Fernando

8
Bạn không thể chỉ thêm một tập lệnh đầu tiên được không $ = require('jquery'); window.jQuery = $; window.$ = $;? (không cần expose-loader)
herman

1
Theo trang GitHub lộ-loader cú pháp webpack 2 như sau: module: { rules: [{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }] }. Đây là cách duy nhất tôi có thể tiếp xúc với jQuery và nó sử dụng cú pháp module.rules mới .
Gavin Sutherland

84

SupplyPlugin thay thế một biểu tượng trong một nguồn khác thông qua việc nhập tương ứng, nhưng không hiển thị biểu tượng trên không gian tên chung. Một ví dụ cổ điển là các plugin jQuery. Hầu hết chúng chỉ mong đợi jQueryđược xác định trên toàn cầu. Với câu lệnh, ProvidePluginbạn sẽ đảm bảo rằng jQuery là một phần phụ thuộc (ví dụ: đã được tải trước đó) và sự xuất hiện jQuerytrong mã của chúng sẽ được thay thế bằng phần thô của webpack require('jquery').

Nếu bạn có các tập lệnh bên ngoài dựa vào biểu tượng để nằm trong không gian tên chung (như giả sử JS được lưu trữ bên ngoài, các lệnh gọi Javascript trong Selenium hoặc đơn giản là truy cập vào biểu tượng trong bảng điều khiển của trình duyệt), bạn muốn sử dụng expose-loaderthay thế.

Nói ngắn gọn: Cung cấp quản lý thời gian xây dựng phụ thuộc vào các ký hiệu toàn cục trong khi expose-loaderquản lý thời gian chạy phụ thuộc vào các ký hiệu toàn cầu.


2
Cảm ơn vì lời giải thích
Foton

Ví dụ cung cấpPlugin với webpack từ tài liệu chính thức: webpack.js.org/plugins/provide-plugin/#usage-jquery
James Gentes

33

Có vẻ như windowđối tượng được hiển thị trong tất cả các mô-đun.

Tại sao không chỉ nhập / yêu cầu JQueryvà đặt:

window.$ = window.JQuery = JQuery;

Bạn sẽ cần đảm bảo rằng điều này xảy ra trước khi yêu cầu / nhập bất kỳ mô-đun nào sử dụng window.JQuery, trong mô-đun yêu cầu hoặc trong mô-đun nơi nó đang được sử dụng.


Giải pháp dễ dàng nhất mà không cần thêm phụ thuộc mới. Cảm ơn!
fatihpense

Điều đó sẽ không hoạt động khi sử dụng các mô-đun lồng nhau khác bằng cách sử dụng biến, chỉ là 'không được xác định'
aboutqx

4
Vâng nó hoạt động khi sử dụng requiretrong khi khôngimport
aboutqx

@aboutqx Không chắc ý bạn. Câu trả lời của tôi giả định rằng JQuery đã được nhập / bắt buộc và được gán cho một biến có tên JQuery.
mhess

2
@mhess khi bạn sử dụng import, bạn có thể gặp lỗi, vì imports được sắp xếp ở đầu tệp và requireở lại vị trí của chúng. Vì vậy, thứ tự chạy chỉ thay đổi importkhi cửa sổ có thể phân chia được không được đặt.
aboutqx

16

Điều này luôn luôn làm việc cho tôi. bao gồm cả webpack 3 window.$ = window.jQuery = require("jquery");


2
giải pháp tốt nhất ! 2018
waza123

6

Không có điều nào ở trên phù hợp với tôi. (và tôi thực sự không thích cú pháp của trình tải tiếp xúc). Thay thế,

Tôi đã thêm vào webpack.config.js:

var webpack = require('webpack');
module.exports = {
   plugins: [
       new webpack.ProvidePlugin({
           $: 'jquery',
       })     
   ]
}

Hơn tất cả các mô-đun có quyền truy cập thông qua jQuery thông qua $.

Bạn có thể hiển thị nó trên cửa sổ bằng cách thêm phần sau vào bất kỳ mô-đun nào của bạn được gói bởi webpack:

window.$ = window.jQuery = $

1
Điều này đã hiệu quả với tôi khi sử dụng webpack-stream đằng sau hậu trường
klewis 18/09/19

1

Cập nhật cho Webpack v2

Cài đặt bộ tải tiếp xúc như Matt Derrick mô tả:

npm install expose-loader --save-dev

Sau đó, chèn đoạn mã sau vào webpack.config.js:

module.exports = {
    entry: {
        // ...
    },
    output: {
        // ...
    },
    module: {
        loaders: [
                { test: require.resolve("jquery"), loader: "expose-loader?$!expose-loader?jQuery" }
        ]
    }
};

(từ tài liệu của trình tải tiếp xúc )


Bây giờ tôi không còn có thể làm cho nó hoạt động trong bất kỳ phiên bản Webpack nào nữa. Không chắc gì đã thay đổi nhưng cách duy nhất tôi có thể nhận jQuery hoặc $ để được công nhận là để làmwindow.jQuery = require('jquery');
trpt4him

0

Trong trường hợp của tôi hoạt động

{ test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" } 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.