импортировать трафарет в Svelte

У меня есть Monorepo со стройным проектом и библиотекой компонентов Stencil. На веб-сайте Stencil очень четко описано, как интегрировать библиотеку, например, с Angular

import { defineCustomElements } from 'test-components/loader';
defineCustomElements(window);

Очень просто. Но теперь я бы тоже хотел использовать его в проекте Svelte ..... уже не так просто :(

Когда я пытаюсь сделать что-то подобное, как описано выше, я получаю серьезные ошибки

введите здесь описание изображения

fbp/dist - это файлы трафаретов.

Когда я сначала создаю свой проект Stencil и копирую свой dist в папку public и загружаю ./dist/fbp.js в заголовок index.html, все работает. Но было бы намного проще, если бы я мог включить его так же, как в Angular. Какие-либо предложения?

Обновление: добавлен emitCss, который дает

введите здесь описание изображения

Где-то в конце статистика: Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)

ОБНОВЛЕНИЕ: с исправлениями @Sambor Svelte теперь может загружать веб-компонент, который, к сожалению, не работает.

введите здесь описание изображения


person Jeanluca Scaljeri    schedule 23.01.2020    source источник
comment
какой бандлер вы используете? (веб-пакет, накопительный пакет)?   -  person V. Sambor    schedule 24.01.2020
comment
это rollup -c -w все настройки по умолчанию / из коробки. Если хотите, можете найти репозиторий здесь   -  person Jeanluca Scaljeri    schedule 24.01.2020
comment
не могли бы вы добавить это: emitCss: true, после строки 25 в конфигурации накопительного пакета?   -  person V. Sambor    schedule 25.01.2020
comment
Я добавил это свойство и обновил свой пост. По-прежнему не работает, но ошибка другая. Также отображается это сообщение: Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)   -  person Jeanluca Scaljeri    schedule 25.01.2020


Ответы (2)


Я создал новый проект, и мне удалось воспроизвести ту же проблему.

Сначала я подумал, что это связано с машинописным текстом, и я пробовал кучу плагинов в свертке, например: @tscc/rollup-plugin-tscc, rollup-plugin-typescript, но это не сработало.

Я также пробовал rollup-plugin-amd с такими же результатами ...

Затем я попытался изменить основной формат вывода и использовать es вместо iife. Таким образом, также потребовалось изменить вывод в каталог, а не в файл (из-за создания нескольких файлов). И, как ни странно, похоже, что это работает.

вот мой код:

/// index.html

<head>
    <meta charset='utf-8'>
    <meta name='viewport' content='width=device-width,initial-scale=1'>
    <title>Test</title>
    <link rel='stylesheet' href='build/bundle.css'>
    <script type="module" defer src='build/main.js'></script>
</head>

<body>
</body>

</html>

Примечание. main.js импортируется как модуль.

/// main.js

import App from './App.svelte';

import { applyPolyfills, defineCustomElements } from '../my-comp/loader';

applyPolyfills().then(() => {
  defineCustomElements(window);
});

const app = new App({ target: document.body });

export default app;

/// rollup.config

import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss';
import autoPreprocess from 'svelte-preprocess';
import json from '@rollup/plugin-json';

const production = !process.env.ROLLUP_WATCH;

export default {
    input: 'src/main.js',
    output: {
        sourcemap: true,
        format: 'es',
        name: 'app',
        dir: 'public/build'
    },
    plugins: [
        json(),
        svelte({
            // Enables run-time checks when not in production.
            dev: !production,

            // Extracts any component CSS out into a separate file — better for performance.
            css: css => css.write('public/build/bundle.css'),

            // Emit CSS as "files" for other plugins to process
            emitCss: true,

            preprocess: autoPreprocess()
        }),

        resolve({
            browser: true,
            dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/')
        }),
        commonjs(),

        postcss({
            extract: true,
            minimize: true,
            use: [
                ['sass', {
                    includePaths: ['./node_modules']
                }]
            ]
        }),

        // In dev mode, call `npm run start` once the bundle has been generated
        !production && serve(),

        // Watches the `public` directory and refresh the browser on changes when not in production.
        !production && livereload('public'),

        // Minify for production.
        production && terser()
    ],
    watch: {
        clearScreen: false
    }
};

function serve() {
    let started = false;

    return {
        writeBundle() {
            if (!started) {
                started = true;

                require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
                    stdio: ['ignore', 'inherit', 'inherit'],
                    shell: true
                });
            }
        }
    };
}

Примечание: я взял свою конфигурацию из другого стройного проекта (неинтересные плагины можно игнорировать)

Кажется, теперь он работает нормально, но я думаю, что это только отправная точка :) потому что есть некоторые известные проблемы с самим трафаретом, с которыми я сталкивался;

core-3d1820a5.js:97 TypeError: Failed to fetch dynamically imported module: http://localhost:57231/build/my-component.entry.js
core-3d1820a5.js:863 Uncaught (in promise) TypeError: Cannot read property 'isProxied' of undefined

https://github.com/sveltejs/sapper/issues/464

https://github.com/ionic-team/stencil/issues/1981

то же самое с реакцией: Невозможно интегрировать компонент stenciljs в приложение React

Это не полностью рабочее решение, но я подумал, что оно может помочь вам в следующих шагах ...

person V. Sambor    schedule 25.01.2020
comment
Спасибо, ваша конфигурация, кажется, работает лучше. Но bundle.js больше нет, поэтому я попытался включить (в index.html) файл main.js. Теперь я получаю в консоли браузера следующую ошибку: Uncaught SyntaxError: Cannot use import statement outside a module. Какие-либо предложения? - person Jeanluca Scaljeri; 25.01.2020
comment
да, я написал ‹Note› рядом с моим html-кодом; действительно, когда вы используете формат es, он генерирует main.js, поэтому вы должны использовать его в своем index.html и добавить type="module", тогда оператор импорта должен работать. - person V. Sambor; 25.01.2020
comment
Я действительно забыл об этом. Так что на этот раз импорт кажется правильным, я все еще получаю сообщение об ошибке: Uncaught TypeError: Failed to resolve module specifier "svelte/internal". Relative references must start with either "/", "./", or "../". Есть идеи? - person Jeanluca Scaljeri; 25.01.2020
comment
Хммм, я не получал этой ошибки. Не могли бы вы обновить вопрос, используя текущую конфигурацию накопительного пакета? - person V. Sambor; 25.01.2020
comment
Конфигурация у меня такая же, как и у вас (копипаст). Я разместил свои материалы в этом общедоступном репо. В корневом каталоге запустите yarn, затем перейдите к ./packages/fbp и запустите yarn build. Теперь вы можете воспроизвести в. / Packages / svelte` эту ошибку. - person Jeanluca Scaljeri; 25.01.2020
comment
Хорошо спасибо. Мне удалось воспроизвести. Мой первый инстинкт - сказать, что это связано с lerna вместе с svelte. Я пойду, если найду что-нибудь. Я дам тебе знать, если так - person V. Sambor; 25.01.2020
comment
Обратите внимание, что Lerna - это инструмент поверх Yarn Workspaces, который также может быть основной причиной этой проблемы! - person Jeanluca Scaljeri; 25.01.2020
comment
Я наконец нашел решение; При работе с Lerna это работает, если вы не включаете дедупликацию в resolve плагин. Так что просто прокомментируйте это: // dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/') - person V. Sambor; 25.01.2020
comment
Вау, это действительно усложняется. Однако я думаю, что когда вы решите одну проблему, возникнет другая. Теперь он не может загрузить сам файл компонента, который загружается лениво. Я добавил ошибку внизу своего сообщения. Возможно, это не проблема Svelte, но, с другой стороны, все это работает с angular :( - person Jeanluca Scaljeri; 26.01.2020
comment
Да, к сожалению, вот что значит попробовать незрелый фреймворк :) Думаю, теперь ошибки связаны с самим трафаретом. Я посмотрю, смогу ли я что-нибудь с этим поделать. - person V. Sambor; 26.01.2020
comment
Я нашел обходной путь! Если вы посмотрите пример интеграции в ситуации без фреймворка, здесь, это станет супер. Я опубликовал пакет Stenciljs в npm и с https://unpkg.com/@scaljeri/[email protected]/dist/fbp.js включил веб-компоненты. Он далек от идеала для разработки, но, по крайней мере, работает и прост. Если вы найдете способ получше, дайте мне знать! - person Jeanluca Scaljeri; 26.01.2020
comment
Хм, вчера вечером я написал в stencil slack об этой проблеме, но никто не ответил ..: - | Если у меня будет что-нибудь, я дам вам знать. - person V. Sambor; 26.01.2020

У меня все еще та же проблема в 2020 году. Как ни странно, шаблон веб-пакета работает нормально. Переключимся на это пока, пока проблема не будет решена.

https://github.com/sveltejs/template-webpack

person mrsauravsahu    schedule 11.02.2020