webpackwebpack-loader

How to resolve "Module parse failed: Unexpected token" error for own Webpack loaders which returns a string?


I want to create the Webpack loader which loads the PUG AST. With below implementation:

import PugLexer from "pug-lexer";
import generatePugAST from "pug-parser";


const pugAstLoader: (source: string) => string | null = function(source: string): string | null {

  try {

    const tokens: PugLexer.Token[] = PugLexer("div test");
    const AST = generatePugAST(tokens, { filename: "Test.pug", src: source });

    return AST;

  } catch (error: unknown) {

    console.error(error);

    return null;

  }
};


export default pugAstLoader;

the error:

ERROR in ./Components/Custom.custom.pug
Module build failed: Error: Final loader (../PugAST_Loader.ts) didn't return a Buffer or String

will be if to run Webpack. If I have understood correctly, the loader must return either Buffer of String. O'K, I suppose all I need is transform AST to string:

import PugLexer from "pug-lexer";
import generatePugAST from "pug-parser";


const pugAstLoader: (source: string) => string | null = function(source: string): string | null {

  try {

    const tokens: PugLexer.Token[] = PugLexer("div test");
    const AST = generatePugAST(tokens, { filename: "Test.pug", src: source });

    return JSON.stringify(AST);

  } catch (error: unknown) {

    console.error(error);

    return null;

  }
};


export default pugAstLoader;

Now, I have

ERROR in ./Components/Custom.custom.pug 1:7
Module parse failed: Unexpected token (1:7)
File was processed with these loaders:
 * ../PugAST_Loader.ts
You may need an additional loader to handle the result of these loaders.
> {"type":"Block",// ...
 @ ./index.ts 8:0-52 11:12-18

error.

Repro (If you will clone this, please make sure that you are in specific_loader-1 branch)


Solution

  • You return a JSON as the string and webpack don't know how to handle it.

    The loader should return the string containing valid JS code:

    import PugLexer from "pug-lexer";
    import generatePugAST from "pug-parser";
    
    
    const pugAstLoader: (source: string) => string | null = function(source: string): string | null {
    
      try {
        const tokens: PugLexer.Token[] = PugLexer("div test");
        const AST = generatePugAST(tokens, { filename: "Test.pug", src: source });
    
        return "export default " + JSON.stringify(AST); // <= export JSON
      } catch (error: unknown) {
        console.error(error);
    
        return '';
      }
    };
    
    
    export default pugAstLoader;
    

    The fixed code above works. No webpack errors. In the browser console will be displayed the Custom object.