使用 Uglify 的 keep_fnames 在生产模式下使用 Webpack 后重复 class 名称
Duplicate class names after using Webpack in production mode with Uglify's keep_fnames
我正在开发一个非常依赖 Function.prototype.name
的库(在父实例上设置快捷方式)。
class FooSection {}
class BarSection {}
class Page {
constructor(sections) {
for (let SectionClass of sections) {
this[SectionClass.name] = new SectionClass(this);
}
}
}
let page = new Page([
FooSection,
BarSection
]);
这一切都很好,花花公子,直到从 Webpack 的优化开始。默认情况下会破坏函数名称,导致 类 和它们的 name
属性 被缩短。通常有用,不在这里。所以我去将适当的配置传递给 Webpack:
// ...
optimization: {
minimizer: [
new UglifyJsPlugin( {
uglifyOptions: {
keep_fnames: true
}
} )
]
}
根据文档,这应该保留我的函数名称。令人惊讶的是,名字是 重复的 ,所以 Page
突然变成了 Page_Page
(注意:这个代码块是我写的,但这大致就是输出的样子):
class FooSection_FooSection{}
class BarSection_BarSection{}
class Page_Page{
constructor(t) {
for(let s of t){this[s.name]=new s(this)}
}
}
let p=new Page_Page([FooSection_FooSection,BarSection_BarSection])
这不能单独使用 UglifyJS 重现,所以它必须在工具链的某个地方(webpack -> uglifyjs-webpack-plugin -> uglifyjs),但我不知道在哪里。有人经历过吗?
版本如下:
- 网络包:4.6.0
- uglifyjs-webpack-插件:1.2.5
- uglifyjs: 3.3.9
更新:
根据评论,使用 TerserPlugin uglifier 似乎会出现同样的问题。
这是一个很老的话题,但我只是把它放在这里作为参考,因为我偶然发现了同样的问题,终于找到了原因。
此行为是由于 webpack ModuleConcatenationPlugin 出于性能原因将所有模块移至全局范围引起的。这可能会导致名称冲突,因此,webpack 重命名 类 并在它们前面加上它们的 file/module 名称。
您可以通过在您的 webpack 配置中将 concatenateModules
设置为 false
来禁用此行为。
module.exports = {
//...
optimization: {
concatenateModules: false
}
};
由于这不是错误并且您正在编写一个库,因此依赖此行为可能不是一个好主意。
我正在开发一个非常依赖 Function.prototype.name
的库(在父实例上设置快捷方式)。
class FooSection {}
class BarSection {}
class Page {
constructor(sections) {
for (let SectionClass of sections) {
this[SectionClass.name] = new SectionClass(this);
}
}
}
let page = new Page([
FooSection,
BarSection
]);
这一切都很好,花花公子,直到从 Webpack 的优化开始。默认情况下会破坏函数名称,导致 类 和它们的 name
属性 被缩短。通常有用,不在这里。所以我去将适当的配置传递给 Webpack:
// ...
optimization: {
minimizer: [
new UglifyJsPlugin( {
uglifyOptions: {
keep_fnames: true
}
} )
]
}
根据文档,这应该保留我的函数名称。令人惊讶的是,名字是 重复的 ,所以 Page
突然变成了 Page_Page
(注意:这个代码块是我写的,但这大致就是输出的样子):
class FooSection_FooSection{}
class BarSection_BarSection{}
class Page_Page{
constructor(t) {
for(let s of t){this[s.name]=new s(this)}
}
}
let p=new Page_Page([FooSection_FooSection,BarSection_BarSection])
这不能单独使用 UglifyJS 重现,所以它必须在工具链的某个地方(webpack -> uglifyjs-webpack-plugin -> uglifyjs),但我不知道在哪里。有人经历过吗?
版本如下:
- 网络包:4.6.0
- uglifyjs-webpack-插件:1.2.5
- uglifyjs: 3.3.9
更新:
根据评论,使用 TerserPlugin uglifier 似乎会出现同样的问题。
这是一个很老的话题,但我只是把它放在这里作为参考,因为我偶然发现了同样的问题,终于找到了原因。
此行为是由于 webpack ModuleConcatenationPlugin 出于性能原因将所有模块移至全局范围引起的。这可能会导致名称冲突,因此,webpack 重命名 类 并在它们前面加上它们的 file/module 名称。
您可以通过在您的 webpack 配置中将 concatenateModules
设置为 false
来禁用此行为。
module.exports = {
//...
optimization: {
concatenateModules: false
}
};
由于这不是错误并且您正在编写一个库,因此依赖此行为可能不是一个好主意。