如何从 angular 构建中排除 moment 语言环境?

How to exclude moment locales from angular build?

在我的 angular 5 应用程序中,当我使用

创建构建时
ng build --prod --sm

和开源地图资源管理器,main.js 文件中 space 的片刻。我发现当我使用

时所有语言环境都会被加载
import * as moment from 'moment';

我已经将 material-moment-adapter 用于应用程序中也需要 moment 包的某些功能。

我使用 angular-cli 创建了应用程序。我发现许多链接使用 webpack.config.js 中的设置排除语言环境 有什么方法可以使用 angular-cli 排除语言环境吗?

这篇文章描述了很好的解决方案: https://medium.jonasbandi.net/angular-cli-and-moment-js-a-recipe-for-disaster-and-how-to-fix-it-163a79180173

简要说明:

  1. ng add ngx-build-plus

  2. 在项目的根目录中添加一个文件webpack.extra.js:

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

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

    在此处输入代码

警告 moment.js 已正式弃用 https://momentjs.com/docs/#/-project-status/(尝试使用 day.js 或 luxon)

如果您不想使用任何第三方库,最简单的方法是在 [=17] 的 compilerOptions 中添加以下内容=] 文件

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

这个Angular问题还有另一个解决方案: https://github.com/angular/angular-cli/issues/6137#issuecomment-387708972

添加名为“moment”的自定义路径,以便默认解析为您想要的 JS 文件:

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

对于 angular 12 或最晚

的任何人

这对我不起作用

const webpack = require('webpack');

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

但是这样

const webpack = require('webpack');

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

在 Angular12 中,我做了以下操作:

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

允许使用自定义 webpack 配置。

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

然后修改你的angular.json如下:

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

并在 extra-webpack.config.js 文件中:

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

当然可以根据需要修改以上选项。这使您可以更好地控制要包含的确切语言环境和时区,而不是我在其他一些答案中看到的正则表达式。

上面的解决方案对我不起作用,因为它们在 tsconfig.app.json

中解决了错误的路径(不要使用 ../ )
{
...
   "compilerOptions": {
      "paths": {
        "moment": [
          "node_modules/moment/min/moment.min.js"
        ]
      }
   }
}

我在 Angular 12.2.X 工作。更改必须在 tsconfig.app.json 中完成,然后 IDE 的类型信息也将起作用。

不要在 tsconfig.json 中更改它,否则您的 IDE 将丢失类型信息。

这修复了应用程序中与库中一样的用法。我用source-map-explorer验证了一下

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

我和 momentjs 库有同样的问题,解决方法如下:

这个答案的主要目的不是使用 IgnorePlugin 来忽略库,而是我使用 ContextReplacementPlugin 来告诉编译器哪个语言环境我想在这个项目中使用的文件。

  1. 执行此答案中提到的所有配置:

  2. 然后在您的 webpack.config.js 文件中写入:

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

此配置只会在您的应用程序 dist 文件夹中添加 enfr 语言环境。