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

require moment without locales #2416

Closed
naartjie opened this issue Jun 12, 2015 · 24 comments
Closed

require moment without locales #2416

naartjie opened this issue Jun 12, 2015 · 24 comments

Comments

@naartjie
Copy link

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

@naartjie naartjie changed the title require moment without locale require moment without locales Jun 12, 2015
@balexand
Copy link

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$/)
]

@naartjie
Copy link
Author

Very cool, thanks @balexand

@naartjie
Copy link
Author

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

@naartjie
Copy link
Author

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

@ksloan
Copy link

ksloan commented Feb 24, 2017

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

@kuncevic
Copy link

kuncevic commented May 1, 2017

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 #2416 (comment) in not working for me. Is there any solution with angular-cli to exclude the locale?

ajhyndman added a commit to L4GG/timeline that referenced this issue Sep 8, 2017
By default, the node bundle for moment includes internationalization data and functionality for ~100 locales.  We aren't using those, so strip them from the webpack output.

See: moment/moment#2416
@WangYang-Rex
Copy link

@balexand Thanks, it works for me

@kirillgroshkov
Copy link

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'

@fergardi
Copy link

fergardi commented Nov 16, 2017

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$/)
]

@lvidal1
Copy link

lvidal1 commented Nov 20, 2017

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

@dominique-mueller
Copy link

dominique-mueller commented Nov 20, 2017

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 ...

@kuncevic
Copy link

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

@felipefialho
Copy link

@dominique-mueller For now is interesting idea, thanks

@FDIM
Copy link

FDIM commented Feb 5, 2018

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

@rodrijuarez
Copy link

@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

@cdaguerre
Copy link

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.

@SamVerschueren
Copy link

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

@felipefialho
Copy link

@SamVerschueren THIS IS AMAZING 😸

@mistrykaran91
Copy link

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.

@JackHowa
Copy link

JackHowa commented Jun 3, 2019

is there an update to this that uses best practice? I see that a recent issue referenced this fix again urish/ngx-moment#212

@zander-indo-bose
Copy link

For anyone else looking for a more up to date solution this is from webpacks site:

new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, });

See:

Example of Ignoring Moment Locales

https://webpack.js.org/plugins/ignore-plugin/

@lucassimines
Copy link

For anyone else looking for a more up to date solution this is from webpacks site:

new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, });

See:

Example of Ignoring Moment Locales

https://webpack.js.org/plugins/ignore-plugin/

✅ It works with the new Laravel Mix 6.*

@esaesa
Copy link

esaesa commented Apr 24, 2021

in tsconfig.app.ts compilerOptions use

"paths": { "moment": [ "./node_modules/moment/min/moment.min.js" ] },
My configuration is

"compilerOptions": {
"paths": {
  "moment": [
    "./node_modules/moment/min/moment.min.js"
  ]
},
"outDir": "./out-tsc/app",
"types": ["node"],
},

It will use only moment without any locals. No need no use extra webpack plugins

@fregante
Copy link

@esaesa perfect! Here's the same configuration for webpack:

module.exports = {
  resolve: {
    alias: {
      // Ignore all locale files of moment.js
      moment: "moment/min/moment.min.js"
    }
  }
}

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

No branches or pull requests