Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add usage instructions with webpack #1435

Closed
fernandoacorreia opened this issue Jan 22, 2014 · 32 comments
Closed

Add usage instructions with webpack #1435

fernandoacorreia opened this issue Jan 22, 2014 · 32 comments

Comments

@fernandoacorreia
Copy link

Add to the section Where to use it instructions for properly integrating Moment.js with webpack.

require('momentjs/moment.js') causes several errors like this:

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') causes this warning:

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
@icambron
Copy link
Member

I've never used Webpack, so I'm unsure what those instructions would be. Were you able to figure it out? If so, we could add your instructions.

@fernandoacorreia
Copy link
Author

Thanks for the reply.

Not yet, but I'll keep you posted.

@sokra
Copy link

sokra commented Jan 23, 2014

The language files are looking for a module moment. See header:

    if (typeof define === 'function' && define.amd) {
        define(['moment'], factory); // AMD

moment is actually the correct name for this module (see package.json) and everything just works if you install it from npm.

@fernandoacorreia Your folder is named momentjs.

@icambron Why not define(['../moment'], factory); as with CommonJs?

It would be better when the order of CommonJs and AMD is consistent in the lang files and the moment.js file.


By default webpack includes all languages because of this statement require('./lang/' + k);. You can override this with the ContextReplacementPlugin:

new webpack.ContextReplacementPlugin(/moment[\\\/]lang$/, /^\.\/(en-gb|de|pl)$/)

@fernandoacorreia
Copy link
Author

@sokra Thanks for explaining about the inconsistency in the module definitions. @icambron can you take a look at these suggestions?

By the way, the directory is named momentjs because I installed it following the instructions here:

bower install --save momentjs

I'm declaring the pathname when requiring, like require ('momentjs/min/moment-with-langs.js').

@sokra
Copy link

sokra commented Jan 23, 2014

hmm ok... it works if you use the node.js instructions.

@fernandoacorreia
Copy link
Author

@sokra That helps. Thanks a lot for debugging this. Although I don't want to install it via npm; I'm installing all my frontend dependencies via bower and I only search for modules in bower_components.

@icambron To update the instructions to make it compatible with webpack (and, presumably, other module loaders), in the docs change this line:

bower install --save momentjs

to:

bower install --save moment=momentjs

@Sigfried
Copy link

Sigfried commented Feb 1, 2014

The npm instructions worked for me, but not bower install --save moment=momentjs

@fernandoacorreia
Copy link
Author

@Sigfried What does your bower.json file look like? Mine has this line:

"moment": "momentjs#~2.5.1"

My webpack.config.js has:

module.exports = {
  resolve: {
    alias: {
      moment: 'moment/moment.js',
    },
    modulesDirectories: ['app/bower_components']
  }
};

I'm requiring moment as:

var moment = require('moment');

I'm using a standard Yeoman directory structure.

@Sigfried
Copy link

Sigfried commented Feb 3, 2014

That did it for me. Thanks!
(Except I wasn't using Yeoman and now I'm wondering if I need to start doing that... The Javascript ecosystem is amazing, I've spend the last three months doing nothing but saving time! :)

@ichernev
Copy link
Contributor

Now you can use bower install --save moment

@fernandoacorreia
Copy link
Author

@ichernev That sounds good. In this case, I believe that updating the Where to use it documentation would resolve this issue.

@full-of-foo
Copy link

Bit late on this, but now one can use the provide plugin

    plugins: [
        new webpack.ProvidePlugin({
           "window.moment": "moment"
        }),
        new BowerWebpackPlugin()
    ]

@kadishmal
Copy link

As @sokra suggested, I have added the following plugin in order to require only the necessary locale. Also notice that lang directory in moment has been changed to locale.

plugins: [
    new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en|ko|ja|zh-cn)$/)
]

@mattjohnsonpint
Copy link
Contributor

Added doc item as moment/momentjs.com#269. Will track there.

@grbush
Copy link

grbush commented Jun 9, 2016

I'm using es6, typescript, and very tight tslint rules. This is what I ended up doing to get moment into the project:

import "expose?moment!imports?this=>window&exports=>false&define=>false!exports?window.moment!moment";

@neyer
Copy link

neyer commented Jun 29, 2016

I just created an empty 'locale' folder in the same folder as 'moment.min.js', so that it includes all of the js files in that folder.

It's a hack but it works.

@zdila
Copy link

zdila commented Jul 14, 2016

To load languages in Webpack lazy / dynamically you can use with bundle-loader:

Step 1 - in webpack configuration:

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // to not to load all locales

Step 2 - in the client code:

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
});

@micheleb
Copy link

micheleb commented Aug 19, 2016

In my case (webpack + npm install moment) the issue was with webpack looking for locales inside the src/lib/locale folder, because that's where moment.js was being picked up.

I removed the node_modules/moment/src folder altogether, and import moment setting its locale using e.g.:

import moment from 'moment';
import 'moment/locale/en-gb';
moment.locale('en-gb');

Everything works perfectly, no warnings, and only the locales I import explicitly are included in the build (even without using the webpack.ContextReplacementPlugin as explained in this comment, which I added at first)

@Jessidhia
Copy link

Jessidhia commented Sep 27, 2016

@micheleb the actual cause for looking in that subfolder is the incorrect setting of jsnext:main in momentjs's package.json, which is respected by webpack 2.

jsnext:main should not point to the raw source code, but to a build of the module that does use ES6 module syntax.

This can be worked around by aliasing 'moment' to 'moment/moment.js' (the commonjs "main") in your webpack config (resolve: { alias: { moment: 'moment/moment.js' } }).

EDIT: Alternatively, a use of the ContextReplacementPlugin that uses the locale data from the src dir (i.e. that requests the same moment module as jsnext:main) is similar to:

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'
  })
}),

This probably could be written without using the callback, but I wanted to be "more sure" that this would only apply to a ./locale request inside the moment module.

Make sure the request doesn't point to ../../../locale; while that will compile, it will result in 2 whole copies of moment being bundled.

@sokra what happens if async: true gets set in the context? I can see that the modules are generated as separate chunks if I do that, but what is the expected runtime behavior; a crash? I assume it is true "by default" if it's called for handling a require.ensure / System.import's context?

@leebenson
Copy link

was this fixed? if not, should it be re-opened?

@ajohnsonRH
Copy link

Why was this closed? This is still an occurring issue.

@butterflyhug
Copy link
Contributor

@ajohnsonRH

"I believe that updating the documentation would resolve this issue."

"Added doc item as moment/momentjs.com#269. Will track there."

So, the issue was closed here because it's been superseded by an issue in Moment's documentation website. We'd love for someone to write a PR there to resolve moment/momentjs.com#269.

@ajohnsonRH
Copy link

@butterflyhug

This fix worked for me:

  1. do the npm install
  2. open vendor.ts and add the line import 'moment'

For reference:
Using Angular2 v2.0.0, Webpack ^1.13.0

@orditeck
Copy link

Is it possible to not includes all the locale without adding configurations to webpack? I'm using create-react-app and I don't have the ability to edit the webpack config file.

I search everywhere and it always seems to come back to adding a config line in webpack.
#2373
#2416

@vperron
Copy link

vperron commented Dec 7, 2016

Agreed, I think requiring the locales should be explicit only, never implicit.

It's so obvious according to the number of issues raised here in moment, in webpack, in bower, npm, and the time spent by everyone to circumvent it since several years.

@trsh
Copy link

trsh commented Jan 2, 2017

@ajohnsonRH

I installed npm packs, but when I do

import moment from 'moment-timezone';

moment is always undefined. How that?

@johnjameshopley
Copy link

I am having this same problem using Angular 2 CLI project. Has anyone found a working solution yet?

@Lakston
Copy link

Lakston commented Nov 6, 2017

Looking for clues for an Angular CLI project too

@FlawaCLV
Copy link

FlawaCLV commented Feb 7, 2018

Any clues for Angular CLI ?

@Lakston
Copy link

Lakston commented Feb 8, 2018

As you can see I asked 4 months ago about the CLI and no answers, our solution was to simply replace moment with date-fns, and since we are also using chartjs in our project and it has a moment dependency we are in the process of replacing that too.

@plandem
Copy link

plandem commented Mar 29, 2018

quite nice solution
moment/momentjs.com#489

@dwilches
Copy link

How can this be solved for Angular CLI without ejecting the Webpack config?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests