Polymer 3.0.5 - DOMException: не удалось выполнить 'define' в 'CustomElementRegistry'

Я не думаю, что это повторяющаяся проблема. У меня установлен только @ полимер / полимер в качестве зависимости и импортирован в мой комплект поставщика (без @ polymer / paper-input). Я использую v3.0.5, и я даже не вижу iron-meta в дереве зависимостей (через список npm), и моя трассировка стека выглядит иначе - она ​​указывает на полимер / lib / elements / dom-module.js


dom-module.js: 178 Uncaught DOMException: не удалось выполнить 'define' в 'CustomElementRegistry': это имя уже использовалось с этим реестром

След указывает на эту линию customElements.define('dom-module', DomModule);

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

Я пытаюсь настроить базовый проект Polymer 3. Я использую Webpack с babel-loader для компиляции в es5. Поскольку я компилирую в es5, я включаю custom-elements-es5-adapter.js вместе с webcomponents-bundle.js в соответствии с инструкциями в репозитории webcomponentsjs. Эти сценарии просто копируются из node_modules в выходной каталог, а теги сценария включаются в заголовок html.

Что касается кода моего компонента, я создаю отдельные фрагменты js для каждого полимерного компонента, а также отдельный фрагмент для общего импорта, который в настоящее время включает только Polymer. Компиляция и разделение кода работают без ошибок, и полученные фрагменты добавляются в 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'
  }
};

А вот HTML:

<!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>

person Jbird    schedule 02.08.2018    source источник
comment
Возможный дубликат исключения Polymer 3.0 Uncaught DOM при использовании Paper- Ввод   -  person tony19    schedule 10.08.2018
comment
Спасибо @ tony19. Разве это не похоже на другую проблему? У меня установлен только @ полимер / полимер в качестве зависимости и импортирован в мой комплект поставщика (без @ polymer / paper-input). Я использую v3.0.5, и я даже не вижу iron-meta в дереве зависимостей (через список npm), и моя трассировка стека выглядит иначе - она ​​указывает на polymer/lib/elements/dom-module.js. Тем не менее, вам предлагается использовать прокладку, как и ожидалось. В идеале эту проблему можно было бы решить и без нее, поэтому я продолжу заниматься ею в эти выходные.   -  person Jbird    schedule 11.08.2018
comment
@Jbird вы в конце концов нашли решение? У меня сейчас такая же проблема.   -  person Andre    schedule 17.10.2018
comment
@Andre Да, если вы добавите следующее в скрипт перед кодом вашего полимерного приложения, это гарантирует, что пользовательские элементы будут объявлены только один раз. const _customElementsDefine = window.customElements.define; window.customElements.define = (имя, cl, conf) = ›{if (! customElements.get (имя)) {_customElementsDefine.call (window.customElements, name, cl, conf); }};   -  person Jbird    schedule 17.10.2018
comment
ty, я обнаружил это также в другом сообщении о переполнении стека, и это действительно решило проблему. Немного раздражает, потому что мой базовый шаблон html теперь представляет собой беспорядок из патчей, полифиллов и различных помощников babel .... радость современной веб-разработки   -  person Andre    schedule 17.10.2018


Ответы (1)


Мы решили эту проблему с помощью вложенного скрипта удаления полимера, проверьте исходную проблему github здесь .

Хитрость заключается в том, чтобы заставить npm запускать сценарий preinstall.sh, добавив в файл package.json следующее:

  "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
person Matt    schedule 18.10.2018
comment
Решение, упомянутое в комментарии выше, является гораздо более простым решением (~ 4 строки) для устранения этой конкретной ошибки, и оно безвредно для остальной части вашего проекта. Вам следует подумать об использовании его вместо этого. Кроме того, мне непонятно, что вы имеете в виду под «... полимерными модулями, которые вложены в node_modules внутри node_modules верхнего уровня ...». Этот комментарий сбивает с толку и заставляет меня думать, что вы имеете дело с другой проблемой, чем та, которая была изначально размещена здесь. Ошибка «не могу определить» может возникать по ряду причин. Попробуйте еще раз вернуться к своему ответу, чтобы уточнить, как он на самом деле решает конкретный сценарий. - person Jbird; 18.10.2018
comment
Это решение требует изменения кода приложения, чтобы исправить эту ошибку. Вероятно, что проблема вложенности в какой-то момент будет исправлена ​​в апстриме, что сделало бы внутреннее решение избыточным - как Анраэ упоминает выше, мой базовый html-шаблон теперь представляет собой беспорядок патчей .... На мой взгляд, важно, чтобы Избегайте этого. - person Matt; 19.10.2018
comment
Это не так. Это не требует никаких изменений в коде вашего приложения. Это изолированная голень. Это только в шаблоне html, если вы поместите его туда. Когда он зафиксирован «вверх по потоку», вы просто снимаете прокладку. - person Jbird; 19.10.2018