在内联脚本(twig 模板)中将页面特定脚本与 Symfony 5 和 WebPack 结合使用

Using page-specific scripts with Symfony 5 and WebPack in inline script (twig template)

我正在尝试将特定于页面的模块与内联脚本一起使用,但出现错误。

起初我创建了一个模块并将其存储在assets/js/tags.js

class TaggedImage {
    constructor(image) {
        this.image = image
    }
    ...
}
export {TaggedImage}

然后我在webpack.config.js中添加了这个模块到特定的路由:

Encore
    ...
    .addEntry('photo_page', './assets/js/tags.js')

现在我正尝试在 twig 模板中将此模块与内联脚本一起使用:

<script>
    const myImage = new TaggedImage(document.getElementById('photoImage'));
    const tags = [
            {x:0.5, y:0.5, width:0.15, height:0.22},
            {x:0.65, y:0.33, width:0.13, height:0.19},
            {x:0.1222, y:0.398, width:0.10, height:0.335}
        ];
    myImage.addTags(tags).render();
</script>

然后我在终端中 运行 npm run dev 并且没有错误地完成了。

...刷新页面后,控制台出现错误:

Uncaught ReferenceError: TaggedImage is not defined

我注意到我的代码已添加到 /public/build/photo_page.js,但我在页面源代码中没有看到任何提及此文件的内容。

你的问题有两点。 第一个是除了在 webpack.config 中定义条目外,您还必须在 html.

中显式导入 javascript

您可以使用手册 page specific scripts 部分中描述的 twig 辅助函数 encore_entry_script_tags 来实现。

所以你会添加:

{{ encore_entry_script_tags('photo_page') }}
<script>
// Here goes your script
</script>

或者覆盖您的块(如果有的话),然后调用 {{ parent() }} 以在所有页面中包含您需要的任何其他脚本。 请注意,entry 标签默认会添加 defer 属性,如 config/packages/webpack_encore.yaml 中所配置,因此您需要考虑到这一点并将脚本包装在 load事件。

第二个是 webpack 不会将模块暴露给全局命名空间。为此,您必须在模块中明确地执行此操作:

// Instead of exporting the module, you export it to the global scope
// (the browser window in this case)
global.TaggedImage = TaggedImage;