Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
471 views
in Technique[技术] by (71.8m points)

javascript - Webpack文件加载器输出[对象模块](Webpack file-loader outputs [object Module])

I am using webpack with HtmlWebpackPlugin , html-loader and file-loader .(我正在将Webpack与HtmlWebpackPluginhtml-loaderfile-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 .(因此,我将HTML代码直接编写到index.html 。) I also use this HTML file as my template in HtmlWebpackPlugin .(我还将这个HTML文件用作HtmlWebpackPlugin模板。)

As all websites do I need to put an image which refers to a PNG in my assets folder.(像所有网站一样,我需要在资产文件夹中放置一个引用PNG的图像。)

file-loader should load the file correctly put the new filename inside the src tag but that is not what is happening.(file-loader应正确加载文件,然后将新文件名放在src标记中,但事实并非如此。) Instead, as the value of src tag, I have [object Module] .(相反,作为src标签的值,我有[object Module] 。) I assume the file-loader emits some object and it is represented like this when its .toString() method is run.(我假设file-loader发出一些对象,并且当其.toString()方法运行时,它像这样表示。) However, I can see that file-loader has processed the file successfully and emitted with new name to the output path.(但是,我可以看到file-loader已经成功处理了文件,并以新名称将其发送到输出路径。) I get no errors.(我没有错误。) Here is my webpack configuration and index.html .(这是我的webpack配置和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:(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:(编辑我的package.json依赖项:)

"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"
  ask by Bora translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Per the file-loader docs :(根据文件加载器文档 :)

By default, file-loader generates JS modules that use the ES modules syntax.(默认情况下,文件加载器会生成使用ES模块语法的JS模块。)

There are some cases in which using ES modules is beneficial, like in the case of module concatenation and tree shaking.(在某些情况下,使用ES模块是有益的,例如在模块串联和摇树的情况下。)

I'm not an expert on this, but 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.(我不是专家,但是webpack似乎将ES模块require()调用解析为一个看起来像这样的对象: {default: module} ,而不是扁平化的模块本身。)

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.(因此, src属性正确解析,您需要能够访问导出模块的default属性。)

If you're using a framework, you should be able to do something like this:(如果您使用的是框架,则应该能够执行以下操作:)
<img src="require('assets/logo.png').default"/>

Alternatively, you can enable file-loader's CommonJS module syntax, which webpack will resolve directly to the module itself.(或者,您可以启用文件加载器的CommonJS模块语法,该webpack将直接解析为模块本身。)

Set esModule:false in your webpack config.(在您的webpack配置中设置esModule:false 。)

webpack.config.js:(webpack.config.js:)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...