Webpack 文件加载器输出 [目标模块] [英] Webpack file-loader outputs [object Module]

查看:30
本文介绍了Webpack 文件加载器输出 [目标模块]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 HtmlWebpackPluginhtml-loaderfile-loader 的 webpack.我有一个简单的项目结构,其中我不使用框架,而只使用打字稿.因此,我将 HTML 代码直接写入 index.html.我也在 HtmlWebpackPlugin 中使用这个 HTML 文件作为我的模板.

与所有网站一样,我需要在我的资产文件夹中放置一个引用 PNG 的图像.file-loader 应该正确加载文件,将新文件名放在 src 标签内,但事实并非如此.相反,作为src 标签的值,我有[object Module].我假设 file-loader 发出一些对象,当它的 .toString() 方法运行时它是这样表示的.但是,我可以看到 file-loader 已成功处理文件并以新名称发送到输出路径.我没有错误.这是我的 webpack 配置和 index.html.

const projectRoot = path.resolve(__dirname, '..');{条目:path.resolve(projectRoot, 'src', 'app.ts'),模式:'生产',输出: {路径:path.resolve(projectRoot, 'dist'),文件名:'app.bundle.js'},解决: {扩展名:['.ts', '.js']},模块: {规则: [{测试:/.html$/i,使用:'html-loader'},{测试:/.(eot|ttf|woff|woff2|svg|png)$/i,使用:'文件加载器'},{测试:/.scss$/i,利用: [{加载器:MiniCssExtractPlugin.loader,选项: {hmr:假的}},{加载器:'css-加载器',选项: {源地图:假}},{loader: 'sass-loader',选项: {源地图:假}}]},{排除:/node_modules/,测试:/.ts$/,使用:'ts-loader'}]},插件: [新的 CleanWebpackPlugin(),新的 HtmlWebpackPlugin({模板:path.resolve(projectRoot, 'src', 'index.html')}),新的 MiniCssExtractPlugin({文件名: '[name].[hash].css',chunkFilename: '[id].[hash].css',忽略顺序:假})]};

index.html:

<html lang="zh-cn"><头><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title></title><body class="dark"><标题><nav class="导航"><div class="left"><img src="assets/logo.png" class="logo"><!-- 这个标志作为[对象模块]输出-->

<div class="right">

</nav></标题>

项目结构:

config/webpack.config.js距离/来源/款式/资产/标志.png索引.html应用程序

编辑我的 package.json 依赖项:

"clean-webpack-plugin": "^3.0.0","css-loader": "^3.2.0","文件加载器": "^5.0.2","html-webpack-plugin": "^3.2.0","mini-css-extract-plugin": "^0.8.0","node-sass": "^4.13.0","sass-loader": "^8.0.0","style-loader": "^1.0.0","ts-loader": "^6.2.1","打字稿": "^3.7.2","webpack": "^4.41.2","webpack-cli": "^3.3.10","webpack-dev-server": "^3.9.0"

解决方案

根据文件加载器 文档:

<块引用>

默认情况下,file-loader 生成使用 ES 模块语法的 JS 模块.在某些情况下,使用 ES 模块是有益的,例如模块串联和摇树的情况.

似乎 webpack 将 ES 模块的 require() 调用解析为如下所示的对象:{default: module},而不是扁平模块本身.这种行为有些争议,在这个问题中进行了讨论.

因此,要让您的 src 属性正确解析,您需要能够访问导出模块的 default 属性.如果您使用的是框架,则应该能够执行以下操作:

<!-- 反应 --><!-- 或 --><img src="require('assets/logo.png').default"/><!-- Vue -->

或者,您可以启用文件加载器的 CommonJS 模块语法,webpack 将直接解析为模块本身.在你的 webpack 配置中设置 esModule:false.

webpack.config.js:

<代码> {测试:/.(png|jpe?g|gif)$/i,利用: [{加载器:'文件加载器',选项: {esModule:假,},},],},

I am using webpack with HtmlWebpackPlugin, html-loader and file-loader. I have a simple project structure in which I use no frameworks, but only typescript. Thus, I write my HTML code directly to index.html. I also use this HTML file as my template in HtmlWebpackPlugin.

As all websites do I need to put an image which refers to a PNG in my assets folder. file-loader should load the file correctly put the new filename inside the src tag but that is not what is happening. Instead, as the value of src tag, I have [object Module]. I assume the file-loader emits some object and it is represented like this when its .toString() method is run. However, I can see that file-loader has processed the file successfully and emitted with new name to the output path. I get no errors. Here is my webpack configuration and index.html.

const projectRoot = path.resolve(__dirname, '..');

{
  entry: path.resolve(projectRoot, 'src', 'app.ts'),
  mode: 'production',
  output: {
    path: path.resolve(projectRoot, 'dist'),
    filename: 'app.bundle.js'
  },
  resolve: {
    extensions: ['.ts', '.js']
  },
  module: {
    rules: [
      {
        test: /.html$/i,
        use: 'html-loader'
      },
      {
        test: /.(eot|ttf|woff|woff2|svg|png)$/i,
        use: 'file-loader'
      },
      {
        test: /.scss$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: false
            }
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: false
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: false
            }
          }
        ]
      },
      {
        exclude: /node_modules/,
        test: /.ts$/,
        use: 'ts-loader'
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: path.resolve(projectRoot, 'src', 'index.html')
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[hash].css',
      chunkFilename: '[id].[hash].css',
      ignoreOrder: false
    })
  ]
};

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
  </head>
  <body class="dark">
    <header>
      <nav class="navigation">
        <div class="left">
          <img src="assets/logo.png" class="logo"> <!-- This logo is output as [object Module] -->
        </div>
        <div class="right">

        </div>
      </nav>
    </header>
  </body>
</html>

Project structure:

config/
    webpack.config.js
dist/
src/
    styles/
    assets/
        logo.png
    index.html
    app.ts

Edit My package.json dependencies:

"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.2.0",
"file-loader": "^5.0.2",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"ts-loader": "^6.2.1",
"typescript": "^3.7.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"

解决方案

Per the file-loader docs:

By default, file-loader generates JS modules that use the ES modules syntax. There are some cases in which using ES modules is beneficial, like in the case of module concatenation and tree shaking.

It seems that webpack resolves ES module require() calls to an object that looks like this: {default: module}, instead of to the flattened module itself. This behavior is somewhat controversial and is discussed in this issue.

Therefore, to get your src attribute to resolve correctly, you need to be able to access the default property of the exported module. If you're using a framework, you should be able to do something like this:

<img src={require('assets/logo.png').default}/> <!-- React -->
<!-- OR -->
<img src="require('assets/logo.png').default"/> <!-- Vue -->

Alternatively, you can enable file-loader's CommonJS module syntax, which webpack will resolve directly to the module itself. Set esModule:false in your webpack config.

webpack.config.js:

 {
        test: /.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              esModule: false,
            },
          },
        ],
      },

这篇关于Webpack 文件加载器输出 [目标模块]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆