Skip to content

Webpack 4.0 file-loader json issue #6586

Closed

Description

@sergey-shpak

Do you want to request a feature or report a bug?
Bug.

What is the current behavior?
JSON parse error (' Unexpected token m in JSON at position 0') after file-loader plugin handles json files.

If the current behavior is a bug, please provide the steps to reproduce.

entry:{
  '0': './manifest.json'
}
//...
module: {
  rules:[{
    test: /\.(json|html)/,
    exclude: /(node_modules|bower_components)/,
    use: [{
      loader: 'file-loader',
      options: { name: '[name].[ext]' },
    }],
  }]
}

What is the expected behavior?
Loading json files and no errors.

If this is a feature request, what is motivation or use case for changing the behavior?

Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.
node v8.9.4, webpack 4.0.1, Ubuntu 16.04

Activity

  1. michael-ciniawsky commented on Feb 26, 2018

    @michael-ciniawsky
    Contributor

    You don't need any loader for .json anymore (since webpack >= v2.0.0). webpack >= v4.0.0 introduced Module.type and JSON got it's own module.type = 'json' (It doesn't get parsed by the JS Parser anymore). Either remove json from Rule.test or explicitly set the Rule.type to another Module.type e.g type = 'javascript/auto'

    webpack.config.js

    module: {
      rules:[{
    +   type: 'javascript/auto',
        test: /\.(json|html)/,
        exclude: /(node_modules|bower_components)/,
        use: [{
          loader: 'file-loader',
          options: { name: '[name].[ext]' },
        }],
      }]
    }

    or

    webpack.config.js (recommended)

    module: {
      rules:[{
    -   test: /\.(json|html)/,
    +   test: /\.html/,
        exclude: /(node_modules|bower_components)/,
        use: [{
          loader: 'file-loader',
          options: { name: '[name].[ext]' },
        }],
      }]
    }
  2. enjikaka commented on Feb 27, 2018

    @enjikaka

    @michael-ciniawsky webpack-contrib/file-loader#259

    Seems like Webpack 4 is not ignoring JSON loaded by other loaders?

  3. Acanthostega commented on Mar 1, 2018

    @Acanthostega

    In fact this is a problem when we do not want to bundle the JSON files for nodejs bundle (target="node").

    For example, I have a situation where I need to do the bundle of a nodejs application. Some part of this application need to have access to a large number of JSON files containing large data. Thus requiring those files include them in the bundle but their size is too important and webpack crashes because of missing memory.

    So I want to use file-loader on some specific json files to put them on the output directory of the bundle, with an hashed name and then read and parse the file with fs to access the content of the JSON files,without bundling, and keeping the hash name functionality to not expose the JSON directory structure on the output directory that will be provided to other people.

    I do not see a way to pass the type="javascript/auto" in an inline loader (require("file-loader!file.json")) that will allow me to keep my build working. If webpack in version 4 doen't try to parse a JSON file when using a loader on it as for version 3, the problem will be solved.

  4. rustam-gaifiev commented on Mar 5, 2018

    @rustam-gaifiev

    have the same issue

    import '!file-loader?name=[name].[ext]!./manifest.json';
    import 'file-loader?name=[name].[ext]!./.htaccess';

  5. omichelsen commented on Mar 6, 2018

    @omichelsen

    I have to echo that this is not solved and the suggested code change does not achieve the same thing.

    The goal is to take a manifest.json and copy it to the output dir (perhaps hashed), and get a URL for it with file-loader. Using built in json parsing I don't see how we can achieve this? I don't want the JSON inlined in my output/bundle, and I want to control the file name that it is assigned.

    My current setup is using https://github.com/markdalgleish/web-app-manifest-loader with file-loader to further resolve some image paths in the manifest itself. If you have a better suggestion I am all ears :-)

  6. differentsmoke commented on Mar 7, 2018

    @differentsmoke

    I believe the actual problem was not properly understood. The problem is not loading JSON into your bundle, but rather loading JSON as a separate file that will be added to the output directory. Is there another way to achieve this on Webpack 4? If not, this should probably remain open.

    EDIT: after fixing some unrelated issue, yes, adding type = 'javascript/auto' did exactly what I was expecting.

  7. sergey-shpak commented on Mar 12, 2018

    @sergey-shpak
    Author

    adding type = 'javascript/auto' or using copy-webpack-plugin solves the problem (in my case)

  8. enjikaka commented on Mar 12, 2018

    @enjikaka

    I also ended up using copy-webpack-plugin instead.

  9. Tatsujinichi commented on Mar 27, 2018

    @Tatsujinichi

    @michael-ciniawsky This is a problem for me as well, for example I need to replace text in JSON files before they are packed. But more importantly, I need Webpack to package those references. They are atlas json files, they contain file paths used by PIXIJS. References to images that otherwise will not be packed.

  10. vsaarinen commented on Mar 28, 2018

    @vsaarinen

    I'm still having trouble with this. Here's my situation:

    My project has a bunch of JSON files. Most of the files I want to import directly as objects (i.e. what json-loader and Webpack 4 do), but since a few of them are very large, I want to import them using file-loader and fetch the JSON files dynamically when the app runs.

    Previously, this worked fine by doing require('file-loader!!../path/to/large-file.json') for the large files. Since upgrading to Webpack 4, however, doing this produces the same error as described in the OP.

    Based on the discussion in this issue, I tried to get around the problem by adding the following to the rules section of my Webpack config file:

      {
        test: /\.json/,
        type: 'javascript/auto',
        use: [require.resolve('json-loader')],
      },
    

    Now I no longer get an error at build time, but run into a new problem: the emitted (large) JSON files now contain the following content:

    module.exports = { <json content> }
    

    Trying to fetch and parse these as JSON files obviously doesn't work.

    The only way I've gotten this situation to work is by renaming my large JSON files to some other extension than JSON, but that's quite an ugly hack. What's the recommended solution to this situation?

  11. differentsmoke commented on Mar 28, 2018

    @differentsmoke

    Please note that the examples that have worked here are using "file-loader" and NOT "json-loader".

  12. vsaarinen commented on Mar 28, 2018

    @vsaarinen

    Alright. So do I have to change my default loader to be file-loader, and then override it with require('json-loader!../data/smaller-file.json') when I do want to import the contents of the JSON file?

  13. vsaarinen commented on Mar 28, 2018

    @vsaarinen

    I tried that approach but am still unable to load some of my JSON files using file-loader and some using json-loader/Webpack's native JSON importing – I get the same error as the OP for files that I tried importing with require('json-loader!../data/smaller-file.json').

    The only thing that has worked so far is renaming the extension of the JSON files that I want to load using file-loader.

  14. differentsmoke commented on Mar 28, 2018

    @differentsmoke

    Sorry, I have a lot of questions about your code, and I'm also not really an expert, but I would suggest using StackOverflow to answer your question since it seems to be more specific to your code than related to the overall issue.

  15. akoliyot commented on Apr 7, 2018

    @akoliyot

    I was able to copy my .json config file to the build folder using this:

    {
        type: 'javascript/auto',
        test: /\.json$/,
        use: [
            {
              loader: 'file-loader',
              options: {
                  name: "./plugin-config/[name].[ext]"
              }
            }
        ]
    }
    
  16. pristas-peter commented on Apr 26, 2018

    @pristas-peter

    If someone needs different solution, just rename the .json to another extension and it will work.

  17. johnsanthosh commented on May 8, 2018

    @johnsanthosh

    @differentsmoke @enjikaka @sergey-shpak @michael-ciniawsky @pristas-peter

    Unexpected behavior while using file-loader with webpack to load large json files ( > 140 MB )

    Stack Overflow Link

  18. the-simian commented on May 27, 2018

    @the-simian

    Has anyone figured out a way to willfully bypass the native json loader so that we may define a partifular pipeline?

  19. lecstor commented on Jun 20, 2018

    @lecstor

    @the-simian adding type: 'javascript/auto' to my json loader rule (as mentioned by @akoliyot 👍) fixed this for me.

                {
                  type: "javascript/auto",
                  test: /locale\/.+\.json/,
                  loader: require.resolve("@lingui/loader")
                },
    

    the closest I found to an explanation was https://scotch.io/tutorials/whats-new-in-webpack-4

    javascript/auto used to be the default module in webpack 3 but webpack 4 completely abstracted the JavaScript specificity from the code base to allow for this change so that users can specify the kind of module they want.

  20. blachawk commented on Mar 3, 2019

    @blachawk

    Thank you @akoliyot for that solution with file-loader. I have it working on my end.

  21. marigerr commented on May 4, 2019

    @marigerr
  22. elgs commented on May 3, 2020

    @elgs

    Just to be clear, you still need the file-loader to load JSON, is it correct?

  23. panlina commented on Jun 16, 2021

    @panlina

    So there's no way to workaround it for inline loader? Since there's no way to set type: "javascript/auto" on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions