Skip to content
This repository was archived by the owner on Mar 17, 2021. It is now read-only.
This repository was archived by the owner on Mar 17, 2021. It is now read-only.

file-loader fails with JSON files in Webpack 4 #259

Closed

Description

@enjikaka

Using import 'file-loader!./manifest.json'; fails with;

Module parse failed: Unexpected token m in JSON at position 0
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token m in JSON at position 0
    at JSON.parse (<anonymous>)
    at JsonParser.parse (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/webpack/lib/JsonParser.js:15:21)
    at doBuild.err (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/webpack/lib/NormalModule.js:367:32)
    at runLoaders (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/webpack/lib/NormalModule.js:264:12)
    at /Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:370:3
    at iterateNormalLoaders (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:211:10)
    at iterateNormalLoaders (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:218:10)
    at /Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:233:3
    at runSyncOrAsync (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:130:11)
    at iterateNormalLoaders (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:229:2)
    at Array.<anonymous> (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/loader-runner/lib/LoaderRunner.js:202:4)
    at Storage.finished (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:43:16)
    at provider (/Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:79:9)
    at /Users/jeremy/Documents/Development/webpack-file-loader-test/node_modules/graceful-fs/graceful-fs.js:78:16
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:505:3)

Minimal reproducible setup: https://ipfs.io/ipfs/QmPfPq71WD3H6RrcCu1y72FswF8zC3f43aU8FPv5ZwS2ea

Activity

  1. enjikaka commented on Feb 27, 2018

    @enjikaka
    Author

    I assume this is related to webpack 4 now handling JSON loading natively

  2. alexander-akait commented on Feb 27, 2018

    @alexander-akait
    Member

    @enjikaka seems bug in webpack@4, he should ignore .json files which loaded other loaders

  3. alexander-akait commented on Feb 27, 2018

    @alexander-akait
    Member

    @webpack-bot move to webpack/webpack

  4. michael-ciniawsky commented on Feb 27, 2018

    @michael-ciniawsky
    Member

    @see webpack/webpack#6586. Why is the file-loader even needed here ? Either explicitly add the type to the rule in webpack.config.js or use a different extname for inline usage (e.g x.manifest). The inline loader syntax is discouraged for a while now and it would even work in case x-loader supports module.type = 'json'.

  5. joelcollyer commented on May 24, 2018

    @joelcollyer

    For anyone who's encountering the error Module parse failed: Unexpected token m in JSON at position 0 like I was, and you find this thread, you don't need to specify that json files be loaded in any special way.

    Simply require your files like this:

    const langFile = require('./locale/en/lang.json');
    

    Webpack 4.x will do the rest.

    No special tests, configuration, or loaders are needed for .json to be required in your JavaScript.

  6. rlefever68 commented on Jun 7, 2018

    @rlefever68

    Please check the encoding of your .json file.
    It is probably 'UTF-8 with BOM'.
    Resave the file with pure 'UTF-8' and it should be solved.

  7. 1 remaining item

  8. BobbyBabes commented on Jul 6, 2018

    @BobbyBabes

    @joelcollyer The only problem with using require() to read JSON files, is that the file will be cached. Unless it's deleted from require()'s cache.

  9. joelcollyer commented on Jul 6, 2018

    @joelcollyer

    @BobbyBabes: I fully agree; it'd be best to fetch json with an async request most of the time.

    In this case we were loading a mandatory language file, so the require isn't so bad. If you try to do that with an import tree shaking gets in the way and the file isn't loaded.

    My point was mostly that no webpack configuration is required for it to understand the loading of a json file (unlike the additional configuration you'd have to do for say, sass, or jsx loading).

  10. crloshro commented on Oct 27, 2018

    @crloshro

    @joelcollyer thank you so much, that tip helped me to fix the bug!

  11. naretini commented on Feb 14, 2019

    @naretini

    In my package.json I have:
    "scripts":{ ... "build-mydir01": "webpack --env.ext mydir01 --mode production ./code/mydir01/index.js --output ./public/mydir01/main.js", ... }

    In my webpack.config.js:
    `
    const HtmlWebPackPlugin = require("html-webpack-plugin");

    module.exports = function (env) {
    console.log(env, env);
    const ext = env.ext || 'src';

    const ext_file = require('./code/' + ext + '/extension.json');
    
    return {
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: {
                        loader: "babel-loader"
                    }
                },
                {
                    test: /\.(json)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {},
                        },
                    ],
                },
                {
                    test: /\.(html)$/,
                    use: [
                        {
                            loader: "html-loader"
                        }
                    ]
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: `./code/${ext}/index.html`,
                filename: "./index.html"
            })
        ]
    }
    

    };
    `

    After executing:

    npm run build-mydir01

    In my ./public/mydir01/ i see index.html and main.js but extension.json is not moved there....
    What do I miss?

  12. blachawk commented on Mar 3, 2019

    @blachawk

    Is there any official documentation on how to output JSON files to my /dist folder with Webpack 4?

    Simply adding const langFile = require('./locale/en/lang.json'); to my webpack.config.js file does not tell me much or do much for me with Webpack 4. I still encounter the same error.

  13. garkin commented on Oct 14, 2019

    @garkin

    Correct way to use file-loader with JSON in Webpack 4+:

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    },
  14. zaitebaki commented on Oct 16, 2019

    @zaitebaki

    Correct way to use file-loader with JSON in Webpack 4+:

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    },

    best wishes, you awesome :)))
    With saving path:

          {
            test: /\.json$/,
            loader: 'file-loader',
            type: 'javascript/auto',
            options: {
              name() {
                return '[path][name].[ext]';
              },
            },
          }
  15. Garwin4j commented on Oct 27, 2019

    @Garwin4j

    Correct way to use file-loader with JSON in Webpack 4+:

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    },

    best wishes, you awesome :)))
    With saving path:

          {
            test: /\.json$/,
            loader: 'file-loader',
            type: 'javascript/auto',
            options: {
              name() {
                return '[path][name].[ext]';
              },
            },
          }

    So I do this, the project build and loads, but it seem the JSON import is undefined like it isn't ready the JSON. is anyone else getting this? Does your application still recognize the JSON values after doing tihs.

  16. kevinlabx commented on Jan 6, 2020

    @kevinlabx

    Correct way to use file-loader with JSON in Webpack 4+:

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    },

    @garkin
    Thank you this actually works.

  17. stories2 commented on Mar 5, 2020

    @stories2

    Correct way to use file-loader with JSON in Webpack 4+:

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    },

    best wishes, you awesome :)))
    With saving path:

          {
            test: /\.json$/,
            loader: 'file-loader',
            type: 'javascript/auto',
            options: {
              name() {
                return '[path][name].[ext]';
              },
            },
          }

    With exclude node_modules it makes best for me.

    {
            test: /\.json$/,
            loader: 'file-loader',
            type: 'javascript/auto',
            exclude: /node_modules/
          }
    
  18. RezaZR commented on Apr 24, 2020

    @RezaZR

    Adding esModule works best for me. Thank you for the solution

    {
            test: /\.json$/,
            use: [
              {
                loader: "file-loader",
                options: {
                  esModule: false,
                },
              },
            ],
            type: "javascript/auto",
          },
    
  19. Richifg commented on May 2, 2020

    @Richifg

    Correct way to use file-loader with JSON in Webpack 4+:

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    },

    This is working for me, my bundle now builds successfully and I have a separate JSON file, but now my app stop working. The js in the bundle that imports the JSON file is only getting a string with the file name instead of the javascript object I was receiving before extracting the JSON file from the bundle.

    Any idea what can he causing this?

  20. Garwin4j commented on May 3, 2020

    @Garwin4j

    I had the same problem. For this you have to read the file as a normal text file and transform it at runtime:

     return Axios.get(`/Config.json`, {
            method: 'GET',
          }).then(x => {
            ConfigService.globalConfig = x.data;
            return ConfigService.globalConfig;
          });

    The thing to consider thou is to ensure this is done before the file is used in code.

    Note that I spit out the file at the root of the app:

    {
        test: /\Config.json$/,
        loader: 'file-loader',
        type: 'javascript/auto',
        options: {
          name(file) {
            return '[name].[ext]';
          },
        },
      }
  21. Richifg commented on May 3, 2020

    @Richifg

    @Garwin4j thanks for the quick reply, yes I ended loading the failed asyncronously as well. I did it with fetch api and it worked well.

    fetch('content.json')
          .then((res) => res.json())
          .then((data) => console.log(data))
    

    In this example the file is also at the root.

  22. Eli-Black-Work commented on May 7, 2020

    @Eli-Black-Work

    So, to sum this up:

    If you want Webpack to load the contents of your JSON, so that you can immediately use it in your code, don't use file-loader at all. (#259 (comment))

    Example:

    Your code

    import languages from './languages.json';
    
    console.log(translations);  // { english: 'English', spanish: 'Español' }

    This method has a downside: The entire contents of the JSON file gets bundled into your app's .js file, which of course makes your app larger.

    If you want to load your JSON file via AJAX, use file-loader. (#259 (comment))

    Example:

    Webpack config file

    {
    	test: /\.json$/,
    	loader: 'file-loader',
    	type: 'javascript/auto'
    }

    Your code

    import languagesFileUrl from './languages.json';
    
    console.log(languagesFileUrl);  // This just returns the URL of your JSON file. For example: '/languages.json'. You should then fetch the file via AJAX.
    
    fetch(languagesFileUrl)
    ...
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions