【问题标题】:import Stencil in Svelte在 Svelte 中导入 Stencil
【发布时间】:2020-01-23 21:46:36
【问题描述】:

我有一个带有精简项目和 Stencil 组件库的 Monorepo。在Stencil website 上,他们非常清楚地描述了如何将库与例如 Angular 集成

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

超级简单。但现在我也想在 Svelte 项目中使用它.....不再那么容易了:(

当我尝试执行与上述类似的操作时,出现严重错误

fbp/dist 是 Stencil 文件所在的位置。

当我首先构建我的 Stencil 项目并将我的 dist 复制到 public 文件夹并在 index.html 的头部加载 ./dist/fbp.js 时,一切正常。但是,如果我可以像使用 Angular 一样包含它,那就容易多了。有什么建议吗?

更新:添加了emitCss,它给出了

它在最后的某个地方统计:Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)

更新:通过 @Sambor 的修复,Svelte 现在能够下载 Web 组件,但不幸的是失败了

【问题讨论】:

  • 你使用什么捆绑器? (webpack,汇总)?
  • 它是rollup -c -w 到目前为止所有默认值/开箱即用。如果你喜欢,你可以找到 repo here
  • 您可以尝试在汇总配置中的第 25 行之后添加:emitCss: true, 吗?
  • 我已添加该属性并更新了我的帖子。仍然无法正常工作,但错误有所不同。它还显示此消息:Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)

标签: javascript typescript web-component svelte stenciljs


【解决方案1】:

我创建了一个新项目,并设法重现了同样的问题。

起初,我认为这与打字稿有关,我在汇总中尝试了一堆插件,例如:@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

与反应相同:Unable to integrate stenciljs component in React application

这不是完全可行的解决方案,但我认为它可能会对您的后续步骤有所帮助...

【讨论】:

  • 谢谢,您的配置似乎运行得更好。但是没有bundle.js 了,所以我尝试包含(在index.html 中)文件main.js。现在我在浏览器控制台中看到以下错误:Uncaught SyntaxError: Cannot use import statement outside a module。有什么建议吗?
  • 是的,我在我的html代码附近写了一个;实际上,当您使用es 格式时,它会生成main.js,因此您必须在index.html 中使用它并添加type="module",然后导入语句应该可以工作。
  • 我确实忘记了那个。所以这次导入似乎是正确的,我仍然收到错误消息:Uncaught TypeError: Failed to resolve module specifier "svelte/internal". Relative references must start with either "/", "./", or "../". 有什么想法吗?
  • 好的,谢谢。我已经成功地重现了。我的第一直觉是说这与lerna 和苗条有关。我会看看如果我能找到什么。如果是的话我会告诉你的
  • 我终于找到了解决办法;使用Lerna 运行时,如果您不在resolve 插件中包含重复数据删除,它似乎可以工作。所以,只需注释掉这个:// dedupe: importee =&gt; importee === 'svelte' || importee.startsWith('svelte/')
【解决方案2】:

我在 2020 年仍然遇到同样的问题。令人惊讶的是,webpack 模板运行良好。现在切换到那个,直到这个问题得到解决。

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

【讨论】:

    猜你喜欢
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 2019-02-03
    • 2020-08-09
    • 2020-03-02
    相关资源
    最近更新 更多