Come impedire a moment.js di caricare locales con webpack?


199

Esiste un modo per interrompere il moment.jscaricamento di tutte le versioni locali (ho solo bisogno dell'inglese) quando si utilizza il webpack? Sto guardando la fonte e sembra che se hasModuleè definito, che è per il webpack, cerca sempre in require()ogni locale. Sono abbastanza sicuro che per risolvere sia necessaria una richiesta pull. Ma c'è un modo per risolverlo con la configurazione del webpack?

Ecco la mia configurazione del webpack per caricare momentjs:

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

Quindi, ovunque ne abbia bisogno, lo faccio e basta require('moment'). Funziona ma aggiunge circa 250 kB di file di lingua non necessari al mio pacchetto. Inoltre sto usando la versione pergolata di momentjs e gulp.

Inoltre, se ciò non può essere risolto dalla configurazione del webpack, ecco un collegamento alla funzione in cui carica le impostazioni locali . Ho provato ad aggiungere && module.exports.loadLocalesalla ifdichiarazione ma immagino che il webpack in realtà non funzioni in un modo in cui funzionerebbe. Non requireimporta quale. Penso che ora usi una regex, quindi non so davvero come faresti per risolverlo.


Hai provato a usare moment tramite nmpinvece di bower?
Andreas Köberle,

Sto usando bower per tutte le mie librerie client e npm per tutti i miei strumenti di compilazione. Voglio continuare in questo modo a causa di come sono strutturati i miei progetti. Inoltre, se guardi l'ultima risposta di github.com/moment/moment/issues/1866, ho risolto il mio problema, ma richiede una modifica della fonte minore. Non so ancora come risolverlo nel modo giusto perché non so come distingueresti tra nodo e webpack.
epelc,

Risposte:


305

Il codice require('./locale/' + name)può utilizzare tutti i file nella directory locale. Quindi il webpack include tutti i file come modulo nel tuo bundle. Non può sapere quale lingua stai usando.

Esistono due plugin utili per fornire al webpack maggiori informazioni su quale modulo deve essere incluso nel pacchetto: ContextReplacementPlugine IgnorePlugin.

require('./locale/' + name)viene chiamato contesto (un requisito che contiene un'espressione). webpack fornisce alcune informazioni da questo frammento di codice: una directory e un'espressione regolare. Qui: directory = ".../moment/locale" regular expression = /^.*$/. Quindi, per impostazione predefinita, tutti i file nella localedirectory sono inclusi.

Ciò ContextReplacementPluginconsente di sovrascrivere le informazioni dedotte, ovvero fornire una nuova espressione regolare (per scegliere le lingue che si desidera includere).

Un altro approccio è ignorare la richiesta con il IgnorePlugin.

Ecco un esempio:

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

3
Puoi spiegare come usare il caricatore ignore? Ho provato `nuovo webpackreg.IgnorePlugin (/\.\/ locale \ /.+. Js $ /, [])` ma non ha funzionato. Anche il contextReplacementPlugin includeva ancora i file nel mio bundle, penso solo che non li usasse.
epelc,

9
Puoi dare un'occhiata a questo problema ( github.com/webpack/webpack/issues/198 ) che contiene una discussione dettagliata su moment + webpack.
Tobias K.,

2
Grazie, penso che new webpack.IgnorePlugin(/^\.\/lang$/, /moment$/)dal tuo commento su Github funzionerà.
epelc,

16
Nei documenti webpack, il secondo argomento è una matrice di regex. Ho provato plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]) ],che ha funzionato bene.
Alex K

6
@AlexKinnee La notazione tra parentesi nei documenti significa che è un argomento facoltativo, non un array.
yangmillstheory,

8

Nel nostro progetto, includo un momento come questo: import moment from 'moment/src/moment';e questo sembra fare il trucco. Il nostro uso del momento è molto semplice, quindi non sono sicuro che ci saranno incongruenze con l'SDK. Penso che funzioni perché WebPack non sa come trovare staticamente i file delle impostazioni locali, quindi ricevi un avviso (che è facile da nascondere aggiungendo una cartella vuota in moment/src/lib/locale/locale) ma nessuna impostazione locale include.


1
Non sono sicuro ragazzi come questo funziona per voi ... Ho appena provato a combattere quel github.com/angular/angular-cli/issues/6137 e poi ho finito per usare github.com/ksloan/moment-mini . La momentlibreria modulare corretta presenterà la versione 3 github.com/moment/moment/milestone/15 a un certo punto.
kuncevic.dev,


2

Sulla base della risposta di Adam McCrmick, eri vicino, cambia il tuo alias in:

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

1
Solo un avvertimento, che questo cambierà il comportamento di tutti i moduli che includi e potrebbe causare problemi interessanti con le librerie di terze parti. Dovrebbe funzionare in generale però
Adam McCormick il

1
Puoi elaborare ? Non ho esperienza con tutti i casi d'uso di alias. A mio avviso, importerebbe solo se si toccasse quel modulo, in questo caso "momento"
bigopon,

3
Quando si impostano gli alias di risoluzione, si applicano a qualsiasi utilizzo dell'importazione o richiesto nel sistema (comprese le librerie da cui si dipende). Quindi, se un modulo dipende dal momento richiesto, cambieresti anche il risultato per quel modulo. Questo si presenta se ti capita di impostare un alias che è in conflitto con un modulo di nodo nel tuo albero delle dipendenze (come "eventi", ad esempio se le tue dipendenze usano quella libreria). In pratica, ho avuto solo un problema con i conflitti di nomi, non con i perfezionamenti del comportamento come questo, ma questo è un approccio più pericoloso rispetto alla modifica di una dichiarazione di importazione.
Adam McCormick

2

Con webpack2e le versioni recenti di moment puoi fare:

import {fn as moment} from 'moment'

E poi dentro webpack.config.js te fai:

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

1
Immagino tu voglia diremainFields: ...
Guillermo Grau,

Guarda webpack2, abbastanza sicuro che il nome del campo sia cambiato.
Kevin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.