Solvedangular cli How would you exclude moment.js locale in a proper way?

Bug Report or Feature Request

  • [x ] question

Versions.

@angular/cli: 1.0.1
node: 7.8.0
os: win32 x64

Details

I've got the whole locale ended up in my bundle:

image

As I am not using --eject flag this solution moment/moment#2416 (comment) in not working for me.

I discovered this SO answer which is kind of not really works for me, getting like Error: Can't resolve './locale' in runtime.

Is there any proper solution with angular-cli to exclude the moment locale without --eject?

39 Answers

✔️Accepted Answer

There is a simplier solution if you want to exlude all locales, in src/tsconfig.app.json add this :

"compilerOptions": {
    "paths": {
      "moment": [
        "../node_modules/moment/min/moment.min.js"
      ]
    }
}

It will instruct the compiler to use the minified-without-locale bundle instead of building from the sources.

Why use this instead of moment-mini ?

  1. Well the moment-min repo is not always up to date with the official moment repo, therefore you can be stuck on an old version
  2. If you use other libraries that depend on moment (such as moment-timezone), by default it will bundle the full moment with locale into your app. The config above avoid this pitfall.

Other Answers:

I found a solution in momentjs issues, then I tried it with @angular-builders/custom-webpack.
This is my config:

./extra-webpack.config.js

'use strict';

const webpack = require('webpack');

// https://webpack.js.org/plugins/context-replacement-plugin/
module.exports = {
  plugins: [new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/)]
};

and angular.json

...
 "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./extra-webpack.config.js",
              "replaceDuplicatePlugins": true,
              "mergeStrategies": {
                "externals": "prepend"
              }
            },
...

It works fine. You can select whatever locale you want.

Hope this will help you.

@ciesielskico is your bundle looking good after all?

By importing through the "scripts": [] and then doing import * as moment from 'moment'; just got multiple moments in a bundles - one in the vendor bundle with all locales(same as I initially got), and another one in a scripts bundle.

P.S
Anyway it is sounds like there is too much hassle of using current moment until the proper modular version will be released https://github.com/moment/moment/milestone/15. So currently just ended up of using https://github.com/ksloan/moment-mini which is works fine for me:

import * as moment from 'moment-mini';

image

@petivagyok16
we are using a npm script after install, found somewhere ...

`
var globby = require('globby');
var rimraf = require('rimraf');

globby(['./node_modules/moment/locale/*', '!./node_modules/moment/locale/de.js', '!./node_modules/moment/locale/de-at.js', '!./node_modules/moment/locale/de-ch.js'])
.then(function then(paths) {
paths.map(function map(item) {
rimraf.sync(item);
});
});
`

Just include the .min.js version which does not include any locales, and then include the locale you need.
This is what I've got:

"scripts": [
    "../node_modules/moment/min/moment.min.js",
    "../node_modules/moment/locale/pl.js",
]

Edit: Found out that my solution does not work, and in fact also includes all locales

More Issues: