Webpackファイルローダー出力[オブジェクトモジュール]


40

でwebpackを使用しています HtmlWebpackPluginhtml-loaderfile-loader。フレームワークを使用せず、typescriptのみを使用する単純なプロジェクト構造があります。したがって、HTMLコードを直接に記述しindex.htmlます。また、このHTMLファイルをのテンプレートとして使用していますHtmlWebpackPlugin

すべてのWebサイトと同じように、PNGを参照する画像をアセットフォルダーに配置する必要があります。file-loader新しいファイル名をsrcタグ内に正しく配置してファイルをロードする必要がありますが、それは何が起こっているのかではありません。代わりに、srcタグの値として、があります[object Module]。私は、file-loaderいくつかのオブジェクトを放出し、その.toString()メソッドが実行されると、このように表されると想定しています。ただし、file-loaderファイルが正常に処理され、新しい名前で出力パスに出力されたことがわかります。エラーは発生しません。これが私の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:

<!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>

プロジェクトの構造:

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

私の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"

回答:


70

ファイルローダーのドキュメントごとに:

デフォルトでは、ファイルローダーはESモジュールの構文を使用するJSモジュールを生成します。モジュールの連結やツリーの揺れのように、ESモジュールの使用が有益な場合があります。

webpackはESモジュールのrequire()呼び出し{default: module}を、フラット化されたモジュール自体ではなく、次のようなオブジェクトに解決するようです。この振る舞いはやや物議を醸すものであり、この問題で議論されています。

したがって、src属性を正しく解決するにdefaultは、エクスポートされたモジュールのプロパティにアクセスできる必要があります。フレームワークを使用している場合は、次のようなことができるはずです。

<img src="require('assets/logo.png').default"/>

または、ファイルローダーのCommonJSモジュール構文を有効にすることもできます。これにより、webpackはモジュール自体に直接解決します。セットするesModule:falseウェブパックのでします。

webpack.config.js:

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

うまくいきました。しかし、それはまだ少し魔法です。なぜこれが当てはまるのかについて考えがある場合は、回答でも説明できますか?ありがとう。
ボラ

@Bora-​​もう少し調査し、回答を更新しました。
stellr42

おかげで、これはまさに私が必要とするものです
Matan Tubul

これはからのアップデート中に私をビットAngular 8Angular 9もたらしたものとしてfile-loaderのバージョンから4.2.06.0.0require(...).default私のためにそれを使用して修正しました。
ebhh2001

8

構成esModule: falseにおける@ stellr42の推奨修正は、現時点でのfile-loader最善の回避策です。

ただし、これは実際には、httpshtml-loader//github.com/webpack-contrib/html-loader/issues/203で追跡されているバグです

これは、ESモジュールのサポートが追加されたように見えるfile-loadercss-loaderと他の友人が、html-loader見落とされてました。

このバグが修正されたら、削除esModule: falseしてアップグレードすることをお勧めしますhtml-loader、ESモジュールにはいくつかの小さな利点があるため(ドキュメントで説明されているように)、。

または、(私のように)HTMLからではなくCSSから画像ロードするときに問題が発生したためにこの問題が見つかった場合はcss-loader、ESモジュールを無効にする必要はなく、アップグレードするだけです。


2

これはファイルローダーバージョン5.0.2で発生し、以前のバージョンはdefaultプロパティを呼び出さなくても正常に動作します


0

ファイルローダーを^ 5.0.2分前に更新しました。

esModule: falseは提案された修正を知っていましたが、それは私にとってはうまくいきませんでした。

私の修正は<img src={require('assets/logo.png').default}/>どちらが奇妙だったかでした。初めて使用しました.defaultが、うまくいきました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.