изображения в src в обновлении angular 12 не загружаются в webpack-dev-сервер

#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 и тогда это сработало для меня