0
votes

I arranged assets paths in my webpack project, it works well under webpack-dev-server, but publishing the project(using Github pages); it seems the browser can't reach assets because its absolute path

for example,

I have src/components/banner.html as bellow

<div class="c-banner ">
    <h3 class="c-banner__title">banner header</h3>
    <p class="c-banner__desc">
            banner body  
    </p>
    <a href="#" class="c-btn c-btn--ghost c-banner__action">more</a>
    <i class="c-icon c-icon--flag c-banner__icon"></i>
    <i class="c-icon c-icon--cancel-circle c-banner__close js-banner__close"></i>
    <img src="../assets/images/profile.png" alt="">
</div>

it bundled in dist/components/banner.html as bellow

<head><link href="/assets/css/styles.css" rel="stylesheet"></head>
<div class="c-banner ">
    <h3 class="c-banner__title">banner header</h3>
    <p class="c-banner__desc">
        banner body    
    </p>
    <a href="#" class="c-btn c-btn--ghost c-banner__action">more</a>
    <i class="c-icon c-icon--flag c-banner__icon"></i>
    <i class="c-icon c-icon--cancel-circle c-banner__close js-banner__close"></i>
    <img src="/assets/images/profile.png" alt="">
    
</div>
<script src="/main.js"></script><script src="/assets/js/banner.js"></script>

my webpack.config.js

var path = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ASSET_PATH = process.env.ASSET_PATH || '/';
const webpack = require('webpack');

module.exports = {
  entry:  {
    'main': './src/index.js',
    'assets/js/banner': './src/assets/js/banner.js',
  },

  output: {
    path: path.join(__dirname, "/dist"),
    publicPath: ASSET_PATH ,
    filename: '[name].js',
  }, 

  devServer: {
    contentBase: path.join(__dirname, "/dist"),
    port: 1111,
    writeToDisk: true,
  },

  module: {
    rules: [
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader",
          }
        ]
      },

      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader, 
            options: {
              publicPath: '/' 
            }
          },
          "css-loader",
          "postcss-loader",
          "sass-loader"
            
        ]
      },

      {
        test: /\.(png|svg|jpe?g|gif)$/,
        use: [
          {
            loader: "file-loader", 
            options: {
              name: '[name].[ext]',
              outputPath: "assets/images",
            }
          }
        ]
      },

      {
        test: /\.(svg|eot|woff|woff2|ttf)$/,
        use: [
          {
            loader: "file-loader", 
            options: {
              name: '[name].[ext]',
              outputPath: "assets/fonts",
            }
          }
        ]
      },
      
    ]
  },

  plugins: [
    new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),

    new HtmlWebpackPlugin({ 
        filename: "index.html",
        template: "./src/index.html",
        chunks: ['main', 'assets/js/banner']
    }),

    new HtmlWebpackPlugin({ 
        filename: "components/banner.html",
        template: "./src/components/banner.html",
        chunks: ['main', 'assets/js/banner']
    }),

    new HtmlWebpackPlugin({ 
      filename: "components/button.html",
      template: "./src/components/button.html",
      chunks: ['main']
    }),

    new MiniCssExtractPlugin({filename: "assets/css/styles.css"}),
    new OptimizeCSSAssetsPlugin({}),
    new webpack.DefinePlugin({
      'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
    }),

  ],
  
}

project structureenter image description here

the same problem in font paths, CSS, and js files

2

2 Answers

2
votes

You can change publicPath in output to '' as follows:

output: {
    path: path.join(__dirname, "/dist"),
    publicPath: '' ,
    filename: '[name].js',
  },

and change the publicPath of MiniCssExtractPlugin configuration to '../../':

{
  loader: MiniCssExtractPlugin.loader, 
  options: {
    publicPath: '../../' 
  }
},

0
votes

You can change publicPath to the correct one on your server, by using the environment variable for example:

  //...
  const publicPath = process.env.BASE_URL || '/';
  output: {
    path: path.join(__dirname, "/dist"),
    publicPath:,
    filename: '[name].js',
  },
  //...