2

I'm developing a react UI component and it depends on another UI component (react-widgets/lib/DropDownlist). This javascript module has resources that end with these file extensions: *.gif, *.eot, *.svg, *.woff, *.ttf.

Webpack4 is complaining that it doesn't know how to process these file types and that I might need a loader to handle these file type. One error is:

Error in .../react-widgets/dist/fonts/rw-widgets.svg?v=4.1.0
Module parse failed: ...
**You may need an appropriate loader to handle this file type.**

So I need to update my webpack.config.js file with the appropriate loaders for those file types. My config is based off of this. Side Note: A shout out goes to Mark England who wrote this article which does a fantastic job for how to create a reusable component.

The relevant snippet is:

// Snippet from Mark's code webpack.config.js
 module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
},

I know what the syntax for webpack is to define the loaders but I don't know what loaders to use. But this sample webpack config file didn't include support for these other file types.

What have I done to try and solve the problem

  • I generally use create-react-app so I avoid this problem altogether. :-) It, however, doesn't allow me to create react libraries for distribution (AFAIK).

  • First I searched on the net webpack *.gif loader. Nothing useful.

  • Next I searched for webpack loaders based on file type. This gave some good results that describe the loader syntax, pointed me to some loaders file-loader and how to use them, and this question on SO that helps me realize the *.svg loader might be what I need to load svg files.

{test: /\.svg$/, use: "svg-inline-loader"},

So I might be able to use svg-inline-loader for the *.svg files. I can repeat this approach for all of the file types.

The next approach is to examine Create React App (CRA)

I primarily develop in react, and look at the CRA webpack config files (because the create-react-app appears to stay leading edge on these topic). So I can see the url-loader is used for images (based on what the node_modules/react-scripts/config/webpack.config.dev.js file is using).

Another one down...

My question

Does webpack (or another website) have a table that lists the loaders available for given file types?

For example, know good image loaders for the following file types are:

Webpack 4
*.gif, *.jpg => url-loader
*.svg => svg-inline-loader
*.eot => ???

I realize that because webpack is more of a plugin/loader architecture that it might not be webpacks place to have this list so another website might need to have it.

When you need a loader what do you do? If there is no central place to look for this answer, then please share how you find loaders that are needed to solve your webpack file loading problem.

PatS
  • 8,833
  • 12
  • 57
  • 100
  • 1
    Did you try the `file-loader`? https://github.com/webpack-contrib/file-loader – Nour May 25 '18 at 20:59
  • 1
    Webpack compiles code; you don't want to compile gifs or any other image files. So your problem is different. I'm not posting this an answer but only as a something to look at. I think you may need to use a 'noparse' directive for the DropDownList component. A snippet that I use may be helpful may be not.... loaders: [{ Your loaders here }], noParse: /(DropDownlist)\.js$/ } ... Some version of this, maybe is where you need to be. I do know Webpack should not be compiling the image files, so that's a thread to follow, a place to start. Good luck. – Elvn May 25 '18 at 21:31

1 Answers1

6

It all depends on your workflow, how u want to load assets at run-time.

For eg, if u have lot of images, it might be a good idea to use a file-loader and place them directly inside the build directory.

The above approach will increase the GET calls and the bundled js file size will not be affeted

If u have less images/small size images then you can use url-loader which converts them into data-URL and put them inside your bundled js files.

The above approach will reduce the GET calls and will slightly increase the bundled js size.

If u want combination of both, then u can set a size limit and fallback loader(file-loader) on url-loader. What this will do is, the size of the dataURL will be calculated.If the size is grater than the limit, the file-loader will be used, which will place it in the build directory.

How I use them

  {
    test: /\.(png|jpg|gif)$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          outputPath: 'images/',
          name: '[name][hash].[ext]',
        },
      },
    ],
  },
  {
    test: /\.(svg)$/,
    exclude: /fonts/, /* dont want svg fonts from fonts folder to be included */
    use: [
      {
        loader: 'svg-url-loader',
        options: {
          noquotes: true,
        },
      },
    ],
  },
  {
    test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
    exclude: /images/,  /* dont want svg images from image folder to be included */
    use: [
      {
        loader: 'file-loader',
        options: {
          outputPath: 'fonts/',
          name: '[name][hash].[ext]',
        },
      },
    ],
  }
Gautam Naik
  • 8,990
  • 3
  • 27
  • 42
  • Your solution worked. I incorrectly thought that webpack only ```copied modules``` to the destination bundle, and did not parse them and did not need loaders for the files in the node_modules folder. This was just plain wrong. Once I referenced ```react-widgets/dist/css/react-widgets.css```, I had to define a CSS loader and allow webpack to parse that file. And because that file referenced other files, I had to provide loaders for those other file types as well. Lesson learned is _sometimes_ webpack does need to parse/process/load files that are in the node_modules directory. – PatS Jun 04 '18 at 20:43