#javascript #angular #image #webpack #webpack-dev-server
Вопрос:
когда мы обновляем наш код для angular 12, у нас возникает проблема с webpack-dev-сервером (prod работает нормально) с src изображений на HTML. например: пожалуйста,смотрите пример src изображений здесь
<div class="hbox logo-wrapper">
<i class="fas fa-bars mx-3 cursor-pointer" (click)="onMenuClick($event)"></i>
<img src="../assets/images/white-logo.svg"
class="cursor-pointer"
(click)="onLogoClick()">
<span class="mx-3">|</span>
<i class="fas fa-home cursor-pointer"
(click)="onHomeButtonClick()"
ngbTooltip="Portal Home"></i>
</div>
этот код принадлежит какому-то компоненту в нашем проекте angular.
мы не используем интерфейс командной строки angular, но запускаем команду сборки webpack :
node --max-old-space-size=8192 node_modules/webpack-dev-server/bin/webpack-dev-server.js
в настоящее время при запуске локальной сборки — приложение работает нормально, но изображение не загружено, я имею в виду, что webpack не может найти его по адресу http://localhost:4200/assets/images/white-logo.svg — верните 404.
все отлично работает с angular 11.2, так как изменение на 12, у нас есть эта проблема, я думаю, что нам чего-то не хватает или нужно изменить какое-то определение.
это наша конфигурация веб-пакета (для разработчиков).
const path = require('path');
const packageJsonVersion = require('./package.json').version;
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const rxPaths = require('rxjs/_esm5/path-mapping');
const buildGuid = Math.floor((1 Math.random()) * 0x10000000000).toString(16).substring(1);
const { SourceMapDevToolPlugin, DefinePlugin } = require('webpack');
const { BaseHrefWebpackPlugin } = require('base-href-webpack-plugin');
const { AngularWebpackPlugin} = require('@ngtools/webpack');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); // Uncomment it below for build monitoring
const entryPoints = ["inline", "polyfills", "sw-register", "styles", "vendor", "main"];
const env = process.env.NODE_ENV || 'development';
const userName = process.env.USER || process.env.USERNAME;
const projectRoot = process.cwd();
const copyWebpackPluginIgnoreList = ["**/.gitkeep", "**/.DS_Store", "**/Thumbs.db"];
module.exports = {
performance: {
hints: false,
maxAssetSize: 100000
},
"mode": "development",
"devtool": false,
"resolve": {
"extensions": [
".ts",
".js",
".es6"
],
"symlinks": true,
"modules": [
"./src",
"./node_modules"
],
"alias": rxPaths(),
"mainFields": [
"browser",
"module",
"main"
],
"fallback": {
"stream": require.resolve("stream-browserify")
}
},
"resolveLoader": {
"modules": [
"./node_modules",
"./node_modules/@angular/cli/node_modules"
],
"alias": rxPaths()
},
"entry": {
"main": [
"./src/main.ts"
],
"polyfills": [
"./src/polyfills.ts"
]
},
"output": {
"path": path.join(process.cwd(), "dist"),
"filename": "[name].[chunkhash:20].bundle.js",
"chunkFilename": "[id].chunk.js",
"crossOriginLoading": false
},
"module": {
"rules": [
{
test: /[/\]@angular[/\]core[/\]. .js$/,
parser: { system: true }, // enable SystemJS
},
{
"test": /.html$/,
"loader": "html-loader",
options: {
esModule: false,
sources: {
list: [
// All default supported tags and attributes
'...',
{
tag: 'link',
attribute: 'href',
type: 'src',
filter: (tag, attribute, attributes, resourcePath) => {
if (/index.html$/.test(resourcePath)) {
return false;
}
return true;
}
}
],
},
},
},
{
"test": /.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani|eot|svg|cur|webm)$/,
"loader": "file-loader",
"options": {
"name": "assets/[name].[hash:20].[ext]",
"limit": 10000
}
},
{
"include": [
path.join(process.cwd(), "src/assets")
],
test: /.scss$/,
use: [
{ loader: 'style-loader', options: { esModule: false } },
{ loader: 'css-loader', options: { sourceMap: true, esModule: false } },
{ loader: "resolve-url-loader" },
{ loader: 'sass-loader', options: { sourceMap: true } }
],
},
{
"include": [
path.join(process.cwd(), "src/app")
],
test: /.scss$/,
use: [
'to-string-loader',
{ loader: 'css-loader', options: { sourceMap: true, esModule: false } },
{ loader: "resolve-url-loader" },
{ loader: 'sass-loader', options: { sourceMap: true } }
]
},
{
"test": /.ts$/,
"loader": "@ngtools/webpack"
}
]
},
"plugins": [
new CopyWebpackPlugin({
patterns: [
{
context: "public",
to: "",
from: "assets/**/*",
globOptions: {
dot: true,
ignore: copyWebpackPluginIgnoreList
},
info: { minimized: true }
}
]
}),
new ProgressPlugin(),
new CircularDependencyPlugin({
"exclude": /node_modules/,
"failOnError": false,
"onDetected": false,
"cwd": projectRoot
}),
new HtmlWebpackPlugin({
"template": "./src/index.html",
"filename": "./index.html",
"hash": false,
"inject": true,
"compile": true,
"favicon": false,
"minify": false,
"cache": true,
"showErrors": true,
"excludeChunks": [],
"title": "Webpack App",
"xhtml": true,
"chunksSortMode": function sort(left, right) {
let leftIndex = entryPoints.indexOf(left);
let rightIndex = entryPoints.indexOf(right);
if (leftIndex > rightIndex) {
return 1;
} else if (leftIndex < rightIndex) {
return -1;
} else {
return 0;
}
}
}),
new BaseHrefWebpackPlugin({}),
new SourceMapDevToolPlugin({
"filename": "[file].map[query]",
"moduleFilenameTemplate": "[resource-path]",
"fallbackModuleFilenameTemplate": "[resource-path]?[hash]",
"sourceRoot": "webpack:///"
}),
new AngularWebpackPlugin({
"fileReplacements": {
"environments/environment.ts": "environments/environment.ts"
},
"tsconfig": "src/tsconfig.app.json",
"compilerOptions": {}
}),
new DefinePlugin({
TEST_ENVIRONMENT: env === 'test',
ENVIRONMENT: JSON.stringify(env),
MACHINENAME: JSON.stringify(userName),
BUILD_GUID: JSON.stringify(buildGuid),
PORTAL_VERSION: JSON.stringify(packageJsonVersion)
}),
new CleanWebpackPlugin(),
// new BundleAnalyzerPlugin(),
],
optimization: {
moduleIds: 'named',
emitOnErrors: false
},
node: {
"global": true
},
devServer: {
port: 4200,
host: "0.0.0.0",
hot: false,
historyApiFallback: true,
proxy: {
"*": "http://localhost:3000"
},
static: [
{
watch: false
}
],
firewall: false
}
};
был бы признателен, если бы кто-нибудь мог подсказать нам, что здесь может пойти не так.
соответствующие версии пакетов:
"webpack-dev-server": "4.0.0-beta.2"
"webpack": "5.24.0",
"webpack-cli": "4.7.2",
"css-loader": "6.2.0"
"style-loader": "3.2.1"
"html-webpack-plugin": "^5.1.0"
"@ngtools/webpack": "12.2.0"
и все другие угловые пакеты с версией 12.2.0
Спасибо
Комментарии:
1. удалите ../ ваш путь к изображению в угловой. ваш абсолютный путь должен быть активами/ или /активами/. это просто проблема с путями — угловой становится немного схематичным с путями импорта изображений. Я боролся с этим много раз. попробуйте простое, прежде чем слишком увлекаться большим количеством угловых и веб — пакетов.
2. я попробовал оба варианта, которые вы предлагаете :
src="assets/images/white-logo.svg"
иsrc="/assets/images/white-logo.svg"
и все та же проблема3. Вы нашли решение?
4. привет @Диего да, я сделал эту конфигурацию в новом AngularWebpackPlugin :
"jitMode": true, "directTemplateLoading": false
и тогда это сработало для меня