Làm cách nào để ngăn khoảnh khắc tải địa phương bằng webpack?


199

Có cách nào bạn có thể dừng moment.jstải tất cả các ngôn ngữ (tôi chỉ cần tiếng Anh) khi bạn đang sử dụng webpack không? Tôi đang xem nguồn và dường như nếu hasModuleđược xác định, đó là cho webpack, thì nó luôn cố gắng đến require()mọi miền. Tôi khá chắc chắn rằng điều này cần một yêu cầu kéo để sửa chữa. Nhưng có cách nào chúng ta có thể khắc phục điều này với cấu hình webpack không?

Đây là cấu hình webpack của tôi để tải Momentjs:

resolve: {
            alias: {
                moment: path.join(__dirname, "src/lib/bower/moment/moment.js")
            },
        },

Sau đó, bất cứ nơi nào tôi cần nó, tôi chỉ cần làm require('moment'). Điều này hoạt động nhưng nó thêm khoảng 250 kB các tệp ngôn ngữ không cần thiết vào gói của tôi. Ngoài ra, tôi đang sử dụng phiên bản bower của Momentjs và gulp.

Ngoài ra, nếu điều này không thể được sửa bởi cấu hình webpack ở đây là một liên kết đến chức năng nơi nó tải các địa phương . Tôi đã thử thêm && module.exports.loadLocalesvào ifcâu lệnh nhưng tôi đoán webpack không thực sự hoạt động theo cách mà nó sẽ hoạt động. Nó chỉ requirelà không có vấn đề gì. Tôi nghĩ rằng nó sử dụng một regex ngay bây giờ vì vậy tôi thực sự không biết làm thế nào bạn thậm chí sẽ sửa chữa nó.


Bạn đã thử sử dụng khoảnh khắc thông qua nmpthay vì bower?
Andreas Köberle

Tôi đang sử dụng Bower cho tất cả các lib khách hàng của mình và npm cho tất cả các công cụ xây dựng của tôi. Tôi muốn giữ nó theo cách này vì cách các dự án của tôi được đặt ra. Ngoài ra nếu bạn xem câu trả lời cuối cùng của github.com/moment/moment/issues/1866 Tôi đã giải quyết vấn đề của riêng mình nhưng nó yêu cầu chỉnh sửa nguồn nhỏ. Tôi vẫn không biết cách khắc phục điều này đúng cách vì tôi không biết làm thế nào để bạn phân biệt giữa nút và webpack.
epelc

Câu trả lời:


305

require('./locale/' + name)có thể sử dụng mọi tập tin trong localethư mục. Vì vậy, gói web bao gồm mọi tệp dưới dạng mô-đun trong gói của bạn. Nó không thể biết bạn đang sử dụng ngôn ngữ nào.

hai plugin hữu ích để cung cấp cho webpack thêm thông tin về mô-đun nào sẽ được bao gồm trong gói của bạn: ContextReplacementPluginIgnorePlugin.

require('./locale/' + name)được gọi là một bối cảnh (một yêu cầu có chứa một biểu thức). webpack chứa một số thông tin từ đoạn mã này: Một thư mục và một biểu thức chính quy. Đây : directory = ".../moment/locale" regular expression = /^.*$/. Vì vậy, theo mặc định, tất cả các tập tin trong localethư mục được bao gồm.

Các ContextReplacementPluginphép để ghi đè lên thông tin suy ra tức là cung cấp một biểu thức chính quy mới (chọn ngôn ngữ bạn muốn bao gồm).

Một cách tiếp cận khác là bỏ qua các yêu cầu với IgnorePlugin.

Đây là một ví dụ:

var webpack = require("webpack");
module.exports = {
  // ...
  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|fr|hu/)
    // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
};

3
Bạn có thể giải thích làm thế nào để sử dụng bộ nạp bỏ qua? Tôi đã thử `webpackreg.IgnorePlugin mới (/\.\/ locale \ /.+. Js $ /, [])` nhưng không được. Ngoài ra, bối cảnhReplocationPlugin vẫn bao gồm các tệp trong gói của tôi, tôi chỉ nghĩ rằng nó không sử dụng chúng.
epelc

9
Bạn có thể xem xét vấn đề này ( github.com/webpack/webpack/issues/198 ) trong đó có một cuộc thảo luận chi tiết về khoảnh khắc + webpack.
Tobias K.

2
Cảm ơn bạn Tôi nghĩ new webpack.IgnorePlugin(/^\.\/lang$/, /moment$/)từ nhận xét của bạn về github sẽ hoạt động.
epelc

16
Trong các tài liệu webpack, đối số thứ hai là một mảng các biểu thức chính quy. Tôi đã thử plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]) ],mà làm việc tốt.
Alex K

6
@AlexKinnee Ký hiệu ngoặc trong tài liệu có nghĩa là đối số tùy chọn, không phải là một mảng.
yangmillstheory

8

Trong dự án của chúng tôi, tôi bao gồm khoảnh khắc như thế này: import moment from 'moment/src/moment';và điều đó dường như thực hiện mánh khóe. Việc sử dụng thời điểm của chúng tôi rất đơn giản, vì vậy tôi không chắc sẽ có bất kỳ mâu thuẫn nào với SDK hay không. Tôi nghĩ điều này hoạt động vì WebPack không biết cách tìm các tệp miền địa phương một cách tĩnh, do đó bạn nhận được cảnh báo (rất dễ để ẩn bằng cách thêm một thư mục trống tại moment/src/lib/locale/locale) nhưng không có ngôn ngữ nào bao gồm.


1
Không chắc mọi người làm thế nào cái này hoạt động cho bạn ... Tôi chỉ cố gắng chiến đấu với github.com/angular/angular-cli/issues/6137 và sau đó kết thúc bằng cách sử dụng github.com/ksloan/moment-mini . momentThư viện mô-đun thích hợp sẽ xuất hiện với Phiên bản 3 github.com/moment/moment/milestone/15 tại một số điểm.
kuncevic.dev


2

Dựa trên câu trả lời của Adam McCrmick, bạn đã gần gũi, thay đổi bí danh của bạn thành:

resolve: {
    alias: {
        moment: 'moment/src/moment'
    },
},

1
Chỉ cần một lời cảnh báo, điều này sẽ thay đổi hành vi cho tất cả các mô-đun bạn đưa vào và có thể gây ra sự cố thú vị với các thư viện của bên thứ ba. Nó nên hoạt động nói chung mặc dù
Adam McCormick

1
Bạn có thể xây dựng ? Tôi không có kinh nghiệm với tất cả các trường hợp sử dụng bí danh. Theo hiểu biết của tôi, sẽ chỉ có vấn đề nếu bạn chạm vào mô-đun đó, trong trường hợp này là 'khoảnh khắc'
bigopon

3
Khi bạn đặt bí danh giải quyết, chúng sẽ áp dụng cho mọi hoạt động nhập hoặc yêu cầu trong hệ thống của bạn (bao gồm cả các thư viện mà bạn phụ thuộc). Vì vậy, nếu một mô-đun bạn phụ thuộc vào thời điểm cần thiết, bạn cũng sẽ thay đổi kết quả cho mô-đun đó. Điều này xuất hiện nếu bạn tình cờ đặt bí danh xung đột với mô-đun nút trong cây phụ thuộc của bạn (ví dụ như "sự kiện" nếu phụ thuộc của bạn sử dụng thư viện đó). Trong thực tế, tôi chỉ gặp vấn đề với xung đột tên, không phải là các sàng lọc hành vi như thế này, nhưng đây là một cách tiếp cận nguy hiểm hơn là thay đổi một tuyên bố nhập khẩu.
Adam McCormick

2

Với webpack2và các phiên bản gần đây của khoảnh khắc bạn có thể làm:

import {fn as moment} from 'moment'

Và sau đó trong webpack.config.jsbạn làm:

resolve: {
    packageMains: ['jsnext:main', 'main']
}

1
Tôi đoán ý bạn làmainFields: ...
Guillermo Grau

Nhìn vào webpack2, khá chắc chắn rằng tên trường đã thay đổi.
Kevin
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.