Skip to content

Exporting JS from an inline loader that consumes a JSON file #6572

Closed

Description

@backjo

Do you want to request a feature or report a bug?
Report a bug (though i might just need to set a property somewhere - couldn't tell from the docs. I suspect this is related to natively supporting JSON modules now.)

What is the current behavior?
I have a loader which loads a JSON file and outputs JS code. When I try to use it with Webpack 4, I get a JSON parse error (webpack is trying to parse the outputted JS code as JSON)


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

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

What is the expected behavior?
I can output JS code from my loader parsing a JSON file (maybe with an option saying I'm outputting JS instead of JSON)
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.
OSX 10.13.3, Node 8.9.4, Webpack 4

Activity

  1. michael-ciniawsky commented on Feb 26, 2018

    @michael-ciniawsky
    Contributor
    {
       type: 'javascript/auto', // <= Set the module.type explicitly
       test: /\.json$/, // Maybe better to use a different extname (e.g /\.config\.json$/)
       use: [ { loader: 'json-to-js-loader' } ]
    }
  2. backjo commented on Feb 26, 2018

    @backjo
    Author

    👍

    Any way to do this with an inline loader?

  3. michael-ciniawsky commented on Feb 26, 2018

    @michael-ciniawsky
    Contributor

    Nope I don't think so, at least I'm not aware of any :)

  4. backjo commented on Feb 26, 2018

    @backjo
    Author

    Hmm - alternatively, is there a way to set the default in the webpack config?

  5. changed the title [-]Exporting JS from a loader that consumes a JSON file[/-] [+]Exporting JS from an inline loader that consumes a JSON file[/+] on Feb 26, 2018
  6. michael-ciniawsky commented on Feb 26, 2018

    @michael-ciniawsky
    Contributor

    Only rule.type (comment above) is possible via webpack.config.js

    You could hack around it within the loader, if really necessary (I don't recommend it), but that's it

    loader.js

    export default function loader (json) {
       // HACK
       this._module.type = 'javascript/auto' // <=
       
       const result = // Your loader... (JSON to JS)
    
       return `export default ${result}`
    }

    Maybe it's time to think about a different approach :)

  7. backjo commented on Feb 26, 2018

    @backjo
    Author

    Yeah, definitely rethinking the approach - but this hack helps bridge us :)

    Thx @michael-ciniawsky - much appreciated for your time on this :)

  8. cletusw commented on Mar 21, 2018

    @cletusw
    Contributor

    I tried the this._module.type hack and it didn't seem to work. I might have had it in the wrong place, though -- I'll try again.

    Regardless, this really should be a supported path. Any loader that converts between module types is affected (val-loader, to-string-loader, apply-loader, json-loader, even babel-loader converts from javascript/esm to javascript/dynamic -- isn't that affected as well?).

    And putting type: 'javascript/auto' in the config is insufficient in the case were you want to pipe the output of the converting loader into another loader that expects the resulting module type. And, as was pointed out, it doesn't work when specifying loaders inline.

    I asked this question on Stack Overflow as well: https://stackoverflow.com/questions/49395913/webpack-4-change-a-modules-type-in-a-loader

  9. cletusw commented on Mar 21, 2018

    @cletusw
    Contributor

    Also, for context, the loader I'm working on, messageformat-loader has to take JSON source and output JS -- I don't think there is a "different approach" we could use. And requiring our users to avoid inline loaders, put type: 'javascript/auto' in every config, and not pipe the output to another loader seems quite restricting.

  10. cletusw commented on Mar 21, 2018

    @cletusw
    Contributor

    Several people are having this problem, as evidenced by duplicates #6586, #6725, webpack-contrib/file-loader#264, webpack-contrib/file-loader#259

    EDIT: Also webpack-contrib/bundle-loader#74

  11. cletusw commented on Mar 21, 2018

    @cletusw
    Contributor

    I finally got the workaround to work in the loader. I had to do:

    this._module.type = 'javascript/auto';
    this._module.parser = new JavascriptParser();
    this._module.generator = new JavascriptGenerator();

    where the parser is webpack/lib/Parser.js and the generator is webpack/lib/JavascriptGenerator.js.

    I think this is a common enough use case that we should extend the Loader API to make this easier. Thoughts?

  12. Tatsujinichi commented on Mar 27, 2018

    @Tatsujinichi

    @michael-ciniawsky
    Is this a bug opened for this? Are we not supposed to be able to use custom loaders for json files?

  13. ianwalter commented on Jun 17, 2018

    @ianwalter

    I think I'm having an issue that is in the same vein. I'm trying to use yaml-loader to load a .yml file (which converts it to JSON), but I get the error:

    ERROR in ./locales/client/en.yml 2:11
    Module parse failed: Unexpected token (2:11)
    You may need an appropriate loader to handle this file type.
    | {
    > 	"features": [
    | 		{
    | 			"title": "Full-Stack Application",

    None of the workarounds talked about above fix this and I'm pretty sure this worked with Webpack 3. Can anyone suggest whether this is accounted for in an existing issue or whether I should create a new one?

  14. montogeek commented on Jun 18, 2018

    @montogeek
    Contributor

    @ianwalter Create a new issue.

  15. shermanrxie commented on Nov 20, 2018

    @shermanrxie

    The bundle JS looks like e.exports="./config.json". Missing require() after webpack. Does anyone know how to fix this?

    My Configuration:
    type: 'javascript/auto', test: /\.json$/, use: [ { loader: 'file-loader', options: { name: '[name].json', outputPath: './', publicPath: './' } } ]

  16. avinash8526 commented on Feb 27, 2019

    @avinash8526
    {
       type: 'javascript/auto', // <= Set the module.type explicitly
       test: /\.json$/, // Maybe better to use a different extname (e.g /\.config\.json$/)
       use: [ { loader: 'json-to-js-loader' } ]
    }

    what is json-to-js-loader

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