वेबपैक फ़ाइल-लोडर आउटपुट [ऑब्जेक्ट मॉड्यूल]


40

मैं वेबपैक का उपयोग कर रहा हूं HtmlWebpackPlugin, html-loaderऔर file-loader। मेरे पास एक सरल परियोजना संरचना है जिसमें मैं कोई रूपरेखा का उपयोग नहीं करता, लेकिन केवल टाइपस्क्रिप्ट। इस प्रकार, मैं सीधे अपना HTML कोड लिखता हूं index.html। मैं इस HTML फ़ाइल को अपने टेम्पलेट के रूप में भी उपयोग करता हूं HtmlWebpackPlugin

जैसा कि सभी वेबसाइटों को मुझे एक छवि डालने की आवश्यकता है जो मेरे संपत्ति फ़ोल्डर में पीएनजी को संदर्भित करता है। file-loaderफ़ाइल को सही तरीके से लोड करना चाहिए ताकि srcटैग के अंदर नया फ़ाइल नाम रखा जा सके लेकिन ऐसा नहीं हो रहा है। इसके बजाय, srcटैग के मूल्य के रूप में , मेरे पास है [object Module]। मैं file-loaderकिसी वस्तु को उत्सर्जित करता हूं और इसे इस तरह से प्रस्तुत किया जाता है जब इसकी .toString()विधि चलाई जाती है। हालाँकि, मैं देख सकता हूँ कि file-loaderफ़ाइल को सफलतापूर्वक संसाधित किया गया है और आउटपुट पथ पर नए नाम के साथ उत्सर्जित किया गया है। मुझे कोई त्रुटि नहीं है। यहाँ मेरा वेबपैक विन्यास और है 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

मेरा पैकेज संपादित करें । संदेश निर्भरताएँ:

"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

फ़ाइल लोडर डॉक्स के अनुसार :

डिफ़ॉल्ट रूप से, फ़ाइल-लोडर जेएस मॉड्यूल उत्पन्न करता है जो ईएस मॉड्यूल सिंटैक्स का उपयोग करता है। ऐसे कुछ मामले हैं जिनमें ईएस मॉड्यूल का उपयोग करना फायदेमंद है, जैसे कि मॉड्यूल कंक्रीटिंग और ट्री शेकिंग के मामले में।

ऐसा लगता है कि वेबपैक ईएस मॉड्यूल require()कॉल को एक वस्तु के रूप में हल करता है जो इस तरह दिखता है: {default: module}चपटा हुआ मॉड्यूल के बजाय। यह व्यवहार कुछ हद तक विवादास्पद है और इस मुद्दे पर चर्चा की गई है ।

इसलिए, अपनी srcविशेषता को सही ढंग से हल करने के लिए, आपको defaultनिर्यात किए गए मॉड्यूल की संपत्ति तक पहुंचने में सक्षम होने की आवश्यकता है । यदि आप एक रूपरेखा का उपयोग कर रहे हैं, तो आपको ऐसा कुछ करने में सक्षम होना चाहिए:

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

वैकल्पिक रूप से, आप फ़ाइल-लोडर के कॉमनजेएस मॉड्यूल सिंटैक्स को सक्षम कर सकते हैं, जो वेबपैक सीधे मॉड्यूल को ही हल करेगा। esModule:falseअपने वेबपैक कॉन्फ़िगरेशन में सेट करें ।

webpack.config.js:

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

वह काम किया। हालांकि यह अभी भी थोड़ा सा जादू है। यदि आपके पास इस बारे में विचार हैं कि ऐसा क्यों है तो क्या आप इसे अपने उत्तर में भी समझा सकते हैं? धन्यवाद।
बोरा

@ बोरा - थोड़ा और शोध और अद्यतन जवाब दिया।
stellr42

धन्यवाद, यह वही है
जिसकी

इस से एक अद्यतन के दौरान मेरे थोड़ा Angular 8के Angular 9रूप में है कि लाया file-loaderसंस्करण से 4.2.0करने के लिए 6.0.0require(...).defaultमेरे लिए यह तय का उपयोग करना ।
ebhh2001

8

@ stellr42 esModule: falseआपके file-loaderकॉन्फ़िगरेशन में सुझाए गए फिक्स वर्तमान समय में सबसे अच्छा समाधान है।

हालाँकि, यह वास्तव में एक बग है html-loaderजिसमें यहां ट्रैक किया जा रहा है: https://github.com/webpack-contrib/html-loader/issues/203

ऐसा लगता है कि ES मॉड्यूल समर्थन की तरह करने के लिए जोड़ा गया है file-loader, css-loaderऔर अन्य मित्र, लेकिन html-loaderयाद किया गया था।

एक बार यह बग ठीक हो जाने के बाद, इसे हटाना esModule: falseऔर सरलता से अपग्रेड करना बेहतर होगा html-loader, क्योंकि ES मॉड्यूल कुछ मामूली लाभ प्रदान करता है (जैसा कि डॉक्स में उल्लिखित है )

वैकल्पिक रूप से, यदि (मेरी तरह), तो आपको यह समस्या इसलिए मिली क्योंकि आपको CSS (HTML से) के बजाय एक छवि लोड करने में समस्या हो रही थी , तो यह सुधार सिर्फ अपग्रेड करने के लिए है css-loader, ES मॉड्यूल को अक्षम करने की आवश्यकता नहीं है।


2

यह फ़ाइल-लोडर संस्करण 5.0.2 पर होता है, पूर्व संस्करण defaultसंपत्ति को कॉल किए बिना ठीक काम करता है


0

बस मेरी फ़ाइल-लोडर को ^ 5.0.2 मिनट पहले अपडेट किया गया।

मुझे पता है esModule: falseकि सुझाया गया फिक्स था लेकिन यह मेरे लिए काम नहीं करता था।

मेरा फिक्स <img src={require('assets/logo.png').default}/>जो अजीब था। पहली बार उपयोग करते हुए .defaultलेकिन यह काम किया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.