webpack string replace for HTML files

tldr; I wrote a plugin called html-webpack-string-replace-plugin to do string replacements in HTML using the amazing HtmlWebpackPlugin.

We do an obscene amount of string replacements in our project, mostly due to differences between environments and the fact that we’ve grown a lot and never really went back to address this situation. Yep, good ol’ tech debt. We have placeholder strings in our JS, TS and even LESS/SCSS. Luckily when we switched to webpack, we were able to use the StringReplacementWebpackPlugin and it worked like a charm! Thanks to jamesandersen for creating and maintaining it!

There was however a gap - we also had placeholder text in our HTML - mostly just the app’s main index.html, but we didn’t have a great solution for it. Enter HtmlWebpackPlugin! Prior to using this plugin, we were copying our main html file, initially using Grunt, and now using CopyWebpackPlugin. The HtmlWebpackPlugin includes a lot of options we aren’t yet using, like injection, favicon, and interpolation of EJS, pug and other templating engines. Of course we are working with a system that has existed for several years, so switching over to using a templating engine isn’t going to work… too many places to change. So I ventured off to see if I could write a plugin that could transform the html file and make the string replacements along the way. Having never written a webpack plugin before, I was skeptical… but it turns out it was scary simple! Hooking into the html-webpack-plugin-before-html-processing event I wrote a plugin that allows developers to easily perform the same string replacements in HTML that we are able to do in other files with the StringReplacementWebpackPlugin. And here it is: https://www.npmjs.com/package/html-webpack-string-replace-plugin

1
$ npm install -D html-webpack-string-replace-plugin

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
plugins: \[
new HtmlWebpackPlugin({
"template": "./src/input.html",
"filename": "./output.html"
}),

new HtmlWebpackStringReplacePlugin({
'\_VERSION\_': '1.0',
'\_CDN\_': 'https://some-cdn'
})
\]

input.html

1
2
3
4
5
6
7
8
<html>
<head>
<title>My App Version \_VERSION\_</title>
<script src="\_CDN\_/foo.js"></script>
</head>
<body>
</body>
</html>

output.html

1
2
3
4
5
6
7
8
<html>
<head>
<title>My App Version 1.0</title>
<script src="https://some-cdn/foo.js"></script>
</head>
<body>
</body>
</html>

I hope this plugin turns out to be useful for others! If you’re curious you can follow along with my teams conversion to use webpack, or follow me on twitter.