Webpack: handling of static assets with webpack-manifest-plugin in a production build

2.1k views Asked by At

I'm currently in the process of integrating Webpack in an existing serverside-rendered multi-page-application to leverage the modern tools and ecosystem around Webpack.

This has primarily been a good experience but I'm currently struggling with the integration into our serverside code, especially with a production build using hashing and a flat folder structure. The basic idea is very simple: all assets are managed by Webpack and with the help of webpack-manifest-plugin I generate a manifest.json that is read by our serverside application. And with a helper function I would turn a path like static/images/logo.png into logo-[hash].png.

This works great for js/css files (where only the bundle name of my entry points are relevant) but I have problems generating a manifest.json file that contains the necessary information I need for the static assets like images and documents.

Partial Webpack configuration

This is the relevant part of my webpack configuration:

{
    entry: {
        index: './js/app.js',
        "static-assets": './js/static-assets.js'
    },
    output: {
        filename: '[name].js'
    },
    resolve: {
        alias: {
            "vendor-assets": "dependencyX/assets",
        }
    },
    plugins: [
        new WebpackManifestPlugin()
    ],
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: isDev ? '[path][name].[ext]' : '[hash].[ext]',
                        }
                    }
                ]
            }
        ]
    }
}

Approach 1: copy-webpack-plugin

I tried a configuration like this:

new CopyWebpackPlugin([
    {
        from: './static',
        to: isDev ? '[path][name].[ext]' : '[name].[hash].[ext]'
    },
    {
        from: 'node_modules/dependencyX/assets/img',
        to: isDev ? 'vendor-assets/[path][name].[ext]' : '[name].[hash].[ext]'
    },
])

Problem 1: In the manifest I only get the key of the new location but no information about the original path at all:

"logo.png": "logo.d985ee06aa950d9232f80c09a9e1329f.png"

instead of:

"node_modules/dependencyX/assets/img/logo.png": "logo.d985ee06aa950d9232f80c09a9e1329f.png",

or even better considering my defined alias:

"vendor-assets/img/logo.png": "logo.d985ee06aa950d9232f80c09a9e1329f.png",

Problem 2: as copy-webpack-plugin seems to do a simple copy there will be a problem of duplication. If I reference one of these static assets also from a regular bundle it will appear a second time in the output folder.

Approach 2: static-assets bundle

My second approach was to define a bundle static-assets.js which references all possible locations of static assets using a request.context:

require.context('../static', true, /.+/);
require.context('vendor-assets/img', true, /.+/);

Problem: Like with the copy approach, the resulting manifest only contains the simple filename as key and not the original path.

Questions

  • Is there a simple way to solve this by configuration?
  • Are there other approaches?
0

There are 0 answers