I want to insert the below script tag into my popup.html
and options.html
when compiled in dist folder:
<script src="http://localhost:8097"></script>
I need this to be the first script before any other scripts. Below is how I expect the script to look in my HTML:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="http://localhost:8097"></script>
<script src="example.js"></script>
<script src="react.js"></script>
</head>
<body>
</body>
</html>
How can I go about injecting this script for local development only, when working with Webpack?
Here's my set-up so far:
webpack.dev.js
:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'cheap-module-source-map'
});
webpack.common.js
:
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
popup: path.resolve('src/popup/popup.tsx'),
options: path.resolve('src/options/options.tsx'),
background: path.resolve('src/background/background.ts'),
contentScript: path.resolve('src/contentScript/contentScript.js')
},
module: {
rules: [
{
use: 'ts-loader',
test: /\.tsx?$/,
exclude: /node_modules/
},
{
use: ['style-loader', 'css-loader'],
test: /\.css$/i
},
{
type: 'asset/resource',
test: /\.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/
}
]
},
plugins: [
new CleanWebpackPlugin({
cleanStaleWebpackAssets: false
}),
new CopyPlugin({
patterns: [
{
from: path.resolve('src/static'),
to: path.resolve('dist/')
}
]
}),
...getHtmlPlugin(['popup', 'options'])
],
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: '[name].js',
path: path.resolve('dist')
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
function getHtmlPlugin(chunks) {
return chunks.map(
(chunk) =>
new HtmlPlugin({
title: 'Test',
filename: `${chunk}.html`,
chunks: [chunk]
})
);
}
Package.json
{
...
"devDependencies": {
"webpack": "^5.94.0",
"webpack-cli": "^5.1.4",
"webpack-merge": "^6.0.1"
}
...
}
You can inject a custom script (like http://localhost:8097
) into your generated HTML files only in development using HtmlWebpackPlugin
with the templateParameters
or inject
options, or by using a custom HTML template with logic to conditionally add that script only in dev.
I think you could even just duplicate your files with other names and adjust your scripts to use them in development mode (popup-dev.html , options-dev.html)
If going for the HtmlWebpackPlugin
:
With EJS you could use a custom template.ejs
for popup.html
and options.html
template.ejs
file
Inside your project (e.g., src/templates/template.ejs
):<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= htmlWebpackPlugin.options.title %></title>
<% if (htmlWebpackPlugin.options.devMode) { %>
<script src="http://localhost:8097"></script>
<% } %>
</head>
<body>
<div id="app"></div>
</body>
</html>
This checks for devMode
, and if true, injects your dev script.
getHtmlPlugin()
in webpack.common.js
Update your helper function to include the template and pass the dev flag dynamically:
function getHtmlPlugin(chunks) {
const isDev = process.env.NODE_ENV === 'development';
return chunks.map(
(chunk) =>
new HtmlPlugin({
title: 'Test',
filename: `${chunk}.html`,
chunks: [chunk],
template: path.resolve(__dirname, 'src/templates/template.ejs'),
templateParameters: {
devMode: isDev
},
inject: 'body'
})
);
}
NODE_ENV
correctlyMake sure you're setting NODE_ENV=development
when running webpack-dev-server
or building locally:
cross-env NODE_ENV=development webpack --config webpack.dev.js
Add "cross-env"
to your dev dependencies if needed:
npm install --save-dev cross-env
If you want separate templates for popup
and options
You can pass different templates to HtmlWebpackPlugin
in getHtmlPlugin()
like this:
template: path.resolve(__dirname, `src/${chunk}/${chunk}.ejs`)
Then make popup.ejs
and options.ejs
with the same if (htmlWebpackPlugin.options.devMode)
logic.