无法在使用Webpack的Angular 5生产环境中显示图片

7

我有一个在Angular应用程序开发期间出现在主页的图片,但是当我发布到生产环境时,图片不显示。我一直在看其他讨论(这个看起来很有希望,但没有解决我的问题),但仍然没有找到解决方案。有什么想法吗?

我的图片标签如下:

<img alt="Rocket" src="../../images/rocket.gif" />

在生产环境中,它的输出如下:

<img alt="Rocket" src="dist/0f686f4440348c6e453c282baa10b674.gif">

我查看了我的 dist 文件夹,发现文件确实存在,但是好像是损坏的。那里还有另一个文件,5743b3dcb9db968dd0e484850845aa54.gif,其中包含我的图像。不确定是否能提供提示。
我的 webpack.config.js 文件如下:
const path = require("path");
const webpack = require("webpack");
const merge = require("webpack-merge");
const AngularCompilerPlugin = require("@ngtools/webpack").AngularCompilerPlugin;
const CheckerPlugin = require("awesome-typescript-loader").CheckerPlugin;

module.exports = (env) => {
    // Configuration in common to both client-side and server-side bundles
    const isDevBuild = !(env && env.prod);
    //const isDevBuild = false;
    const sharedConfig = {
        stats: { modules: false },
        context: __dirname,
        resolve: {
            extensions: [".ts", ".js"],
            "alias": {
                "jquery-ui":"jquery-ui-dist/jquery-ui",
                "scripts": path.resolve(__dirname, "./ClientApp/scripts"),
                "node_modules": path.resolve(__dirname,"./node_modules")
            }
        },
        output: {
            filename: "[name].js",
            publicPath: "dist/" // Webpack dev middleware, if enabled, handles requests for this URL prefix
        },
        module: {
            rules: [
                { test: /\.ts$/, include: /ClientApp/, use: ["awesome-typescript-loader?silent=true", "angular2-template-loader", "angular-router-loader"] },
                { test: /\.html$/, use: "html-loader?minimize=false" },
                { test: /\.scss$/, include: /ClientApp/, use: ["raw-loader", "sass-loader"] },
                { test: /\.css$/, use: ["to-string-loader", isDevBuild ? "css-loader" : "css-loader?minimize"] },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: "url-loader?limit=25000" }
            ]
        },
        plugins: [
            new CheckerPlugin(),
            new webpack.ProvidePlugin({
                jQuery: "jquery",
                $: "jquery",
                jquery: "jquery",
                "window.jQuery": "jquery'",
                "window.$": "jquery"
            })]
    };

    // Configuration for client-side bundle suitable for running in browsers
    const clientBundleOutputDir = "./wwwroot/dist";
    const clientBundleConfig = merge(sharedConfig, {
        entry: { "main-client": "./ClientApp/boot.browser.ts" },
        output: { path: path.join(__dirname, clientBundleOutputDir) },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require("./wwwroot/dist/vendor-manifest.json")
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: "[file].map", // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, "[resourcePath]") // Point sourcemap entries to the original file locations on disk
            })
        ] : [
                // Plugins that apply in production builds only
                new webpack.optimize.UglifyJsPlugin(),
                //new AotPlugin({
                new AngularCompilerPlugin({
                    tsConfigPath: "./tsconfig.json",
                    entryModule: path.join(__dirname, "ClientApp/app/app.module.browser#AppModule"),
                    exclude: ["./**/*.server.ts"]
                })
            ])
    });

    // Configuration for server-side (prerendering) bundle suitable for running in Node
    const serverBundleConfig = merge(sharedConfig, {
        resolve: { mainFields: ["main"] },
        entry: { "main-server": "./ClientApp/boot.server.ts" },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require("./ClientApp/dist/vendor-manifest.json"),
                sourceType: "commonjs2",
                name: "./vendor"
            })
        ].concat(isDevBuild ? [] : [
            // Plugins that apply in production builds only
            //new AotPlugin({
            new AngularCompilerPlugin({
                tsConfigPath: "./tsconfig.json",
                entryModule: path.join(__dirname, "ClientApp/app/app.module.server#AppModule"),
                exclude: ["./**/*.browser.ts"]
            })
        ]),
        output: {
            libraryTarget: "commonjs",
            path: path.join(__dirname, "./ClientApp/dist")
        },
        target: "node",
        devtool: "inline-source-map"
    });

    return [clientBundleConfig, serverBundleConfig];
};

我的webpack.config.vendor.js文件如下所示:
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const merge = require("webpack-merge");
const treeShakableModules = [
    "@angular/animations",
    "@angular/cdk",
    "@angular/common",
    "@angular/compiler",
    "@angular/core",
    "@angular/forms",
    "@angular/http",
    "@angular/material",
    "@angular/platform-browser",
    "@angular/platform-browser-dynamic",
    "@angular/router",
    "@asymmetrik/ngx-leaflet",
    "@progress/kendo-angular-charts",
    "@progress/kendo-angular-inputs",
    "@progress/kendo-angular-intl",
    "@progress/kendo-angular-l10n",
    "@progress/kendo-drawing",
    "@progress/kendo-file-saver",
    "zone.js"
];
const nonTreeShakableModules = [
    "@progress/kendo-theme-default/dist/all.css",
    "ag-grid-angular",
    "ag-grid",
    "ag-grid-enterprise/dist/ag-grid-enterprise.js",
    "ag-grid/dist/styles/ag-grid.css",
    "ag-grid/src/styles/ag-theme-material.scss",
    "bootstrap",
    "bootstrap/dist/css/bootstrap.css",
    "es6-promise",
    "es6-shim",
    "event-source-polyfill",
    "exceljs/dist/exceljs.min.js",
    "file-saver",
    "font-awesome/css/font-awesome.css",
    "hammerjs",
    "jquery",
    "jquery-ui-dist/jquery-ui",
    "leaflet",
    "leaflet/dist/leaflet.css",
    "lodash",
    "moment",
    "ngx-bootstrap",
    "tether",
    "sheetjs",
    "xlsx",
    "./ClientApp/theme/material/js/material.js",
    "./ClientApp/theme/material/js/ripples.js",
    "./ClientApp/theme/material/css/bootstrap-material-design.css",
    "./ClientApp/theme/material/css/ripples.css"
];
const allModules = treeShakableModules.concat(nonTreeShakableModules);

module.exports = (env) => {
    const extractCSS = new ExtractTextPlugin("vendor.css");
    const isDevBuild = !(env && env.prod);
    //const isDevBuild = false;
    const sharedConfig = {
        stats: { modules: false },
        resolve: {
            extensions: [".js"]
        },
        module: {
            rules: [
                { test: /\.(png|gif|jpg|jpeg|woff|woff2|eot|ttf|svg)(\?|$)/, use: "url-loader?limit=100000" },
                { test: /\.scss$/, use: ["raw-loader", "sass-loader"] }
            ]
        },
        output: {
            publicPath: "dist/",
            filename: "[name].js",
            library: "[name]_[hash]"
        },
        plugins: [
            new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", jquery: "jquery", "window.jQuery": "jquery", "_": "lodash" }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
            new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, "./ClientApp")), // Workaround for https://github.com/angular/angular/issues/11580
            new webpack.ContextReplacementPlugin(/\@angular(\\|\/)core(\\|\/)esm5/, path.join(__dirname, "./ClientApp")), 
            new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/, path.join(__dirname, "./ClientApp")), // Workaround for https://github.com/angular/angular/issues/14898
            new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
        ]
    };

    const clientBundleConfig = merge(sharedConfig, {
        entry: {
            // To keep development builds fast, include all vendor dependencies in the vendor bundle.
            // But for production builds, leave the tree-shakable ones out so the AOT compiler can produce a smaller bundle.
            vendor: isDevBuild ? allModules : nonTreeShakableModules
        },
        output: { path: path.join(__dirname, "wwwroot", "dist") },
        module: {
            rules: [
                { test: /\.css(\?|$)/, use: extractCSS.extract({ use: isDevBuild ? "css-loader" : "css-loader?minimize" }) }
            ]
        },
        plugins: [
            extractCSS,
            new webpack.DllPlugin({
                path: path.join(__dirname, "wwwroot", "dist", "[name]-manifest.json"),
                name: "[name]_[hash]"
            })
        ].concat(isDevBuild ? [] : [
            new webpack.optimize.UglifyJsPlugin()
        ])
    });

    const serverBundleConfig = merge(sharedConfig, {
        target: "node",
        resolve: { mainFields: ["main"] },
        entry: { vendor: allModules.concat(["aspnet-prerendering"]) },
        output: {
            path: path.join(__dirname, "ClientApp", "dist"),
            libraryTarget: "commonjs2"
        },
        module: {
            rules: [{ test: /\.css(\?|$)/, use: ["to-string-loader", isDevBuild ? "css-loader" : "css-loader?minimize"] }]
        },
        plugins: [
            new webpack.DllPlugin({
                path: path.join(__dirname, "ClientApp", "dist", "[name]-manifest.json"),
                name: "[name]_[hash]"
            })
        ]
    });

    return [clientBundleConfig, serverBundleConfig];
}
1个回答

5
我已经解决了这个问题。原来我需要在 webpack.config.vendor.js 文件中的非 tree shakeable 部分添加对该图像的引用。
我添加了以下代码,在组件 HTML 页面中修复了引用,现在 AOT 发布的应用程序可以完美运行!太棒了!
"./ClientApp/images/rocket.gif"

在这种情况下,您需要记得重新生成供应商文件。webpack --config webpack.config.vendor.js - tone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接