How to inspect files packaged by webpack before they are emitted

I recently had a need to inspect files in my front-end project that are packaged by webpack before they were emitted. In my pursuit to accomplish this an elegant and robust manner, I came across webpack hooks which are an exceedingly powerful way to t…


This content originally appeared on DEV Community and was authored by Mike Ellis

I recently had a need to inspect files in my front-end project that are packaged by webpack before they were emitted. In my pursuit to accomplish this an elegant and robust manner, I came across webpack hooks which are an exceedingly powerful way to tap into the inner workings of webpack.

What is webpack?

webpack is a module bundler for JavaScript. Front-end applications contain many types of assets such as JavaScript, (HOPEFULLY) Typescript, JSON, HTML, CSS, and images. webpack (after you've configure it to process files in a certain manner) will generate static assets, representing your applications modules so that they can be interpreted by a browser.

What are webpack hooks?

A "hook" in software development is an place in code that allows you to tap into a module to either provide different behavior or to react when something happens. webpack provides the following types of hooks:

How about an example?

For an example scenario, let's pretend we want to make sure that, when we build our application, no file is outputted that contains the string MY_SUPER_SECRET. Perhaps we want to do this to provide a last line of defense from a developer including a sensitive value in our code and we want to prevent webpack from even compiling it. If that string is detected, we want wepback to:

  • throw an error.
  • not emit any files at any point during the build.

To do this, let's look at the shouldEmit compiler hook. This hook is called before assets are emitted and will allow us to error out and not emit assets if our validation fails.

To start, let's create a new plugin class and add it to the plugins block of our webpack.config:

// src/webpack.config.ts
import { AssetValidatorPlugin } from './plugins/asset-validator-plugin';

module.exports= {
    entry: {...},
    module:{...},
    plugins: [
        new AssetValidatorPlugin(),
        ...
    ]
};

Note that, while I've defined my plugin in a separate class/file, you could include it in your webpack.config inline.

Now, let's take a look at the plugin:

// src/plugins/asset-validator-plugin.ts
import * as webpack from 'webpack';

export class AssetValidatorPlugin {
  apply(compiler: webpack.Compiler) {
    compiler.hooks.shouldEmit.tap('AssetValidatorPlugin', (compilation: webpack.compilation.Compilation) => {
      this.validateAssets(compilation);
    });
  }

  public validateAssets(compilation: webpack.compilation.Compilation) {
    const assets = Object.entries(compilation.assets);
    const regex = new RegExp('MY_SUPER_SECRET', 'g');

    // Loop through each asset and check to see if it contains any sensitive strings
    for (let i = 0; i < assets.length; i++) {
      const [fileName] = assets[i];
      const asset = compilation.getAsset(fileName);
      const source = asset.source.source();
      const contents = convertSourceToString(source);
      const matches = contents.match(regex);

      if (matches) {
        throw new Error(
          "Our tool has identified the presence of the string 'MY_SUPER_SECRET' in your compiled code. Compilation has been aborted."
        );
      }
    }

    return true;
  }
}

// This function is only needed because asset.source.source() can be a string or ArrayBuffer
const convertSourceToString = (source: string | ArrayBuffer): string => {
  if (typeof source === 'string') {
    return source;
  } else {
    return new TextDecoder().decode(source);
  }
};

So, let's review what is included our plugin. We've defined our plugin class and, within, are able to tap into the compiler.hooks.shouldEmit hook. In the hook callback, we simply call a validateAssets() function we've defined which loops through all assets that are part of the compilation and use regular expression matching to see if the string exists. We throw an error if it does, short-circuiting the compilation and not emitting any files. If it doesn't contain our special string, we'll return true, compilation will continue, emitting the packaged files as expected.

If you have a need to pass any parameters to your plugin, that can easily be accomplished by defining a constructor in your plugin class like this:

constructor(options: MyPluginOptions) {
    this.options = options;
}

Conclusion

Hopefully you now have a better understanding of webpack hooks and how you can leverage them to provide additional behavior when your application's assets are packaged.


This content originally appeared on DEV Community and was authored by Mike Ellis


Print Share Comment Cite Upload Translate Updates
APA

Mike Ellis | Sciencx (2022-06-30T20:30:34+00:00) How to inspect files packaged by webpack before they are emitted. Retrieved from https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/

MLA
" » How to inspect files packaged by webpack before they are emitted." Mike Ellis | Sciencx - Thursday June 30, 2022, https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/
HARVARD
Mike Ellis | Sciencx Thursday June 30, 2022 » How to inspect files packaged by webpack before they are emitted., viewed ,<https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/>
VANCOUVER
Mike Ellis | Sciencx - » How to inspect files packaged by webpack before they are emitted. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/
CHICAGO
" » How to inspect files packaged by webpack before they are emitted." Mike Ellis | Sciencx - Accessed . https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/
IEEE
" » How to inspect files packaged by webpack before they are emitted." Mike Ellis | Sciencx [Online]. Available: https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/. [Accessed: ]
rf:citation
» How to inspect files packaged by webpack before they are emitted | Mike Ellis | Sciencx | https://www.scien.cx/2022/06/30/how-to-inspect-files-packaged-by-webpack-before-they-are-emitted/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.