简体   繁体   中英

How to exclude moment locales from angular build?

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?

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

    enter code here

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

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"
  ]
}

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"
      ]
    }
}

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

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.

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. 在此处输入图像描述

在此处输入图像描述

Don't change it in the tsconfig.json or your IDE will lose type information. 在此处输入图像描述

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

在此处输入图像描述

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://stackoverflow.com/a/72423671/6666348

  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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM