Moment: require moment without locales

Created on 12 Jun 2015  ·  20Comments  ·  Source: moment/moment

I am using moment in a webpack build.

It looks like require('moment') is the equivalent of using moment-with-locales.min.js from CDN (judging mainly by the size increase in my bundle).

Is there a way to require moment with only the default english locale? (i.e. the equivalen of moment.min.js from CDN).

I guess my question is related to #2373

Most helpful comment

I just experienced the same issue as you with webpack. This SO post covers 2 different ways to avoid packaging the locales: http://stackoverflow.com/a/25426019/239965

The IgnorePlugin did the job for me:

plugins: [
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]

All 20 comments

I just experienced the same issue as you with webpack. This SO post covers 2 different ways to avoid packaging the locales: http://stackoverflow.com/a/25426019/239965

The IgnorePlugin did the job for me:

plugins: [
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]

Very cool, thanks @balexand

The IgnorePlugin does the job, I'm down to 11kb gzipped when adding moment.

Still would be nice to have the option to require with locales or without locales. Closing this one, as there is already #2373

According to this comment, there should be a moment without locales on npmjs.

this module exposes moment without the locales https://github.com/ksloan/moment-mini

Using moment with angular-cli so got the whole locale ended up in my bundle.

image

As I am not using --eject flag this one https://github.com/moment/moment/issues/2416#issuecomment-111713308 in not working for me. Is there any solution with angular-cli to exclude the locale?

@balexand Thanks, it works for me

If someone misses typings, here's my fork:

https://github.com/kirillgroshkov/moment-mini-ts

npm i moment-mini-ts

import * as moment from 'moment-mini-ts'

How about ignoring all locales with IgnorePlugin except some of my choosing? For example, ignore all except EN, ES, FR. Can that be done with a regular expression?

plugins: [
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]

Edit: I figured It out, in case someone still needs it. Found in https://stackoverflow.com/a/25426019/2477303

plugins: [
  new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|es|fr/),
  // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]

@kuncevic, did you achieve to exclude locale with angular-cli?

I know it's kind of hacky, but for our projects we've created a moment-angular-cli-patch.js file with the following content:

'use strict';

const fs = require( 'fs' );

console.log( 'Patchin internal Angular CLI configuration ...' );
const webpackProductionConfigPath = './node_modules/@angular/cli/models/webpack-configs/production.js';
fs.readfile( webpackProductionConfigPath, 'utf-8', ( error, fileContent ) => {
  const momentFix = 'extraPlugins.push( new webpack.ContextReplacementPlugin( /moment[\\/\\\\]locale$/, /de.js/ ) );';
  if ( fileContent.indexOf( momentFix ) === -1 ) {
    const uniqueContent = 'return {'; // Line 112
    const modifiedFileContent = fileContent.replace( uniqueContent, `${ momentFix }\n    ${ uniqueContent }` );
    fs.writeFile( webpackProductionConfigPath, modifiedFileContent, 'utf-8', ( error ) => {
      console.log( 'Done.' );
    } );
  } else {
    console.log( 'Nothing to do.' );
  }
} );

The script above ignores all locales except german, and it's written specifically for @angular/cli 1.5.0 (other versions might need to be handled differently). Within our package.json files, we've added it to the scripts:

"scripts": {
  "postinstall": "node ./moment-angular-cli-patch.js"
}

Not a great solution but a solution that works ...

@dominique-mueller that is interesting idea, thanks for sharing

@dominique-mueller For now is interesting idea, thanks

@dominique-mueller thanks for the idea! I've ended up patching moment instead of angular cli though.

const fs = require('fs');
const filePath = './node_modules/moment/moment.js';
const patch = {
    find: 'var aliasedRequire = require;',
    replace: 'var aliasedRequire = function(){};'
};

console.log('Patching moment');
let source = fs.readFileSync(filePath);
const index = source.indexOf(patch.find);
if (index === -1) {
    console.log('Nothing to do.');
} else {
    source = source.toString().replace(patch.find, patch.replace);
    fs.writeFileSync(filePath, source, 'utf-8');
    console.log('done');
}

@dominique-mueller interesting idea but I don't think patching the internal webpack configuration of the angular-cli is a good idea in the long run, given that the patch'd be really dependent on the angular-cli versions and you wouldn't be able to update really easily. The same goes for the patch in the moment config.
The ideal solution'd be for angular to open their webpack config so we can add plugins or moment to give us an option for not having so many unused stuff in our bundle

In addition to @fergardi 's comment, slightly changing the regex avoids including some more undesired locales.

plugins: [
  new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /(en|es|fr)$/),
]

This way you don't get all the es-* locales like es-do, es-usand so on.
Actually, without this change you end up with 13 locales instead of 3 because of all the regional variations.

With ngx-build-plus you should be able to adjust the Webpack config in Angular CLI without ejecting.

@SamVerschueren THIS IS AMAZING 😸

How can I ignore few directory from my modules? As my project is huge and it is giving while prod build so I thinking to build chunks by chunks so will need to Ignore/exclude few directory ? Please help its bit urgent. Thanks in advance.

is there an update to this that uses best practice? I see that a recent issue referenced this fix again https://github.com/urish/ngx-moment/issues/212

Was this page helpful?
0 / 5 - 0 ratings