Adicione à seção Onde usar instruções para integrar adequadamente o Moment.js com o webpack .
require('momentjs/moment.js')
causa vários erros como este:
ERROR in ./app/bower_components/momentjs/lang/ar-ma.js
Module not found: Error: Cannot resolve module moment in /home/fernando/work/myproject/myproject-manage-app/app/bower_components/momentjs/lang
@ ./app/bower_components/momentjs/lang/ar-ma.js 8:8-35
ERROR in ./app/bower_components/momentjs/lang/ar.js
Module not found: Error: Cannot resolve module moment in /home/fernando/work/myproject/myproject-manage-app/app/bower_components/momentjs/lang
@ ./app/bower_components/momentjs/lang/ar.js 8:8-35
require ('momentjs/min/moment-with-langs.js')
causa este aviso:
WARNING in ./app/bower_components/momentjs/min/moment-with-langs.js
Module not found: Error: Cannot resolve file or directory ./lang in /home/fernando/work/myproject/myproject-manage-app/app/bower_components/momentjs/min
@ ./app/bower_components/momentjs/min/moment-with-langs.js 808:24-46
Eu nunca usei o Webpack, então não tenho certeza de quais seriam essas instruções. Você conseguiu dar conta? Em caso afirmativo, podemos adicionar suas instruções.
Obrigado pela resposta.
Ainda não, mas te mantenho informado.
Os arquivos de idioma estão procurando um módulo moment
. Veja o cabeçalho:
if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
moment
é na verdade o nome correto para este módulo (veja package.json) e tudo funciona se você instalá-lo a partir do npm.
@fernandoacorreia Sua pasta se chama momentjs
.
@icambron Por que não define(['../moment'], factory);
como com CommonJs?
Seria melhor quando a ordem de CommonJs e AMD fosse consistente nos arquivos lang e no arquivo moment.js.
Por padrão, o webpack inclui todos os idiomas devido a esta instrução require('./lang/' + k);
. Você pode substituir isso com ContextReplacementPlugin
:
new webpack.ContextReplacementPlugin(/moment[\\\/]lang$/, /^\.\/(en-gb|de|pl)$/)
@sokra Obrigado por explicar sobre a inconsistência nas definições do módulo. @icambron pode dar uma olhada nessas sugestões?
A propósito, o diretório se chama momentjs
porque eu o instalei seguindo as instruções aqui :
bower install --save momentjs
Estou declarando o nome do caminho ao exigir, como require ('momentjs/min/moment-with-langs.js')
.
hmm ok... funciona se você usar as instruções do node.js.
@sokra Isso ajuda. Muito obrigado por depurar isso. Embora eu não queira instalá-lo via npm; Estou instalando todas as minhas dependências de frontend via bower e só procuro módulos em bower_components
.
@icambron Para atualizar as instruções para torná-lo compatível com webpack (e, presumivelmente, outros carregadores de módulo), nos documentos altere esta linha:
bower install --save momentjs
para:
bower install --save moment=momentjs
As instruções do npm funcionaram para mim, mas não bower install --save moment=momentjs
@Sigfried Como é o seu arquivo bower.json
? O meu tem essa linha:
"moment": "momentjs#~2.5.1"
Meu webpack.config.js
tem:
module.exports = {
resolve: {
alias: {
moment: 'moment/moment.js',
},
modulesDirectories: ['app/bower_components']
}
};
Estou exigindo momento como:
var moment = require('moment');
Estou usando uma estrutura de diretório padrão do Yeoman.
Isso fez isso por mim. Obrigado!
(Exceto que eu não estava usando o Yeoman e agora estou me perguntando se preciso começar a fazer isso... O ecossistema Javascript é incrível, passei os últimos três meses sem fazer nada além de economizar tempo! :)
Agora você pode usar bower install --save moment
@ichernev Isso soa bem. Nesse caso, acredito que atualizar a documentação de Onde usar resolveria esse problema.
Um pouco atrasado nisso, mas agora é possível usar o plug-in de fornecimento
plugins: [
new webpack.ProvidePlugin({
"window.moment": "moment"
}),
new BowerWebpackPlugin()
]
Como @sokra sugeriu, adicionei o seguinte plugin para exigir apenas a localidade necessária. Observe também que o diretório lang
em moment
foi alterado para locale
.
plugins: [
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en|ko|ja|zh-cn)$/)
]
Item de documento adicionado como moment/momentjs.com#269. Vai rastrear lá.
Estou usando es6, typescript e regras tslint muito rígidas. Isto é o que acabei fazendo para entrar no projeto:
import "expor?momento!importa?this=>janela&exports=>falso&define=>falso!exporta?janela.momento!momento";
Acabei de criar uma pasta 'locale' vazia na mesma pasta que 'moment.min.js', para que inclua todos os arquivos js nessa pasta.
É um hack mas funciona.
Para carregar idiomas no Webpack preguiçosamente / dinamicamente você pode usar com bundle-loader
:
Passo 1 - na configuração do webpack:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // to not to load all locales
Passo 2 - no código do cliente:
require('bundle!moment/locale/' + locale + '.js')(function () {
moment().locale(locale).format('lll');
// note that now you can use the locale even outside of this callback
});
No meu caso (webpack + npm install moment
) o problema foi com o webpack procurando por locales dentro da pasta src/lib/locale
, porque era onde moment.js
estava sendo pego.
Eu removi a pasta node_modules/moment/src
completamente e importei o momento definindo sua localidade usando, por exemplo:
import moment from 'moment';
import 'moment/locale/en-gb';
moment.locale('en-gb');
Tudo funciona perfeitamente, sem avisos, e apenas as localidades que importo explicitamente são incluídas na compilação (mesmo sem usar o webpack.ContextReplacementPlugin
conforme explicado neste comentário , que adicionei no início)
@micheleb a causa real para procurar nessa subpasta é a configuração incorreta de jsnext:main
no package.json
do momentjs, que é respeitado pelo webpack 2.
jsnext:main
deve _não_ apontar para o código-fonte bruto, mas para uma compilação do módulo que usa a sintaxe do módulo ES6.
Isso pode ser contornado com o alias de 'moment'
para 'moment/moment.js'
(o commonjs "principal") na configuração do seu webpack ( resolve: { alias: { moment: 'moment/moment.js' } }
).
EDIT: Alternativamente, um uso do ContextReplacementPlugin
que usa os dados de localidade do diretório src
(ou seja, que solicita o mesmo módulo moment
que jsnext:main
) é igual a:
new webpack.ContextReplacementPlugin(/^\.\/locale$/, context => {
if (!/\/moment\//.test(context.context)) { return }
// context needs to be modified in place
Object.assign(context, {
// include only CJK
regExp: /^\.\/(ja|ko|zh)/,
// point to the locale data folder relative to moment's src/lib/locale
request: '../../locale'
})
}),
Isso provavelmente poderia ser escrito sem usar o retorno de chamada, mas eu queria ter "mais certeza" de que isso se aplicaria apenas a uma solicitação ./locale
dentro do módulo moment
.
Certifique-se de que request
não aponta para ../../../locale
; enquanto isso compila, resultará em 2 cópias inteiras de moment
sendo empacotadas.
@sokra o que acontece se async: true
for definido no contexto? Eu posso ver que os módulos são gerados como pedaços separados se eu fizer isso, mas qual é o comportamento de tempo de execução esperado; um acidente? Eu suponho que é true
"por padrão" se for chamado para manipular um contexto require.ensure
/ System.import
?
isso foi corrigido? se não, deve ser reaberto?
Por que isso foi fechado? Este ainda é um problema que está ocorrendo.
@ajohnsonRH
"Acredito que atualizar a documentação resolveria esse problema."
"Adicionado item de documento como moment/momentjs.com#269. Será rastreado lá."
Portanto, o problema foi encerrado aqui porque foi substituído por um problema no site de documentação do Moment. Adoraríamos que alguém escrevesse um PR lá para resolver moment/momentjs.com#269.
@butterflyhug
Esta correção funcionou para mim:
import 'moment'
Para referência:
Usando Angular2 v2.0.0, Webpack ^1.13.0
É possível não incluir toda a localidade sem adicionar configurações ao webpack? Estou usando o create-react-app e não tenho a capacidade de editar o arquivo de configuração do webpack.
Eu pesquiso em todos os lugares e sempre parece voltar a adicionar uma linha de configuração no webpack.
https://github.com/moment/moment/issues/2373
https://github.com/moment/moment/issues/2416
Concordo, acho que exigir as localidades deve ser apenas explícito, nunca implícito.
É tão óbvio de acordo com o número de problemas levantados aqui no momento, no webpack, no bower, npm, e o tempo gasto por todos para contorná-lo desde vários _anos_.
@ajohnsonRH
Eu instalei pacotes npm, mas quando eu faço
importe o momento do 'momento-fuso horário';
momento é sempre indefinido. Como isso?
Estou tendo esse mesmo problema usando o projeto Angular 2 CLI. Alguém já encontrou uma solução funcional?
Procurando pistas para um projeto Angular CLI também
Alguma pista para o Angular CLI?
Como você pode ver, perguntei há 4 meses sobre a CLI e nenhuma resposta, nossa solução foi simplesmente substituir moment por date-fns, e como também estamos usando chartjs em nosso projeto e tem uma dependência de momento, estamos no processo de substituindo isso também.
solução bem legal
https://github.com/moment/momentjs.com/pull/489
Comentários muito úteis
Como @sokra sugeriu, adicionei o seguinte plugin para exigir apenas a localidade necessária. Observe também que o diretório
lang
emmoment
foi alterado paralocale
.