Skip to content

Instantly share code, notes, and snippets.

@johnAirRobe
Last active April 13, 2022 23:34
Show Gist options
  • Save johnAirRobe/3cd338435a7a14d002f60ef05dffeec6 to your computer and use it in GitHub Desktop.
Save johnAirRobe/3cd338435a7a14d002f60ef05dffeec6 to your computer and use it in GitHub Desktop.
Setting up React Fast Refresh for chrome-extension-boilerplate-react project
{
"presets": [
// "@babel/preset-env"
"@babel/preset-react"
// "react-app"
],
"plugins": [
// "@babel/plugin-proposal-class-properties",
"react-refresh/babel"
]
}
{
"name": "prototype-widget-install-extension",
"version": "4.3.5",
"description": "",
"license": "MIT",
"repository": {
"type": "git",
"url": ""
},
"scripts": {
"build": "node utils/build.js",
"start": "node utils/webserver.js",
"prettier": "prettier --write '**/*.{js,jsx,ts,tsx,json,css,scss,md}'"
},
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-class-properties": "^7.16.7",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
"@types/chrome": "^0.0.180",
"@types/node": "^17.0.23",
"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",
"@types/webpack": "^5.28.0",
"babel-loader": "^8.2.4",
"babel-preset-react-app": "^10.0.1",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.2.4",
"css-loader": "^6.7.1",
"eslint": "^8.12.0",
"eslint-config-react-app": "^7.0.0",
"eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"file-loader": "^6.2.0",
"fs-extra": "^10.0.1",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"node-sass": "^7.0.1",
"prettier": "^2.6.2",
"react-refresh": "^0.12.0",
"sass-loader": "^12.6.0",
"source-map-loader": "^3.0.1",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.1",
"ts-loader": "^9.2.8",
"ts-node": "^10.7.0",
"type-fest": "^2.12.2",
"typescript": "^4.6.3",
"webpack": "^5.71.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
}
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
var webpack = require('webpack'),
path = require('path'),
fileSystem = require('fs-extra'),
env = require('./utils/env'),
CopyWebpackPlugin = require('copy-webpack-plugin'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
TerserPlugin = require('terser-webpack-plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ASSET_PATH = process.env.ASSET_PATH || '/';
var alias = {}
// load the secrets
var secretsPath = path.join(__dirname, 'secrets.' + env.NODE_ENV + '.js');
if (fileSystem.existsSync(secretsPath)) {
alias['secrets'] = secretsPath;
}
var fileExtensions = [
'jpg',
'jpeg',
'png',
'gif',
'eot',
'otf',
'svg',
'ttf',
'woff',
'woff2',
];
const isDevelopment = process.env.NODE_ENV !== 'production'
var options = {
mode: process.env.NODE_ENV || 'development',
entry: {
newtab: path.join(__dirname, 'src', 'pages', 'Newtab', 'index.jsx'),
options: path.join(__dirname, 'src', 'pages', 'Options', 'index.jsx'),
popup: path.join(__dirname, 'src', 'pages', 'Popup', 'index.jsx'),
background: path.join(__dirname, 'src', 'pages', 'Background', 'index.js'),
contentScript: path.join(__dirname, 'src', 'pages', 'Content', 'index.js'),
devtools: path.join(__dirname, 'src', 'pages', 'Devtools', 'index.js'),
panel: path.join(__dirname, 'src', 'pages', 'Panel', 'index.jsx'),
},
chromeExtensionBoilerplate: {
notHotReload: ['background', 'contentScript', 'devtools'],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'build'),
clean: true,
publicPath: ASSET_PATH,
},
module: {
rules: [
{
// look for .css or .scss files
test: /\.(css|scss)$/,
// in the `src` directory
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: new RegExp('.(' + fileExtensions.join('|') + ')$'),
type: 'asset/resource',
exclude: /node_modules/,
// loader: 'file-loader',
// options: {
// name: '[name].[ext]',
// },
},
{
test: /\.html$/,
loader: 'html-loader',
exclude: /node_modules/,
},
{ test: /\.(ts|tsx)$/, loader: 'ts-loader', exclude: /node_modules/ },
{
test: /\.(js|jsx)$/,
use: [
{
loader: 'source-map-loader',
},
{
loader: require.resolve('babel-loader'),
options: {
plugins: [isDevelopment && require.resolve('react-refresh/babel')].filter(Boolean),
},
},
],
exclude: /node_modules/,
},
],
},
resolve: {
extensions: fileExtensions
.map((extension) => '.' + extension)
.concat(['.js', '.jsx', '.ts', '.tsx', '.css']),
},
plugins: [
new CleanWebpackPlugin({ verbose: false }),
new webpack.ProgressPlugin(),
// expose and write the allowed env vars on the compiled bundle
new webpack.EnvironmentPlugin(['NODE_ENV']),
new CopyWebpackPlugin({
patterns: [
{
from: 'src/manifest.json',
to: path.join(__dirname, 'build'),
force: true,
transform: function (content, path) {
// generates the manifest file using the package.json informations
return Buffer.from(
JSON.stringify({
description: process.env.npm_package_description,
version: process.env.npm_package_version,
...JSON.parse(content.toString()),
})
);
},
},
],
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'src/pages/Content/content.styles.css',
to: path.join(__dirname, 'build'),
force: true,
},
],
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'src/assets/img/icon-128.png',
to: path.join(__dirname, 'build'),
force: true,
},
],
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'src/assets/img/icon-34.png',
to: path.join(__dirname, 'build'),
force: true,
},
],
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'pages', 'Newtab', 'index.html'),
filename: 'newtab.html',
chunks: ['newtab'],
cache: false,
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'pages', 'Options', 'index.html'),
filename: 'options.html',
chunks: ['options'],
cache: false,
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'pages', 'Popup', 'index.html'),
filename: 'popup.html',
chunks: ['popup'],
cache: false,
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'pages', 'Devtools', 'index.html'),
filename: 'devtools.html',
chunks: ['devtools'],
cache: false,
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'pages', 'Panel', 'index.html'),
filename: 'panel.html',
chunks: ['panel'],
cache: false,
}),
isDevelopment && new ReactRefreshWebpackPlugin()
],
infrastructureLogging: {
level: 'info',
},
};
if (env.NODE_ENV === 'development') {
options.devtool = 'cheap-module-source-map';
} else {
options.optimization = {
alias: alias,
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false,
}),
],
};
}
module.exports = options;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment