【问题标题】:How to prevent moment.js from loading locales with webpack?如何防止 moment.js 使用 webpack 加载语言环境?
【发布时间】:2014-10-12 14:37:24
【问题描述】:

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

这是我加载 momentjs 的 webpack 配置:

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

然后在任何我需要它的地方,我只需要require('moment')。这可行,但它在我的包中添加了大约 250 kB 的不需要的语言文件。另外我正在使用momentjs和gulp的凉亭版本。

另外,如果 webpack 配置无法解决这个问题,这里是 a link to the function where it loads the locales。我尝试将&& module.exports.loadLocales 添加到if 语句中,但我猜webpack 实际上并不能以这样的方式工作。无论如何,它只是requires。我认为它现在使用正则表达式,所以我真的不知道你会如何修复它。

【问题讨论】:

  • 您是否尝试过使用时刻通过nmp 而不是bower
  • 我的所有客户端库都使用 bower,所有构建工具都使用 npm。我想保持这种方式,因为我的项目是如何布局的。另外,如果您查看github.com/moment/moment/issues/1866 的最后回复,我解决了我自己的问题,但它需要对源代码进行少量编辑。我仍然不知道如何以正确的方式解决这个问题,因为我不知道如何区分 node 和 webpack。

标签: javascript gulp momentjs webpack


【解决方案1】:

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

two plugins 有助于为 webpack 提供有关应将哪个模块包含在您的包中的更多信息:ContextReplacementPluginIgnorePlugin

require('./locale/' + name) 称为context(包含表达式的要求)。 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 仍然包含我的包中的文件,我只是认为它没有使用它们。
  • 你可以看看这个 issue (github.com/webpack/webpack/issues/198),里面有关于 moment+webpack 的详细讨论。
  • 谢谢您,我认为您在 github 上的评论中的new webpack.IgnorePlugin(/^\.\/lang$/, /moment$/) 会起作用。
  • 在 webpack 文档中,第二个参数是一个正则表达式数组。我试过plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]) ],,效果很好。
  • @AlexKinnee 括号符号in the docs 表示它是可选参数,而不是数组。
【解决方案2】:

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

【讨论】:

【解决方案3】:

更新:2021 年
您可能还想签出许多其他库:

原始答案:
似乎是正确的模块化 momentwill never come up 但是,我刚刚结束了使用 https://github.com/ksloan/moment-mini 之类的 import * as moment from 'moment-mini';

【讨论】:

    【解决方案4】:

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

    resolve: {
        alias: {
            moment: 'moment/src/moment'
        },
    },
    

    【讨论】:

    • 请注意,这将改变您包含的所有模块的行为,并可能导致第三方库出现有趣的问题。它应该可以正常工作
    • 你能详细说明一下吗?我对所有别名用例都没有经验。据我了解,只有你触摸了那个模块才重要,在这种情况下是“时刻”
    • 当您设置解析别名时,它们适用于您系统中的任何 import 或 require 用法(包括您依赖的库)。因此,如果您依赖于所需时刻的模块,您也将更改该模块的结果。如果您碰巧设置了与依赖关系树中的节点模块冲突的别名(例如“事件”,例如,如果您的依赖关系使用该库),则会出现这种情况。在实践中,我只遇到过名称冲突问题,而不是像这样的行为改进问题,但这是一种比更改一个导入语句更危险的方法。
    【解决方案5】:

    使用 webpack2 和最新版本的 moment,您可以:

    import {fn as moment} from 'moment'
    

    然后在webpack.config.js 你这样做:

    resolve: {
        packageMains: ['jsnext:main', 'main']
    }
    

    【讨论】:

    • 我猜你的意思是mainFields: ...
    • 看看webpack2,很确定字段名变了。
    【解决方案6】:

    这是在 NPM 安装程序中使用 postinstall script 的另一个解决方案。

    您可以在 package.json 文件中添加一行:

    {
      "scripts": {
        ...
        "postinstall": "find node_modules/moment/locale -type f -not -name 'en-gb.js' -not -name 'pl.js' -printf '%p\\n' | xargs rm"
        ...
      }
    }
    

    npm install 完成安装包后,不需要的语言环境将立即被删除。

    在我的情况下,只有 en-gbpl 语言环境将保留在捆绑包中。

    如果您已经有postinstall 脚本,您可以将脚本添加到现有命令中:

    {
      "scripts": {
        ...
        "postinstall": "previous_command && find node_modules/moment/locale -type f -not -name 'en-gb.js' -not -name 'pl.js' -printf '%p\\n' | xargs rm"
        ...
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-09
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      相关资源
      最近更新 更多