using webpack to bundle webextension manifest with typescript
Asked Answered
M

2

6

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/.

Mier answered 27/9, 2018 at 9:29 Comment(0)
R
2

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.

Raymonderaymonds answered 15/3, 2021 at 2:48 Comment(1)
The project is long over, but I actually ended up using parcel. Thanks for providing this answer, to anyone else who needs a solution: Yes I can attest this answer works like a charm :DMier
M
0

Please note: This is not an answer to the original question, I will not mark this as accepted. I have found a setup which works for me. But it is the two step approach: compiling typescript first, then running webpack.

Fix: After trying various build setups, I think the correct solution might be the two-step build process after all:

  1. use typescript to compile to javascript
  2. use webpack to bundle generated javascript into a webextension

If the typescript compiler is not configured properly, you won't see error messages in your editor. In order to get proper autocompletion and error messages, you basically need a tsconfig.json. So the first step needs to be set up in any case.

Then, since you have already configured typescript, you might as well just bundle the generated javascript. The important trick here is to re-use the existing sourcemaps generated by the typescript compiler. (Webpack use existing source map from previous build step)

I have forked the repository and reconfigured it to use typescript + webpack. This includes getting rid of the babel polyfill: https://github.com/lhk/webextensions-webpack-boilerplate

Mier answered 27/9, 2018 at 12:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.