如何防止 moment.js 使用 webpack 加载语言环境?

IT技术 javascript gulp momentjs webpack
2021-01-20 11:08:53

moment.js当您使用 webpack 时,有什么方法可以阻止加载所有语言环境(我只需要英语)?我正在查看源代码,似乎如果hasModule定义了,它是针对 webpack 的,那么它总是尝试require()每个语言环境。我很确定这需要一个拉取请求来修复。但是有什么办法可以用 webpack 配置来解决这个问题吗?

这是我用于加载 momentjs 的 webpack 配置:

resolve: {
            alias: {
                moment: path.join(__dirname, "src/lib/bower/moment/moment.js")
            },
        },

然后在任何我需要它的地方,我就做require('moment')这有效,但它向我的包中添加了大约 250 kB 不需要的语言文件。另外我使用的是 bower 版本的 momentjs 和 gulp。

此外,如果 webpack 配置无法解决此问题,这里有一个链接,指向加载 locales 的函数我尝试添加&& module.exports.loadLocalesif声明中,但我猜 webpack 实际上并没有以一种可行的方式工作。它只是require没什么不管是什么。我认为它现在使用正则表达式,所以我真的不知道你会如何修复它。

6个回答

代码require('./locale/' + name)可以使用目录中的每个文件locale所以 webpack 将每个文件都作为module包含在你的包中。它无法知道您使用的是哪种语言。

两个插件可用于为 webpack 提供有关应包含在包中的module的更多信息:ContextReplacementPluginIgnorePlugin.

require('./locale/' + name)称为上下文(包含表达式的要求)。webpack 从这个代码片段推断出一些信息:一个目录和一个正则表达式。这里:directory = ".../moment/locale" regular expression = /^.*$/所以默认情况下,locale目录中的每个文件都包含在内。

ContextReplacementPlugin允许覆盖推断的信息,即提供了一个新的正则表达式(选择要包括语言)。

另一种方法是使用IgnorePlugin.

下面是一个例子:

var webpack = require("webpack");
module.exports = {
  // ...
  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|fr|hu/)
    // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
};
你能解释一下如何使用忽略加载器吗?我试过 ` new webpackreg.IgnorePlugin(/\.\/locale\/.+.js$/, [])` 但这没有用。此外,contextReplacementPlugin 仍然包含在我的包中的文件,我只是认为它没有使用它们。
2021-04-04 11:08:53
你可以看一下这个 issue ( github.com/webpack/webpack/issues/198 ),里面有关于 moment+webpack 的详细讨论。
2021-04-05 11:08:53
谢谢,我认为new webpack.IgnorePlugin(/^\.\/lang$/, /moment$/)您对 github 的评论会起作用。
2021-04-05 11:08:53
@AlexKinnee文档中的括号表示法意味着它是一个可选参数,而不是数组。
2021-04-06 11:08:53
在 webpack 文档中,第二个参数是一个正则表达式数组。我试过 plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]) ],哪个工作得很好。
2021-04-13 11:08:53

在我们的项目中,我包括这样的时刻:import moment from 'moment/src/moment';这似乎可以解决问题。不过我们对 moment 的使用非常简单,所以我不确定是否会与 SDK 有任何不一致之处。我认为这是有效的,因为 WebPack 不知道如何静态查找语言环境文件,因此您会收到警告(通过在 处添加一个空文件夹很容易隐藏moment/src/lib/locale/locale),但不包含语言环境。

不知道这个人是如何为你工作的......我只是试图与github.com/angular/angular-cli/issues/6137作斗争,然后最终使用了github.com/ksloan/moment-mini适当的module化moment库将在某个时候出现第 3 版github.com/moment/moment/milestone/15
2021-03-18 11:08:53

更新:2021 年
您可能还想查看许多其他库:

原始答案:
似乎永远不会出现合适的module化moment但是,我最终使用了https://github.com/ksloan/moment-mini 之类的import * as moment from 'moment-mini';

根据 Adam McCrmick 的回答,您已经接近了,请将您的别名更改为:

resolve: {
    alias: {
        moment: 'moment/src/moment'
    },
},
只是一个警告,这将改变您包含的所有module的行为,并可能导致第三方库出现有趣的问题。虽然它应该可以正常工作
2021-03-17 11:08:53
当您设置解析别名时,它们适用于您系统中导入或要求的任何用法(包括您依赖的库)。因此,如果您依赖于所需时刻的module,那么您也将更改该module的结果。如果您碰巧设置了与依赖项树中的节点module冲突的别名(例如“事件”,如果您的依赖项使用该库),就会出现这种情况。在实践中,我只遇到了名称冲突的问题,而不是像这样的行为改进问题,但这是一种比更改一个导入语句更危险的方法。
2021-03-24 11:08:53
你能详细说明一下吗?我对所有别名用例都没有经验。在我的理解中,只有你触摸那个module才重要,在这种情况下是“时刻”
2021-04-13 11:08:53

使用webpack2最新版本的 moment 您可以执行以下操作:

import {fn as moment} from 'moment'

然后在webpack.config.js你做:

resolve: {
    packageMains: ['jsnext:main', 'main']
}
看看 webpack2,很确定字段名改变了。
2021-03-18 11:08:53
我猜你的意思是 mainFields: ...
2021-04-03 11:08:53