Polymer 3 + Webpack报错:PolymerElement必须使用new调用
嘿,我之前在折腾Polymer 3.0预览版+Webpack转ES5的时候,也踩过这个一模一样的坑!这个错误本质是Babel的类转译逻辑和custom-elements-es5-adapter.js的适配机制没配合好,给你几个亲测有效的解决思路:
思路1:确保适配器在打包代码之前加载,且不被Webpack转译
custom-elements-es5-adapter.js的作用是让转译为ES5的自定义元素类能正确被浏览器识别,但它本身不能被Babel转译,而且必须在所有Polymer代码执行前加载。
- 从
@webcomponents/webcomponentsjs包里把custom-elements-es5-adapter.js复制到你的静态资源目录(比如public/) - 在演示页面的HTML里,先引入适配器,再引入Webpack打包后的bundle:
<script src="custom-elements-es5-adapter.js"></script> <script src="bundle.js"></script>
- 别把适配器加到Webpack的入口里,让它以原生脚本的形式加载。
思路2:调整Babel配置,排除Polymer核心模块的转译
Babel默认会把所有ES6代码转成ES5,但Polymer的核心模块(@polymer/polymer等)已经做了适配准备,被Babel过度转译后会破坏custom-elements-es5-adapter的工作。
在你的Babel配置文件(.babelrc或babel.config.js)里添加排除规则:
{ "presets": [ ["@babel/preset-env", { "targets": { "browsers": ["ie 11", "last 2 versions"] } }] ], "exclude": [/node_modules\/@polymer\//] }
这样Babel就不会转译@polymer下的模块,让适配器能正确处理这些类的构造逻辑。
思路3:检查Webpack的模块解析规则
如果你的Webpack配置里有对.js文件统一应用Babel loader的规则,要确保custom-elements-es5-adapter.js被排除在外:
module.exports = { // ...其他配置 module: { rules: [ { test: /\.js$/, exclude: [/node_modules/, /custom-elements-es5-adapter\.js$/], use: 'babel-loader' } ] } }
错误原因补充
当Babel把ES6的class PolymerElement转成ES5的构造函数后,浏览器的自定义元素API会尝试调用这个构造函数,但如果没有适配器的拦截,或者适配器加载时机不对,就会出现“不能不用new调用”的错误——因为转译后的ES5构造函数必须用new执行,而适配器的作用就是确保这一点能被正确处理,前提是它能在转译后的Polymer代码运行前生效。
内容的提问来源于stack exchange,提问作者Jan Rembold

