How to exclude moment locales from angular build?
Asked Answered
L

8

17

In my angular 5 application, when I create build using

ng build --prod --sm

and open source map explorer, moment takes lot of space in the main.js file. I have found all the locales gets loaded when I use

import * as moment from 'moment';

I have used material-moment-adapter to some functionality in the application that requires the moment package also.

I have created the application using angular-cli. I have found many links that excludes locales using settings in webpack.config.js Is there any way to exclude locales using angular-cli ?

Lox answered 16/4, 2018 at 7:0 Comment(4)
You can either use lazy loading or switch to the native module for material. I would recommend the second option.Fattal
github.com/urish/ngx-momentBaese
can you please provide some example for material native module?Lox
I have used moment-mini . It workedLox
S
13

This article describe good solution: https://medium.jonasbandi.net/angular-cli-and-moment-js-a-recipe-for-disaster-and-how-to-fix-it-163a79180173

Briefly:

  1. ng add ngx-build-plus

  2. Add a file webpack.extra.js in the root of your project:

    const webpack = require('webpack');
    module.exports = {
        plugins: [
            new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
        ]
    }
    
  3. Run:

    npm run build --prod --extra-webpack-config webpack.extra.js
    

Warning moment.js has been deprecated officially https://momentjs.com/docs/#/-project-status/ (try use day.js or luxon)

Sydel answered 28/2, 2019 at 12:20 Comment(5)
when i use this answer the compiler gives this error An unhandled exception occurred: Project 'webpack.extra.js' does not exist.Fordham
and when I change npm run build with ng build the compiler gives this error: An unhandled exception occurred: Cannot find module '/Users/test/Desktop/projects/shb2c/webpack.extra.js' Require stack:Fordham
Check step 2: ADD/CREATE webpack.extra.js in the root of your projectSydel
moment.js deprecated ?Deficient
giving me an error: ``` Unknown option: '--extra-webpack-config' Unknown option: 'webpack.extra.js' ```Gorrian
L
5

If you don't want to use any third party libraries the simplest way to do this is to add the following in compilerOptions of your tsconfig.json file

"paths": {
  "moment": [
    "../node_modules/moment/min/moment.min.js"
  ]
}
Leyte answered 13/3, 2019 at 5:19 Comment(3)
I was not able to make it work with this solution if moment-timezone is used.Intrigante
this doesnt provide moment directiveQuest
Thanks for the hint. However I'm getting Could not find a declaration file for module 'moment'. error with this way. Do you have any idea how to fix it?Malpractice
I
5

For anyone on angular 12 or latest

This does not work for me

const webpack = require('webpack');

module.exports = {
    plugins: [
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    ]
}

However this does

const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,
      contextRegExp: /moment$/
    })
  ]
};
Irish answered 1/10, 2021 at 10:21 Comment(0)
V
2

There is another solution in this Angular Issue: https://github.com/angular/angular-cli/issues/6137#issuecomment-387708972

Add a custom path with the name "moment" so it is by default resolved to the JS file you want:

"compilerOptions": {
    "paths": {
      "moment": [
        "./node_modules/moment/min/moment.min.js"
      ]
    }
}
Vietnam answered 29/12, 2020 at 0:20 Comment(0)
S
0

In Angular 12, I did the following:

npm i --save-dev @angular-builders/custom-webpack

to allow using a custom webpack configuration.

npm i --save-dev moment-locales-webpack-plugin
npm i --save-dev moment-timezone-data-webpack-plugin

Then modify your angular.json as follows:

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

and in the extra-webpack.config.js file:

const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const MomentTimezoneDataPlugin = require('moment-timezone-data-webpack-plugin');

module.exports = {
    plugins: [
        new MomentLocalesPlugin({
            localesToKeep: ['en-ie']
        }),
        new MomentTimezoneDataPlugin({
            matchZones: /Europe\/(Belfast|London|Paris|Athens)/,
            startYear: 1950,
            endYear: 2050,
        }),
    ]
};

Modify the above options as needed, of course. This gives you far better control on which exact locales and timezones to include, as opposed to the regular expression that I see in some other answers.

Stamina answered 4/11, 2021 at 15:53 Comment(0)
I
0

the solutions above didn't work for me because they address the wrong path (don't use ../ ) in the tsconfig.app.json

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

Works for me in Angular 12.2.X. The changes must be done in the tsconfig.app.json, than also the type information of your IDE will work. enter image description here

enter image description here

Don't change it in the tsconfig.json or your IDE will lose type information. enter image description here

This fix the usage in the app as in the lib. I used source-map-explorer to verify it.

ng build --sourceMap=true --namedChunks=true --configuration production && source-map-explorer dist/**/*.js

enter image description here

Isham answered 8/4, 2022 at 8:8 Comment(0)
L
0

I had the same problem with momentjs library and solve it as below:

The main purpose of this answer is not to use IgnorePlugin for ignoring the library but I use ContextReplacementPlugin to tell the compiler which locale files I want to use in this project.

  1. Do all of the configurations mentioned in this answer: https://mcmap.net/q/744893/-how-to-see-webpack-config-from-angular-application

  2. Then in your webpack.config.js file write this:

    const webpack = require("webpack");
    
    module.exports = {
        plugins: [
            new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /(en|fr)$/)
        ]
    };
    

This configuration will add only en and fr locale in your application dist folder.

Lebeau answered 29/5, 2022 at 20:46 Comment(0)
A
0

You can try to use moment-mini-ts instead of moment

npm i moment-mini-ts

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

Don’t forget to uninstall moment

npm uninstall moment 

I’m using angular 9

Ailment answered 22/12, 2022 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.