如何防止moment.js用webpack加载locale
How to prevent moment.js from loading locales with webpack?
当您使用webpack时,是否有任何方法可以阻止moment.js
加载所有区域设置(我只需要英语)?我正在查看源代码,似乎如果定义了hasModule
,这是针对webpack的,那么它总是尝试require()
每个locale。我很确定这需要一个拉请求来修复。但是我们有什么办法可以用webpack配置来解决这个问题吗?
这是我加载momentjs的webpack配置:
resolve: {
alias: {
moment: path.join(__dirname, "src/lib/bower/moment/moment.js")
},
},
然后在任何我需要它的地方,我只要做require('moment')
。这是可行的,但它会在我的包中添加大约250 kB的不需要的语言文件。我还使用了较低版本的momentjs和gulp。
如果这不能通过webpack配置来修复,这里有一个链接到加载区域设置的函数。我尝试将&& module.exports.loadLocales
添加到if
语句,但我猜webpack实际上并没有以这种方式工作。不管怎样,它都是 require
s。我认为它现在使用正则表达式,所以我真的不知道你会怎么去修复它。
代码require('./locale/' + name)
可以使用locale
目录中的每个文件。所以webpack将每个文件作为模块包含在bundle中。它无法知道您使用的是哪种语言。
ContextReplacementPlugin
和IgnorePlugin
这两个插件可以帮助webpack了解哪些模块应该包含在你的包中。
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$/)
]
};
在我们的项目中,我包括这样的时刻:import moment from 'moment/src/moment';
,这似乎做的技巧。我们对moment的使用非常简单,所以我不确定是否会有与SDK不一致的地方。我认为这是有效的,因为WebPack不知道如何静态地找到区域设置文件,所以你会得到一个警告(这很容易通过在moment/src/lib/locale/locale
添加一个空文件夹来隐藏),但没有包含区域设置。
UPDATE: 2021
您可能还需要检出许多其他库:
- https://date-fns.org
- https://github.com/iamkun/dayjs
原答案:
似乎适当的模块化moment
库将永远不会出现,然而,我只是结束了使用https://github.com/ksloan/moment-mini像import * as moment from 'moment-mini';
作为时刻2.18,所有的区域都与核心库捆绑在一起(见这个GitHub问题)。
传递给IgnorePlugin的resourceRegExp参数不是针对已解析的文件名或导入或需要的绝对模块名进行测试,而是针对传递给需要或导入的源代码中的字符串进行测试。例如,如果你试图排除node_modules/moment/locale/*.js,这将不起作用:
new webpack.IgnorePlugin({ resourceRegExp: /moment'/locale'// });
更确切地说,因为moment导入使用以下代码:
require('./locale/' + name);
你的第一个regexp必须匹配那个'。/地区/字符串。然后使用第二个contextRegExp参数选择发生导入的特定目录。以下命令将导致忽略这些区域设置文件:
plugins:[
new webpack.IgnorePlugin({
resourceRegExp: /^'.'/locale$/,
contextRegExp: /moment$/,
}),
]
表示"任何要求语句匹配"。/locale'从任何以'moment'结尾的目录将被忽略。
根据Adam McCrmick的回答,你很接近了,把你的别名改成:
resolve: {
alias: {
moment: 'moment/src/moment'
},
},
使用webpack2
和最新版本的moment,您可以:
import {fn as moment} from 'moment'
然后在webpack.config.js
你做:
resolve: {
packageMains: ['jsnext:main', 'main']
}
在NPM安装程序中使用postinstall脚本是另一个解决方案。
您可以在包中添加一行。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-gb
和pl
区域将保留在bundle中。
如果您已经有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"
...
}
}
对于web,如果您打算使用很少的moment
区域,您可以选择此解决方案。使用externals
配置。此外,我们还需要将moment
库和特定的locale脚本添加到HTML模板中。
优点:
- 增加webpack的编译速度。
- 减少包的大小
- 不需要
require('moment/locale/zh-tw')
语句(V.S.webpack.IgnorePlugin
溶液)
缺点:
- 每个语言环境脚本必须手动添加。
- 区域设置脚本总是从CDN下载,即使你不在你的代码中使用它们。这意味着有更多的HTTP请求。
下面的示例只使用moment
的zh-tw
区域设置。
webpack.config.js
:
const HTMLWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: 'production',
entry: './src/index.js',
externals: {
moment: 'moment'
},
plugins: [
new HTMLWebpackPlugin({
template: './src/index.html'
}),
]
};
src/index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/locale/zh-tw.min.js"></script>
</body>
</html>
src/index.js
:
import moment from 'moment';
moment.locale('zh-tw');
console.log(moment().fromNow())
- 如何使用url加载程序在webpack中导入多个图像
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 如何在不使用require语句的情况下使用webpack加载目录中的所有文件
- 无法使用Webpack加载ES6模块
- 具有动态查询的Webpack加载器
- 使用Webpack加载Mustache模板
- webpack加载程序和include
- 如何使用webpack加载.swf文件
- 如何防止moment.js用webpack加载locale
- Webpack加载整个库(Kendo UI)而不是单个组件
- 如何将查询添加到具有多个加载器的webpack加载器中
- 如何使用webpack加载库源映射
- 如何用webpack加载供应商文件
- 如何解析自定义webpack加载器中的require字符串
- 查询参数在webpack加载器中的用途是什么?
- 一个非常简单的查询-用webpack加载普通的旧javascript文件
- 本地主机节点服务器不能从webpack加载bundle.js
- 使用 webpack 加载 .jsx 文件
- 是否可以用webpack加载twilio.js库?
- Webpack加载代码会动态拆分包