Я использую Webpack для упаковки статических файлов javascript с папками и активами в один выходной файл bundle.js. Затем файл bundle.js извлекается из исходной кодовой базы и статически размещается на внутреннем сервере. Проблема в том, что активы не объединены в файл bundle.js. Когда я пытаюсь отобразить общедоступный URL-адрес index.js во внешнем интерфейсе, я получаю сообщение об ошибке:
GET http://127.0.0.1:5503/public/Stage/sounds/pop.wav 404 (Not Found)
Сейчас бэкэнд работает на localhost:5000
, а фронтенд — на localhost:5503
. Версия веб-пакета 5.77.0
.
Я знаю, что webpack будет автоматически связывать ресурсы, если они явно импортированы и указаны в файлах, но проблема в том, что статические файлы javascript на самом деле являются javascripts Scratch-кодов, которые преобразуются с помощью пакета с именем sb-edit
, и я не могу изменить способ кодирования. написано.
Вот как активы упоминаются в файлах:
new Costume("button4-a", "./Button4/costumes/button4-a.svg")
Это содержимое webpack.config
, я использую asset-modules
, поэтому нет необходимости в file-loader
или любых других загрузчиках:
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: '[path][name].[ext]',
},
experiments: { outputModule: true },
externals: {
'https://unpkg.com/leopard@^1/dist/index.esm.js': 'https://unpkg.com/leopard@^1/dist/index.esm.js',
},
externalsType: 'module',
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif|mp3|wav)$/i,
type: 'asset',
},
],
},
optimization: {
usedExports: true,
sideEffects: false,
},
resolve: {
fallback: {
"path": require.resolve("path-browserify"),
"url": require.resolve("url"),
"events": require.resolve('events'),
}
},
};
Это один пример (не вся структура) структуры статических файлов javascript:
.
├── Sprite2/
│ ├── costumes/
│ │ └── costumes1.svg
│ ├── sounds/
│ │ └── pop.wav
│ └── Sprite2.js
├── Sprite3/
│ ├── costumes/
│ │ └── costumes1.svg
│ ├── sounds/
│ │ └── pop.wav
│ └── Sprite3.js
└── index.js
Ссылка на файл во внешнем интерфейсе выглядит следующим образом:
<script type = "module" src = "http://localhost:5000/api/v1/scratch/bundle.js"></script>
Я пытался изменить типы модулей активов на asset/resource
, asset/inline
и asset
, но ни один из этих вариантов не работает. Есть ли способ добиться этого без внесения изменений в исходный код? Огромное спасибо заранее!
Я использую живой сервер Visual Studio, чтобы начать работу с интерфейсом.
Мне удалось найти способ обойти это, и я надеюсь, что это каким-то образом поможет другим.
Прежде всего, я использовал CopyWebpackPlugin
веб-пакета, чтобы скопировать все активы в папку назначения, сохранив при этом их исходную файловую иерархию. Я проигнорировал все файлы, которые не были активами:
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: './**/*',
to: './',
context: './',
globOptions: {
ignore: ['**/*.js', '**/node_modules/**', '**/*.html', '**/*.json']
}
}
]
}),
],
Затем я помещаю папку с этими активами в статически хранимую папку в бэкэнде вместе со сгенерированным файлом bundle.js
.
Первоначально я использовал только статически хранящийся файл js в теге script следующим образом:
<script type = "module" src = "http://localhost:5000/api/v1/scratch/bundle.js"></script>
Теперь я сначала использую axios, чтобы сначала получить файл js пакета, затем я анализирую файл js и вручную добавляю URL-адрес бэкэнда перед относительными путями ресурсов внутри пакета:
axios.get('http://localhost:5000/url-to-statically-held-folder/bundle.js')
.then(response => {
let jsCode = response.data;
jsCode = jsCode.replace(/\.[/\w\s-]+\.(png|svg|jpg|jpeg|gif|mp3|wav)/g, (match) => {
let urlStr = `http://localhost:5000/url-to-statically-held-folder/${match}`
return urlStr;
});
const script = document.createElement('script');
script.type = 'module';
script.src = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(jsCode);
document.head.appendChild(script);
})
.catch(error => {
console.error(error);
});
Теперь это работает.
Как вы запускаете фронтенд-сервер?