Hallo zusammen!
tl;dr;
Ich versuche den webpack worker-loader im JavaScript meines Shopware-Plugins einzusetzen und komme hier leider auf keinen grünen Zweig. Hat jemand Erfahrung damit?
Ausführlicher:
Ich versuche in meinem Plugin JavaScript Web Worker (Web Workers API - Web APIs | MDN) einzusetzen. Da Storefront auf webpack in der Version 4 setzt und ich gerne mit Hot Module Reload (HMR) entwickle, habe ich in meiner eigenen webpack.config.js den worker-loader (worker-loader | webpack) eingebaut.
Meine webpack.config.js sieht wie folgt aus:
const { join, resolve } = require('path');
const webpack = require('webpack');
const path = require("path");
module.exports = () => {
return {
module: {
rules: [
{
test: /\.worker\.js$/,
use: {
loader: "worker-loader"
},
},
],
},
resolveLoader: {
alias: {
"worker-loader": resolve(
join(__dirname, '..', 'node_modules', 'worker-loader'),
),
},
}
}
}
In meiner packackge.json im Plugin trage ich webpack, webpack-cli und den worker-loader wie folgt ein:
"devDependencies": {
"webpack": "^4.0.0",
"webpack-cli": "^4.0.0",
"worker-loader": "^3.0.0"
}
Das .bin/build-storefront läuft so problemlos durch. Allerdings kann der Browser die Worker-Datei (xyz.worker.js) nicht finden. Im HMR-Mode (ich nutze das über Dockware make watch-storefront
) versucht er textmesh.worker.worker.js über http://localhost:9998/js/textmesh.worker.worker.js zu finden und schlägt dabei fehl. Ich vermute, dass im Hot-Mode eher http://localhost:9998/_webpack_hot_proxy_/js/textmesh.worker.worker.js angefragt werden sollte, kann das sein?
Ich freue mich über jede Info/Erfahrung/Anregung zu dem Thema!
Liebe Grüße
Habe mich mit dem HMR-Mode noch nie wirklich explizit auseinandergesetzt, ist das aber nicht schon in watch-storefont.sh implementiert? Einzige Bedingung ist, dass das env=dev ist, wenn ich mich recht erinnere.
Das HMR tut auch was es soll - allerdings meine ich, dass es den publicPath anpasst, mit dem die Assets dann erreichbar sind. Deswegen sieht man im base.html.twig von der Storefront auch diesen Teil hier:
{# @deprecated tag:v6.5.0 - Will be moved to `layout/meta.html.twig` - Use block `layout_head_javascript_hmr_mode` instead #}
{% block base_script_hmr_mode %}
{% if isHMRMode %}
<script type="text/javascript" src="/_webpack_hot_proxy_/js/vendor-node.js"></script>
<script type="text/javascript" src="/_webpack_hot_proxy_/js/vendor-shared.js"></script>
<script type="text/javascript" src="/_webpack_hot_proxy_/js/runtime.js"></script>
<script type="text/javascript" src="/_webpack_hot_proxy_/js/app.js"></script>
{# The storefront entry is a combined entry point which contains all plugins & themes #}
<script type="text/javascript" src="/_webpack_hot_proxy_/js/storefront.js"></script>
{% else %}
{% for file in theme_config('assets.js') %}
<script type="text/javascript" src="{{ asset(file, 'theme') }}"></script>
{% endfor %}
{% endif %}
{% endblock %}
Da ist ja dann immer dieser _webpack_hot_proxy Präfix bei vor den Assets.
Hat hier jemand schon einmal einen Web Worker in einem Shopware Plugin erfolgreich eingebaut?
#Teil-Lösung
Für den HMR-Teil konnte ich es mit der inline-option vom worker-loader lösen:
rules: [
{
test: /\.worker\.js$/,
use: {
loader: "worker-loader",
options: {
inline: isHotMode ? "fallback" : "no-fallback",
},
},
},
],
Wenn ich „ganz normal“ über yarn build
, also webpack --config ./build/webpack.config.prod.js
bauen möchte, behauptet er, mein JS-File, das den Worker importen möchte sei Fehlerhaft:
ERROR in ./src/my-plugin/Aufrufendes.js 10:21
Module parse failed: Unexpected token (10:21)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Falls noch jemand darüber stolpert: die Option inline
im webpack-dev falle auf fallback zu setzen und sonst auf no-fallback hat bei mir zum gewünschten Ergebnis geführt!