Komi
Komi

Reputation: 478

How can I set webpack to translate asset paths to another path?

I have a Vue.js app, which is going to be used as a theme for a WordPress site, and wordpress serves the assets on a diffrent path than Vue.js would expect, this is the path that would work normally:

<img src="src/assets/images/image.svg"/>

But this is what works:

<img src="/wp-content/themes/theme-name/src/assets/images/image.svg"/>

So my question is that how would I go about this? Since I have almost null knowledge about how wordpress operates, except for the REST API part, what could I do. I would like WebPack to translate these paths if possible, and i have tried the publicPath: '/wp-content/pathtoassets' trick, but it does not seem to work. Also if this is not possible with WebPack, can i do something in php to serve this path as a global variable to my Vue theme?
Here is my vue.config.js:

const {
  WebpackManifestPlugin
} = require('webpack-manifest-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const gifsicle = require('imagemin-gifsicle');
const jpegtran = require('imagemin-jpegtran');
const optipng = require('imagemin-optipng');

module.exports = {
  runtimeCompiler: true,
  // filenameHashing: false,
  productionSourceMap: false,
  chainWebpack: config => {
    config.plugins.delete('preload');
    config.plugins.delete('prefetch');
    config.module.rule('images').use('url-loader');
    config.module.rule('svg').use('file-loader');
  },
  configureWebpack: config => {
    config.output.filename = 'scripts/[name].js';
    config.output.chunkFilename = 'scripts/[name].js';
    config.plugins = [
      ...config.plugins,
      new CopyWebpackPlugin({
        patterns: [{
            from: 'src/assets/fonts',
            to: 'fonts/[name].[ext]',
          },
          {
            from: 'src/assets/images',
            to: 'images/[name].[ext]',
          },
        ],
      }),
      new ImageMinimizerPlugin({
        severityError: 'warning',
        minimizerOptions: {
          plugins: [
            [gifsicle, {
              interlaced: true
            }],
            [jpegtran, {
              progressive: true
            }],
            [optipng, {
              optimizationLevel: 5
            }],
          ],
        },
      }),
      new WebpackManifestPlugin({
        fileName: 'manifest.json',
        basePath: '/dist/',
      }),
    ];
  },
  css: {
    extract: {
      filename: 'styles/[name].css',
      chunkFilename: 'styles/[name].css',
    },
  },
};

Also I, have been able to use the manifest.json to enqueue my scripts and styles, i just dont know how to make these assets like images or fonts work like they should.
Furthermore, if anyone who sees this and has worked with Vue.js as a WordPress theme, and has any suggestions to what should/could do more to help me along the way, i would appreciate it real much! Thank you in advance!

Upvotes: 1

Views: 423

Answers (1)

Komi
Komi

Reputation: 478

Welp, it turns out it's as easy as adding publicPatch property to your loaders, like:

config.module
  .rule('svg')
  .use('file-loader')
  .options({
    name: 'images/[name].[ext]',
    publicPath,
  });

The publicPath property being the following:

const [, themeName] = __dirname.match(/\/wp-content\/themes\/([^/]+)/);
const publicPath = isProduction ? `/wp-content/themes/${themeName}/dist/` : '/';

Which will compile down to my .svg's being resolved to this path:
/wp-content/themes/${themeName}/dist/images/[name].[ext]

Upvotes: 1

Related Questions