Search code examples
javascripttypescriptwebpackfirefox-addon-webextensions

using webpack to bundle webextension manifest with typescript


I'm developing a web extension in typescript. To organize the code, I would like to bundle the extension with webpack.

Ideally, webpack should compile typescript and copy the resulting javascript, together with html, css, images to a dist/ directory. I found a repository which does just what I need. It has the manifest.json as entry point and creates a dist/ directory.

But the template doesn't use typescript. And this is my problem: In the manifest.json I need to define javascript files that will be executed (content, background, etc). But these scripts don't exist yet. They are produced by the typescript compiler. So if I point webpack to the manifest, it complains about not finding sources. A workaround (which I would like to avoid) might be to design a two-step workflow:

  1. use the typescript compiler to compile my sourcecode to javascript.
  2. use webpack to bundle the resulting code to dist/.

I would like to condense this into a single webpack-based step and tried to do this based on the example repository. They do the following:

  • The entry point is the manifest
  • HTML, CSS and Assets are processed with the usual loaders
  • For Javascript the config looks for index.js files and processes them with spawn-loader
  • Other Js files are loaded with babel.

I didn't know it was possible to use a manifest as the entry point. They do this with extricate-loader. The docs have a nice sample.

I have created a mix of the two setups. The sample from the docs and the repository. Here is the code to reproduce the problem: https://github.com/lhk/webextension_typescript_webpack/tree/complex

I have also set up a minimal working example: https://github.com/lhk/webextension_typescript_webpack. But this working example doesn't copy any html, css, etc. It just compiles the typescript to dist/.


Solution

  • The boilerplate you're using is a little hacky and requires so much code that it defeats the purpose of "using the manifest.json" as an entry point. I have 3 alternatives.

    Use Parcel

    Parcel v1 and v2 have good WebExtensions transformers that actually parse real manifest.json automatically, meaning that you can specify your .ts files in it and they'll be automatically transpiled.

    With v1 you need zero configuration, just use parcel build manifest.json; With v2 you'll only need a 1-line JSON config file.

    Use a proper manifest parser in webpack

    I don't actually suggest this option, but at least webextension-manifest-loader automatically gets any files specified in the manifest + it lets you have per-browser builds.

    Don't use manifest.json as an entry point

    While less automated, you could just use webpack to bundle JS and CSS files as always and leave the final manifest.json in the dist folder. This avoids having to maintain a house-of-cards webpack config that gets in the way more than it actually helps.