Reputation: 551
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 ?
Upvotes: 17
Views: 10735
Reputation: 1075
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:
ng add ngx-build-plus
Add a file webpack.extra.js in the root of your project:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
]
}
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)
Upvotes: 13
Reputation: 61
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
Upvotes: 0
Reputation: 614
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.
Do all of the configurations mentioned in this answer: https://stackoverflow.com/a/72423671/6666348
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.
Upvotes: 0
Reputation: 31
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
Upvotes: 0
Reputation: 3181
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.
Upvotes: 0
Reputation: 459
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$/
})
]
};
Upvotes: 5
Reputation: 23065
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"
]
}
}
Upvotes: 2
Reputation: 829
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"
]
}
Upvotes: 5