Polymer 聚合物3.0.5-“;DOMEException:未能执行';定义';在';CustomElementRegistry'&引用;

Polymer 聚合物3.0.5-“;DOMEException:未能执行';定义';在';CustomElementRegistry'&引用;,polymer,webpack-4,polymer-3.x,Polymer,Webpack 4,Polymer 3.x,我不认为这是一个重复的问题。我只有@polymer/polymer作为依赖项安装,并导入到我的供应商包中(没有@polymer/paper输入)。我使用的是v3.0.5,在依赖关系树中甚至没有看到iron meta(通过npm列表),我的堆栈跟踪看起来也不一样——它指向polymer/lib/elements/dom-module.js dom module.js:178未捕获的DomeException:未能在上执行“定义” “CustomElementRegistry”:此名称已用于此 登

我不认为这是一个重复的问题。我只有@polymer/polymer作为依赖项安装,并导入到我的供应商包中(没有@polymer/paper输入)。我使用的是v3.0.5,在依赖关系树中甚至没有看到iron meta(通过npm列表),我的堆栈跟踪看起来也不一样——它指向polymer/lib/elements/dom-module.js


dom module.js:178未捕获的DomeException:未能在上执行“定义” “CustomElementRegistry”:此名称已用于此 登记处

跟踪指向此行
customElements.define('dom-module',dommule)

@polymer/polymer/lib/elements/dom module.js?:178:16

我正在尝试建立一个基本的聚合物3项目。我正在使用带有babel loader的Webpack编译到es5。因为我是编译到es5的,所以我按照上的说明包括
custom-elements-es5-adapter.js
以及
webcomponents bundle.js
。这些脚本只是从node_模块复制到输出目录,脚本标记包含在html头中

至于我的组件代码,我正在为每个polymer组件创建单独的js块,以及为共享导入创建单独的块,当前只包括polymer。编译和代码拆分工作正常,生成的块在结束body标记之前添加到html中

Webpack SplitChunks插件将
@polymer/polymer
导入到单独的块中,以便它们只包含一次

目标是将所有必需的供应商代码拉入一个公共脚本中,并将每个组件放在自己的一小块中,可以有选择地包含其中

  • my-common.js(共享/公共块)
  • my-button.js(组件块)
  • my-tabs.js(组件块)
  • …更多组件块
在我当前的设置中,块的创建似乎是正确的

理论上,根据我到目前为止读到的内容,这应该是可行的,但我完全被这个错误所困扰

如果我将组件文件捆绑在一起,一切正常。


下面是我的一个非常简单的组件文件示例:

import { html, PolymerElement } from '@polymer/polymer';

export default class MyButton extends PolymerElement {
  constructor() {
    super();
  }

  static get template() {
    return html`
      <slot></slot>
    `;
  }

  static get properties() {
    return { }
  }
}

customElements.define('my-button', MyButton);
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

const SRC_PATH = path.resolve(__dirname, './src');
const DIST_PATH = path.resolve(__dirname, './dist');

module.exports = {
  entry: {
    'my-button': `${SRC_PATH}/js/components/my-button.js`,
    'my-tabs': `${SRC_PATH}/js/components/my-tabs.js`
  },
  output: {
    filename: 'js/[name].js',
    path: DIST_PATH
  },
  resolve: {
    extensions: ['.js']
  },
  module: {
    rules: [{
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: [[
            'env',
            {
              targets: {
                browsers: [
                  'last 2 versions',
                  'ie > 10'
                ]
              },
              debug: true
            }
          ]]
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: `${SRC_PATH}/index.html`,
      filename: 'index.html',
      inject: 'head'
    }),
    new CopyWebpackPlugin([{
      from: './node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js',
      to: 'js/vendor',
      toType: 'dir'
    }, {
      from: './node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js',
      to: 'js/vendor',
      toType: 'dir'
    }, {
      from: './node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js',
      to: 'js/vendor',
      toType: 'dir'
    }]),
    new BundleAnalyzerPlugin()
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        default: false,
        commons: {
          name: 'my-common',
          chunks: 'all',
          minChunks: 2
        }
      }
    },
    minimizer: [
      new UglifyJSPlugin({
        uglifyOptions: {
          ie8: false,
          safari10: false,
          compress: {
            warnings: false,
            drop_console: true
          },
          output: {
            ascii_only: true,
            beautify: false
          }
        }
      })
    ]
  },
  devServer: {
    contentBase: DIST_PATH,
    compress: false,
    overlay: {
      errors: true
    },
    port: 8080,
    host: '127.0.0.1'
  }
};
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
  <title>polymer-3-sandbox</title>
  <meta name="description" content="A polymer 3 sandbox">
  <link rel="manifest" href="/manifest.json">
  <script src="/js/vendor/webcomponents-bundle.js"></script>
  <script src="/js/vendor/custom-elements-es5-adapter.js"></script>
  <script type="text/javascript" src="js/my-common.js"></script> 
  <script type="text/javascript" src="js/my-button.js"></script>
  <script type="text/javascript" src="js/my-tabs.js"></script>
</head>

<body>    
  <p>
    <my-button>Learn More</my-button>
  </p>
</body>

</html>
下面是html:

import { html, PolymerElement } from '@polymer/polymer';

export default class MyButton extends PolymerElement {
  constructor() {
    super();
  }

  static get template() {
    return html`
      <slot></slot>
    `;
  }

  static get properties() {
    return { }
  }
}

customElements.define('my-button', MyButton);
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

const SRC_PATH = path.resolve(__dirname, './src');
const DIST_PATH = path.resolve(__dirname, './dist');

module.exports = {
  entry: {
    'my-button': `${SRC_PATH}/js/components/my-button.js`,
    'my-tabs': `${SRC_PATH}/js/components/my-tabs.js`
  },
  output: {
    filename: 'js/[name].js',
    path: DIST_PATH
  },
  resolve: {
    extensions: ['.js']
  },
  module: {
    rules: [{
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: [[
            'env',
            {
              targets: {
                browsers: [
                  'last 2 versions',
                  'ie > 10'
                ]
              },
              debug: true
            }
          ]]
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: `${SRC_PATH}/index.html`,
      filename: 'index.html',
      inject: 'head'
    }),
    new CopyWebpackPlugin([{
      from: './node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js',
      to: 'js/vendor',
      toType: 'dir'
    }, {
      from: './node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js',
      to: 'js/vendor',
      toType: 'dir'
    }, {
      from: './node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js',
      to: 'js/vendor',
      toType: 'dir'
    }]),
    new BundleAnalyzerPlugin()
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        default: false,
        commons: {
          name: 'my-common',
          chunks: 'all',
          minChunks: 2
        }
      }
    },
    minimizer: [
      new UglifyJSPlugin({
        uglifyOptions: {
          ie8: false,
          safari10: false,
          compress: {
            warnings: false,
            drop_console: true
          },
          output: {
            ascii_only: true,
            beautify: false
          }
        }
      })
    ]
  },
  devServer: {
    contentBase: DIST_PATH,
    compress: false,
    overlay: {
      errors: true
    },
    port: 8080,
    host: '127.0.0.1'
  }
};
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
  <title>polymer-3-sandbox</title>
  <meta name="description" content="A polymer 3 sandbox">
  <link rel="manifest" href="/manifest.json">
  <script src="/js/vendor/webcomponents-bundle.js"></script>
  <script src="/js/vendor/custom-elements-es5-adapter.js"></script>
  <script type="text/javascript" src="js/my-common.js"></script> 
  <script type="text/javascript" src="js/my-button.js"></script>
  <script type="text/javascript" src="js/my-tabs.js"></script>
</head>

<body>    
  <p>
    <my-button>Learn More</my-button>
  </p>
</body>

</html>

聚合物-3-沙箱

了解更多


我们已使用嵌套聚合物去除脚本解决了此问题,请检查

诀窍是通过将以下内容添加到package.json文件中,让npm运行preinstall.sh脚本:

  "scripts": {
    "preinstall": "../preinstall.sh"
  }
然后运行以下脚本,无脚本安装npm两次,以避免安装错误:

#!/bin/bash
# Author: Flatmax developers
# Date : 2018 10 17
# License : free

npm i --ignore-scripts || true
if [ `ls node_modules/ | wc -l` -eq "0" ]; then
  zenity --error --text="ERROR : cb() never called\nrm node_modules and pacakge-lock.json and try again"
fi
npm i --ignore-scripts || true
if [ `ls node_modules/ | wc -l` -eq "0" ]; then
  zenity --error --text="ERROR : cb() never called\nrm node_modules and pacakge-lock.json and try again"
fi
. ../fixNestings.sh
最后,实际的嵌套删除脚本如下所示:

#!/bin/bash
# Author: Flatmax developers
# Date : 2018 10 17
# License : free

# The following function will remove nested directories, where $1 exists like so
# node_modules/.*/node_modules/$1
# @param $1 the module name to remove nestings of
function rmNestedMod(){
  name=$1
  paths=`find -L node_modules -name $1 | sed "s|^node_modules/||;s|/\$name$||" | grep node_modules`
  for p in $paths; do
    echo rm -rf node_modules/$p/$name
    rm -rf node_modules/$p/$name
  done
}

# remove all nested polymer namespaces
namespaces=`ls node_modules/@polymer/`
for n in $namespaces; do
  rmNestedMod "$n"
done

可能重复的感谢@tony19。这看起来不是一个不同的问题吗?我只有@polymer/polymer作为依赖项安装,并导入到我的供应商包中(没有@polymer/paper输入)。我使用的是v3.0.5,在依赖关系树中甚至没有看到iron meta(通过npm列表),我的堆栈跟踪看起来也不一样——它指向
polymer/lib/elements/dom module.js
。尽管如此,我们还是建议您按预期工作。理想情况下,这个问题可以在没有它的情况下解决,所以我将在本周末继续调查。@Jbird您最终找到解决方案了吗?我现在也遇到了同样的问题。@Andre是的,如果在polymer应用程序代码之前向脚本添加以下内容,它将确保自定义元素只声明一次。const_customElementsDefine=window.customElements.define;window.customElements.define=(name,cl,conf)=>{if(!customElements.get(name)){{u customElementsDefine.call(window.customElements,name,cl,conf);};泰,我在另一篇堆栈溢出文章中也发现了这一点,它确实解决了这个问题。有点烦人,因为我的基本html模板现在是一堆补丁,多边形填充和各种巴贝尔助手。。。。现代web开发的乐趣我在上面的评论中提到的解决方案是一个更简单的解决方案(~4行),可以解决这个特定错误,并且对项目的其余部分无害。你应该考虑使用它。另外,我不清楚你所说的“…聚合物模块嵌套在顶层节点模块内的节点模块中…”是什么意思。这条评论让人困惑,让我觉得你处理的问题与最初发布在这里的问题不同。出现“无法定义”错误的原因有很多。考虑重新考虑你的答案来澄清它是如何解决特定场景的。这个解决方案需要改变应用程序代码来修复这个bug。嵌套问题很可能会在某个时候被修复,这会使应用内解决方案变得多余,正如Anrae在上面提到的“我的基本html模板现在是一堆补丁…”。在我看来,避免这种情况很重要,这是不对的。它要求对应用程序代码进行零更改。这是一个孤立的胫骨。只有将html模板放在那里,它才是int。当它固定在“上游”位置时,只需拆下垫片即可。