当着陆页不在子目录中时,如何为多页 webpack 配置设置图像链接?

How to set image links for a multipage webpack configuration when the landing page is not in a subdirectory?

我正在尝试多页面 webpack 配置,我有一个问题,即与站点上的其他页面相比,如何以不同方式为登录页面加载图像。着陆页构建到根目录,而其他页面构建到它们各自的子文件夹。

Webpack 为其他页面附加了正确的相对路径 ../images/,但是登录页面需要保持 images/,因为它与图像文件夹位于根目录中。

如何配置 webpack,使着陆页的 <img src="images/00.jpg"> 保持不变,但所有其他页面更新为 <img src="../images/00.jpg">

这是源文件夹:

/ src /
   -home.html
   -about.html
   js/
      -home.js
      -about.js
   images/
      -00.jpg
      -01.jpg
   scss/
      -style.scss

这里是 webpack 生成的构建文件夹:

/ public_html /
   -index.html   // relative links in this file become broken :(
   -bundle.js
   about/
      -index.html
      -bundle.js
   images/
      -00.jpg
      -01.jpg
   css/
      -style.css

最后是webpack的配置。请原谅代码墙,我决定包括整个配置,以防有更好的设置方法。

// webpack.config.js

const webpack = require('webpack');
const path = require('path');

const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
 entry: {
   home: './src/js/home.js',
   about: './src/js/about.js',
  },
 output: {
   filename: (pathData) => {
     return pathData.chunk.name === 'home' ? 'bundle.js' : '[name]/bundle.js';
   },
   path: path.resolve(__dirname, 'public_html')
 },
 module: {
   rules: [
     {
       test: /\.js$/,
       exclude: /node_modules/,
       use: {
         loader: "babel-loader"
       }
     },{
       test: /\.html$/,
       use: [
         {
           loader: "html-loader",
           options: { minimize: true }
         }
       ]
     },{
       test: /\.css$/,
       use: [MiniCssExtractPlugin.loader, "css-loader"]
     },{
       test: /\.sass$|\.scss$/,
       use: [
         MiniCssExtractPlugin.loader,
         { loader: 'css-loader' },
         { loader: 'sass-loader' },
       ],
     },{
       test: /\.(jpg|png|svg)$/,
       use: [
         {
           loader: 'file-loader',
           options: {
             name: '[name].[ext]',
             outputPath:'images/',
             publicPath:'../images/'    // how to exclude home.html ?
           }
         }
       ]
     }
   ]
 },
 plugins: [
    new HtmlWebPackPlugin({
      hash: true,
      filename: 'index.html',      // landing page remains in root directory
      template: 'src/index.html',
      chunks: ['home']
   }),
    new HtmlWebPackPlugin({
      hash: true,
      filename: 'about/index.html', // all other pages move to subdirectories
      template: 'src/about.html',
      chunks: ['about']
   }),
   new MiniCssExtractPlugin({
      filename: "css/style.css"
   }),
   new CleanWebpackPlugin()
 ]
};

谢谢!另外,让我知道您喜欢这个配置文件!

我有它的工作。万岁!

我从来没有用过 publicPath。也许会有一种方法可以改变它,但这最终是一个转移注意力的问题。相反,我重组了我的 src 目录以遵循我正在寻找的模式,并删除了 html-loader 因此路径在构建过程中不会被更改。

这是我的新源目录:

/ src /
  -home.html
  templates/
    -about.html
  js/
    -home.js
    -about.js
  images/
    -00.jpg
    -01.jpg
  scss/
    -style.scss

你可以看到 home.html 是故意放在主目录而不是 /templates。图片来源在 home.html 中被引用为 images/,在其他地方被引用为 ../images/

现在我使用 copy-webpack-plugin 代替 html-loader 要求/将图像从源目录复制到构建文件夹,因为 html-loader 在构建过程中更改了路径.我试了几次才弄清楚 html-loader 是罪魁祸首。

这是我最终的工作 webpack 配置记录。

// webpack.config.js

const webpack = require('webpack');
const path = require('path');

const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
 context: path.resolve(__dirname, 'src'),
 entry: {
   home: './js/home.js',
   about: './js/about.js',
  },
 output: {
   filename: (pathData) => {
     return pathData.chunk.name === 'home' ? 'bundle.js' : '[name]/bundle.js';
   },
   path: path.resolve(__dirname, 'public_html')
 },
 module: {
   rules: [
     {
       test: /\.js$/,
       exclude: /node_modules/,
       use: {
         loader: "babel-loader"
       }
     },{
       test: /\.css$/,
       use: [MiniCssExtractPlugin.loader, "css-loader"]
     },{
       test: /\.sass$|\.scss$/,
       use: [
         MiniCssExtractPlugin.loader,
         { loader: 'css-loader' },
         { loader: 'sass-loader' },
       ],
     },{
       test: /\.(jpg|png|svg)$/,
       use: [
         {
           loader: 'file-loader',
           options: {
             name: '[path][name].[ext]'
           }
         }
       ]
     }
   ]
 },
 plugins: [
    new CopyPlugin({
      patterns: [
        {from:'./image',to:'image'} 
      ],
    }),
    new HtmlWebPackPlugin({
      hash: true,
      filename: 'index.html',      // landing page remains in root directory
      template: 'index.html',
      chunks: ['home']
   }),
    new HtmlWebPackPlugin({
      hash: true,
      filename: 'about/index.html', // all other pages move to subdirectories
      template: 'templates/about.html',
      chunks: ['about']
   }),
   new MiniCssExtractPlugin({
      filename: "style.css"
   }),
   new CleanWebpackPlugin()
 ]
};

我就是这样解决问题的

  1. 在视图中导入图像

Import YourImage from '../../public/assets/img/your-image.png';

  1. 在需要的地方调用并实施它们

src={YourImage}

或者在你的 classNames

background-image: `url(${YourImage})`

  1. 在 webpack.config.js 文件的规则部分中从 GitHub 配置项目存储库的路径。

存储库:“https://maikpwwq.github.io/your-repository/”

rules: [ { type: "asset", test: /\.(png|svg|jpg|gif|jpeg)$/i, use: [{ options: { publicPath: '/your-repository/'}, loader: 'file-loader' ]} } ]