webpack4无法编译所有的HTML文件?

6

我最初并没有正确理解问题的本质,我修改了问题,以更准确地阐述问题...

有这样一个webpack的组件:

'use strict';
const webpack = require('webpack');
const path = require('path');
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');


const minimizerBlock = {
  minimizer: [
    new UglifyJsPlugin({
      uglifyOptions: {
        warnings: false,
        parse: {},
        compress: {},
        mangle: true,
        output: null,
        toplevel: false,
        nameCache: null,
        ie8: false,
        keep_fnames: false,
      },
    }),
    new OptimizeCSSAssetsPlugin({})
  ]
}

const config = {
  entry: {
    main: './frontend/src/index.js'
  },
  output: {
    path: path.resolve(__dirname, './public'),
    filename: 'main.js'
  },
  devServer: {
    contentBase: path.join(__dirname, 'public'),
    port: 8888,
    overlay: true,
    proxy: {
      '/api': 'http://localhost:8889'
    }
  },
  module: {
    rules: [{
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"]
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      },
      {
        test: /\.sass$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      },
      //{ test: /\.(ttf|eot|woff|woff2|png|jpg|jpeg|svg|gif|webp)$/, loader: 'url-loader', },
      {
        test: /\.(png|jpg|jpeg|svg|gif|webp)$/,
        include: [
          path.resolve(__dirname, './frontend/binary/image/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: 'image/[name].[ext]',
          }
        }]
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        include: [
          path.resolve(__dirname, './frontend/binary/fonts/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: 'fonts/[name].[ext]',
          }
        }]
      },
      {
        test: /\.(mp3)$/,
        include: [
          path.resolve(__dirname, './frontend/binary/audio/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: 'audio/[name].[ext]',
          }
        }]
      },
      {
        test: /\.(html)$/,
        include: [
          path.resolve(__dirname, './frontend/pages/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]',
          }
        }]
      },
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: './index.css',
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'frontend/src/', 'template.html'),
      filename: 'index.html',
      favicon: 'frontend/binary/image/icons/iconfinder_tech_0001_4023871.png',

    }),

  ]
};
module.exports = (env, options) => {
  let production = options.mode == 'production';
  config.devtool = production ? false : 'inline-cheap-module-source-map';
  config.optimization = production ? minimizerBlock : {};
  return config;
}

有一个“src”文件夹-“template.html”文件,其中包含布局的这一部分。

该布局如下:

 <div id="root">
   <img src="${require(`../binary/image/icons/iconfinder_tech_0001_4023871.png`)}" alt="" />
</div>

在编译后,webpack将其转化为位于公共文件夹中的index.html文件,我得到了以下结果

<div id="root">
  <img src="images/iconfinder_tech_0001_4023871.png" alt="" />
</div>

它能够工作。

与此同时,src 下有一个文件夹 pages 包含不同的页面,在这些页面中有相同的排版。

<header>
   <img src="${require(`../../../../binary/image/sheelak/0viber-image.jpg`)}" alt=""/>
</header>

运行webpack后,会创建一个包含以下文件的文件夹,这是结果:

 <header>
   <img src="${require(`../../../../binary/image/sheelak/0viber-image.jpg`)}" alt=""/>
</header>

然后是关于在header中使用imgrequire不起作用的问题。

会出现错误。

告诉我我的webpack有什么问题?

项目链接


仍然遇到问题吗? - abestrad
Abestrad,是的,我还没有解决这个问题。 - Air
6个回答

2
你应该使用启用了 interpolate 标志的 html-loader

最初的回答

       {
            test: /\.(html)$/,
            include: [
                path.resolve(__dirname, './frontend/pages/')
            ],
            use: [
                {
                    loader: 'file-loader'
                },
                {
                    loader: 'extract-loader'
                },
                {
                    loader: 'html-loader',
                    options: {
                        interpolate: true,
                    }
                }
            ],
            exclude: [
                path.resolve(__dirname, 'frontend/src/', 'template.html')
            ]
        }

我已经创建PR来解决你的问题:https://github.com/sarnor/club/pull/1
另外请注意,当你可以直接写图像源时,插值是丑陋的:<img src="../../image/icons/iconfinder_tech_0001_4023871.png"
还要注意,你的相对URL指向错误的目录,你的URL中缺少../

@Air 我很高兴能够帮助。warmatebebi ^_^ - karaxuna
Shenc gisurveb warmatebebs...) - Air
嗨,你可以看一下这个问题...也许你能提供帮助。https://stackoverflow.com/questions/67999709/build-angular-12-without-angular-cli-on-webpack-5 - Air

0

你能从配置文件中删除下面这行并检查一下吗?

favicon: 'frontend/binary/image/icons/iconfinder_tech_0001_4023871.png'

0

你的问题不在于加载器,而是你使用模板字面量的方式。反引号需要包裹${}

<div id="root">
   <img src=`${require("../binary/image/icons/iconfinder_tech_0001_4023871.png")}` alt="" />
</div>

同样地,你会有

<header>
   <img src=`${require("../../../../binary/image/sheelak/0viber-image.jpg")}` alt=""/>
</header>

0
要在您的HTML文件模板中使用require,您需要为.html文件包含html-loader,同时您已经为其使用了file-loader,这可能已经完成。
因此,webpack配置应该类似于:
{
  test: /\.(html)$/,
  include: [
    path.resolve(__dirname, './frontend/pages/')
  ],
  use: [{
    loader: 'html-loader',
    options: {
      name: '[path][name].[ext]',
      attrs: [':data-src']
    }
  }]
}


{
  test: /\.(png|jpg|jpeg|svg|gif|webp)$/,
  include: [
    path.resolve(__dirname, './frontend/binary/image/')
  ],
  use: [{
    loader: 'file-loader',
    options: {
      name: 'image/[name].[ext]',
    }
  }]
}

然后使用 img标签中require,如下所示:

更多关于这个链接的信息


我已经尝试过了,但返回的结果是 module.exports = "<div class=\"slider\">\r\n\t <img src=\"${require(\../../binary/image/background/city_white_black_5.jpg`)}" width="50" height="50" alt="" />\r\n\t \r\n</div>";` 我不知道该怎么处理它。 - Air
@Air,我在我的Mac电脑上克隆并运行了你的项目,一切都很顺利,没有出现404错误。你能告诉我具体是什么问题吗? - Gaurav Saraswat
抱歉,我忘记更新代码库了。你可以再试一次。 - Air

0

如果你想知道什么时候使用哪个加载器,请参考:

https://webpack.js.org/loaders/

(Webpack) 使用 url-loader 或 file-loader,我是否真的需要在我的 .js 文件中为每个静态图像都包含一个 require() 语句?

对于图片,我认为 url-loader 是不错的选择,因为它可以将 base-64 编码的图像链接渲染成图像。

尝试一下:

            {
                test: /\.(jpg|png|gif|eot|woff2|woff|ttf|ico|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: ["url-loader?limit=100&name=static/[name]_[hash].[ext]"]
            }

它会做什么?它将接受任何类型的文件jpg|png|gif|eot|woff2|woff|ttf|ico|svg并发射到文件夹static(也可以是任何名称,可选)并添加哈希到名称。它不仅会发射图像和字体,还会将任何文件的大小限制为100 kb,并在每次更改静态资源的名称时添加唯一哈希,确保具有相同名称的图像的任何更改也会刷新缓存。


url-loader与此问题无关。 - Air

0

你正在使用file-loader处理你的HTML文件,我认为它不会尝试解析文件内部的任何内容,而只是将其复制到输出文件夹中。

我建议尝试改用html-loader,看看是否可以解决问题。

特别是,你需要更改这个部分:

{
  test: /\.(html)$/,
  include: [
    path.resolve(__dirname, './frontend/pages/')
  ],
  use: [{
    loader: 'file-loader',
    options: {
      name: '[path][name].[ext]',
    }
  }]
}

看起来像这样:

{
  test: /\.(html)$/,
  include: [
    path.resolve(__dirname, './frontend/pages/')
  ],
  use: [{
    loader: 'html-loader',
    options: {
      name: '[path][name].[ext]',
    }
  }]
}

并可能使用以下命令安装html-loader:

npm i -D html-loader

我已经做了这件事了... 接下来,我有一个名为“JS”的脚本,它导入这些“HTML”文件,但如果我添加“html-loader”导入就不会发生。 - Air
我不太明白重点在哪里。我想要理解,而不是要现成的例子。我喜欢了解我正在做什么。我应该在file-loader中使用html-loader吗? - Air

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