Як не допустити, щоб moment.js не завантажував локалі за допомогою веб-пакета?


199

Чи є якийсь спосіб, коли ви не можете moment.jsзавантажувати всі локалі (мені просто потрібна англійська мова), коли ви використовуєте веб-пакет? Я дивлюся на джерело, і здається, що якщо hasModuleвизначено, що це для webpack, то воно завжди намагається перейти до require()кожної локалі. Я впевнений, що для виправлення потрібен запит на витяг. Але чи можна це виправити за допомогою конфігурації webpack?

Ось моя конфігурація веб-пакета для завантаження momentjs:

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

Тоді, де мені це потрібно, я просто роблю require('moment'). Це працює, але додає близько 250 кБ непотрібних мовних файлів у мій пакет. Також я використовую бауер-версію momentjs та gulp.

Також якщо конфігурація веб-пакету цього неможливо виправити, тут є посилання на функцію, де вона завантажує локалі . Я спробував додати && module.exports.loadLocalesдо ifзаяви, але, мабуть, webpack насправді не працює таким чином, де це буде працювати. Це просто requireнезважаючи ні на що. Я думаю, що зараз він використовує регулярний вираз, тому я не знаю, як би ви навіть вирішили його виправити.


Ви намагалися використати момент через, nmpа не bower?
Andreas Köberle

Я використовую bower для всіх моїх клієнтських ліфтів і npm для всіх своїх інструментів збирання. Я хочу зберегти це таким чином через те, як складаються мої проекти. Також якщо ви подивитесь на останню відповідь github.com/moment/moment/isissue/1866, я вирішив власну проблему, але вона потребує незначного редагування джерела. Я досі не знаю, як це виправити правильним способом, оскільки я не знаю, як би ви відрізняли вузол від webpack.
epelc

Відповіді:


305

Код require('./locale/' + name)може використовувати кожен файл у режимі locale. Тож вебпакет включає кожен файл як модуль у вашому пакеті. Він не може знати, якою мовою ви користуєтесь.

Є два плагіни , які корисні для того, щоб дати веб-упаковці більше інформації про те, який модуль повинен бути включений у ваш пакет: ContextReplacementPluginта IgnorePlugin.

require('./locale/' + name)називається контекстом (потреба, яка містить вираз). webpack виводить деяку інформацію з цього фрагмента коду: Каталог та регулярний вираз. Тут: directory = ".../moment/locale" regular expression = /^.*$/. Отже, за замовчуванням кожен файл у localeкаталозі включений.

ContextReplacementPluginДозволяє перевизначити виведену інформацію тобто забезпечити нове регулярне вираз (вибрати мови , які ви хочете включити).

Іншим підходом є ігнорування вимоги з IgnorePlugin.

Ось приклад:

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

3
Чи можете ви пояснити, як користуватися завантажувачем ігнорування? Я спробував `new webpackreg.IgnorePlugin (/\.\/ locale \ /.+. Js $ /, [])`, але це не спрацювало. Також contextReplacementPlugin все ще включав файли в мій пакет, я просто думаю, що він не використовував їх.
epelc

9
Ви можете подивитися на цю проблему ( github.com/webpack/webpack/isissue/198 ), яка містить детальну дискусію про момент + webpack.
Тобіас К.

2
Дякую, я думаю, що new webpack.IgnorePlugin(/^\.\/lang$/, /moment$/)з вашого коментаря до github вийде.
epelc

16
У документах webpack другий аргумент - це масив регулярних виразів. Я спробував, plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]) ],який спрацював чудово.
Алекс К

6
@AlexKinnee Позначення дужок у документах означає, що це необов'язковий аргумент, а не масив.
yangmillstheory

8

У нашому проекті я включаю такий момент: import moment from 'moment/src/moment';і це, здається, робить свою справу. Наше використання моменту дуже просто, тому я не впевнений, чи будуть невідповідності з SDK. Я думаю, що це працює, тому що WebPack не знає, як статично знайти файли локалів, тому ви отримуєте попередження (це легко приховати, додавши порожню папку в moment/src/lib/locale/locale), але жодна локаль не включає.


1
Не впевнені, хлопці, як ця працює для вас ... Мене просто намагалися боротись з цим github.com/angular/angular-cli/isissue/6137, а потім просто закінчилися за допомогою github.com/ksloan/moment-mini . Власна модульна momentбібліотека придумає версію 3 github.com/moment/moment/milestone/15 в якийсь момент.
kuncevic.dev


2

Виходячи з відповіді Адама МакКрміка, ви були поруч, змінивши псевдонім на:

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

1
Лише застереження про те, що це змінить поведінку для всіх модулів, які ви включаєте, і може спричинити цікаві проблеми з сторонніми бібліотеками. Це повинно працювати взагалі
Адам Маккормік

1
Чи можете ви докладно? Я не досвідчений у всіх випадках використання псевдонімів. На моє розуміння, було б важливо лише, якщо ви торкнулися цього модуля, в даному випадку "моменту"
bigopon

3
Під час встановлення псевдонімів дозвіл вони застосовуються до будь-якого використання імпорту або необхідності у вашій системі (включаючи бібліотеки, від яких ви залежите). Отже, якщо модуль, від якого ви залежите від потрібного моменту, ви б змінювали результат і для цього модуля. Це з'являється, якщо вам трапляється встановити псевдонім, який конфліктує з модулем вузла у вашому дереві залежностей (наприклад, "події", наприклад, якщо ваші залежності використовують цю бібліотеку). На практиці у мене виникли лише проблеми з конфліктами імен, а не вдосконаленнями поведінки, як це, але це більш небезпечний підхід, ніж зміна однієї заяви про імпорт.
Адам МакКормік

2

З webpack2моментом та останніми версіями моменту ви можете:

import {fn as moment} from 'moment'

А потім у webpack.config.jsвас:

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

1
Гадаю, ти маєш на увазіmainFields: ...
Гільєрмо Грау

Подивіться на webpack2, майже впевнений, що назва поля змінилася.
Кевін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.