webpack: Move webpack configuration to web.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2023-02-23 17:20:53 -08:00
committed by Tim Abbott
parent 23fd4f95f4
commit 0ef8e88b17
13 changed files with 105 additions and 103 deletions

8
web/.browserslistrc Normal file
View File

@@ -0,0 +1,8 @@
> 0.15%
> 0.15% in US
last 2 versions
Firefox ESR
not dead and supports async-functions
[test]
current Node

25
web/babel.config.js Normal file
View File

@@ -0,0 +1,25 @@
"use strict";
module.exports = {
plugins: [
[
"formatjs",
{
additionalFunctionNames: ["$t", "$t_html"],
overrideIdFn: (id, defaultMessage) => defaultMessage,
},
],
],
presets: [
[
"@babel/preset-env",
{
corejs: "3.27",
shippedProposals: true,
useBuiltIns: "usage",
},
],
"@babel/typescript",
],
sourceType: "unambiguous",
};

23
web/postcss.config.js Normal file
View File

@@ -0,0 +1,23 @@
"use strict";
const path = require("path");
const {media_breakpoints} = require("./src/css_variables");
module.exports = ({file}) => ({
plugins: [
(file.basename ?? path.basename(file)) === "dark_theme.css" &&
// Add postcss-import plugin with postcss-prefixwrap to handle
// the flatpickr dark theme. We do this because flatpickr themes
// are not scoped. See https://github.com/flatpickr/flatpickr/issues/2168.
require("postcss-import")({
plugins: [require("postcss-prefixwrap")("%dark-theme")],
}),
require("postcss-nested"),
require("postcss-extend-rule"),
require("postcss-simple-vars")({variables: media_breakpoints}),
require("postcss-calc"),
require("postcss-media-minmax"),
require("autoprefixer"),
],
});

View File

@@ -2,7 +2,7 @@
// This module is included from webpack in development mode. To access it from
// the browser console, run:
// var debug = require("./web/src/debug");
// var debug = require("./src/debug");
/*
debug.print_elapsed_time("foo", foo)

View File

@@ -34,7 +34,7 @@ require("@babel/register")({
"babel-plugin-rewire-ts",
["@babel/plugin-transform-modules-commonjs", {lazy: () => true}],
],
root: path.resolve(__dirname, "../../.."),
root: path.resolve(__dirname, "../.."),
});
// Create a helper function to avoid sneaky delays in tests.

View File

@@ -1,89 +1,86 @@
{
"activity": [
"./web/src/bundles/common",
"./src/bundles/common",
"sorttable",
"./web/src/analytics/activity",
"./web/styles/portico/activity.css"
"./src/analytics/activity",
"./styles/portico/activity.css"
],
"billing": [
"./web/src/bundles/portico",
"./web/src/portico/landing-page",
"./web/styles/portico/landing_page.css",
"./web/src/billing/helpers",
"./web/src/billing/billing",
"./web/src/templates",
"./web/src/loading",
"./web/styles/portico/billing.css"
"./src/bundles/portico",
"./src/portico/landing-page",
"./styles/portico/landing_page.css",
"./src/billing/helpers",
"./src/billing/billing",
"./src/templates",
"./src/loading",
"./styles/portico/billing.css"
],
"upgrade": [
"./web/src/bundles/portico",
"./web/src/portico/tippyjs",
"./web/src/portico/landing-page",
"./web/styles/portico/landing_page.css",
"./web/src/billing/helpers",
"./web/src/billing/upgrade",
"./web/src/templates",
"./web/src/loading",
"./web/styles/portico/billing.css"
"./src/bundles/portico",
"./src/portico/tippyjs",
"./src/portico/landing-page",
"./styles/portico/landing_page.css",
"./src/billing/helpers",
"./src/billing/upgrade",
"./src/templates",
"./src/loading",
"./styles/portico/billing.css"
],
"billing-event-status": [
"./web/src/bundles/portico",
"./web/styles/portico/landing_page.css",
"./web/src/billing/event_status.js",
"./web/src/billing/helpers",
"./web/styles/portico/billing.css"
"./src/bundles/portico",
"./styles/portico/landing_page.css",
"./src/billing/event_status.js",
"./src/billing/helpers",
"./styles/portico/billing.css"
],
"portico": ["./web/src/bundles/portico"],
"error-styles": [
"./web/third/bootstrap/css/bootstrap.css",
"./web/styles/portico/portico_styles.css"
],
"common": ["./web/src/bundles/common"],
"portico": ["./src/bundles/portico"],
"error-styles": ["./third/bootstrap/css/bootstrap.css", "./styles/portico/portico_styles.css"],
"common": ["./src/bundles/common"],
"help": [
"./web/src/bundles/portico",
"./src/bundles/portico",
"simplebar/dist/simplebar.css",
"simplebar",
"./web/src/portico/help",
"./web/src/portico/tabbed-instructions"
"./src/portico/help",
"./src/portico/tabbed-instructions"
],
"landing-page": [
"./web/src/bundles/portico",
"./web/src/portico/landing-page",
"./web/styles/portico/landing_page.css"
"./src/bundles/portico",
"./src/portico/landing-page",
"./styles/portico/landing_page.css"
],
"integrations": [
"./web/src/bundles/portico",
"./web/src/portico/integrations",
"./web/styles/portico/landing_page.css",
"./web/styles/portico/integrations.css"
"./src/bundles/portico",
"./src/portico/integrations",
"./styles/portico/landing_page.css",
"./styles/portico/integrations.css"
],
"communities": [
"./web/src/bundles/portico",
"./web/src/portico/communities",
"./web/styles/portico/landing_page.css",
"./web/styles/portico/integrations.css"
"./src/bundles/portico",
"./src/portico/communities",
"./styles/portico/landing_page.css",
"./styles/portico/integrations.css"
],
"signup": ["./web/src/bundles/portico", "jquery-validation", "./web/src/portico/signup"],
"register": ["./web/src/bundles/portico", "jquery-validation", "./web/src/portico/signup"],
"signup": ["./src/bundles/portico", "jquery-validation", "./src/portico/signup"],
"register": ["./src/bundles/portico", "jquery-validation", "./src/portico/signup"],
"confirm-preregistrationuser": [
"./web/src/bundles/common",
"./web/src/portico/confirm-preregistrationuser"
"./src/bundles/common",
"./src/portico/confirm-preregistrationuser"
],
"support": [
"./web/src/bundles/common",
"./src/bundles/common",
"sorttable",
"./web/src/analytics/activity",
"./web/styles/portico/activity.css",
"./web/src/analytics/support"
"./src/analytics/activity",
"./styles/portico/activity.css",
"./src/analytics/support"
],
"desktop-login": ["./web/src/bundles/portico", "./web/src/portico/desktop-login"],
"desktop-redirect": ["./web/src/bundles/portico", "./web/src/portico/desktop-redirect"],
"desktop-login": ["./src/bundles/portico", "./src/portico/desktop-login"],
"desktop-redirect": ["./src/bundles/portico", "./src/portico/desktop-redirect"],
"stats": [
"./web/src/bundles/portico",
"./web/styles/portico/stats.css",
"./web/src/stats/stats",
"./src/bundles/portico",
"./styles/portico/stats.css",
"./src/stats/stats",
"tippy.js/dist/tippy.css"
],
"app": ["./web/src/bundles/app"],
"digest": ["./web/src/bundles/portico"]
"app": ["./src/bundles/app"],
"digest": ["./src/bundles/portico"]
}

255
web/webpack.config.ts Normal file
View File

@@ -0,0 +1,255 @@
/// <reference types="webpack-dev-server" />
import path from "path";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
import HtmlWebpackPlugin from "html-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import type webpack from "webpack";
import BundleTracker from "webpack-bundle-tracker";
import DebugRequirePlugin from "./debug-require-webpack-plugin";
import assets from "./webpack.assets.json";
import dev_assets from "./webpack.dev-assets.json";
export default (env: {minimize?: boolean} = {}, argv: {mode?: string}): webpack.Configuration[] => {
const production: boolean = argv.mode === "production";
const baseConfig: webpack.Configuration = {
mode: production ? "production" : "development",
context: __dirname,
cache: {
type: "filesystem",
buildDependencies: {
config: [__filename],
},
},
snapshot: {
immutablePaths: ["/srv/zulip-npm-cache"],
},
};
const frontendConfig: webpack.Configuration = {
...baseConfig,
name: "frontend",
entry: production
? assets
: Object.fromEntries(
Object.entries({...assets, ...dev_assets}).map(([name, paths]) => [
name,
[...paths, "./src/debug"],
]),
),
module: {
rules: [
{
test: require.resolve("./src/zulip_test"),
loader: "expose-loader",
options: {exposes: "zulip_test"},
},
{
test: require.resolve("./debug-require"),
loader: "expose-loader",
options: {exposes: "require"},
},
{
test: require.resolve("jquery"),
loader: "expose-loader",
options: {exposes: ["$", "jQuery"]},
},
// Generate webfont
{
test: /\.font\.js$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
url: false, // webfonts-loader generates public relative URLs
},
},
{
loader: "webfonts-loader",
options: {
fileName: production
? "files/[fontname].[chunkhash].[ext]"
: "files/[fontname].[ext]",
publicPath: "",
},
},
],
},
// Transpile .js and .ts files with Babel
{
test: /\.(js|ts)$/,
include: [
path.resolve(__dirname, "shared/src"),
path.resolve(__dirname, "src"),
],
loader: "babel-loader",
},
// regular css files
{
test: /\.css$/,
exclude: path.resolve(__dirname, "styles"),
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
],
},
// PostCSS loader
{
test: /\.css$/,
include: path.resolve(__dirname, "styles"),
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
sourceMap: true,
},
},
{
loader: "postcss-loader",
options: {
sourceMap: true,
},
},
],
},
{
test: /\.hbs$/,
loader: "handlebars-loader",
options: {
ignoreHelpers: true,
// Tell webpack not to explicitly require these.
knownHelpers: [
"if",
"unless",
"each",
"with",
// The ones below are defined in web/src/templates.js
"plural",
"eq",
"and",
"or",
"not",
"t",
"tr",
"rendered_markdown",
"tooltip_hotkey_hints",
],
preventIndent: true,
// This replaces relative image resources with
// a computed require() path to them, so their
// webpack-hashed URLs are used.
inlineRequires: /^(\.\.\/)+(images|static)\//,
},
},
// load fonts and files
{
test: /\.(eot|jpg|svg|ttf|otf|png|woff2?)$/,
type: "asset/resource",
},
],
},
output: {
path: path.resolve(__dirname, "../static/webpack-bundles"),
publicPath: "",
filename: production ? "[name].[contenthash].js" : "[name].js",
assetModuleFilename: production
? "files/[name].[hash][ext][query]"
: // Avoid directory traversal bug that upstream won't fix
// (https://github.com/webpack/webpack/issues/11937)
(pathData) => "files" + path.join("/", pathData.filename!),
chunkFilename: production ? "[contenthash].js" : "[id].js",
},
resolve: {
...baseConfig.resolve,
extensions: [".ts", ".js"],
},
// We prefer cheap-module-source-map over any eval-* options
// because stacktrace-gps doesn't currently support extracting
// the source snippets with the eval-* options.
devtool: production ? "source-map" : "cheap-module-source-map",
optimization: {
minimize: env.minimize ?? production,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.cleanCssMinify,
}),
"...",
],
splitChunks: {
chunks: "all",
// webpack/examples/many-pages suggests 20 requests for HTTP/2
maxAsyncRequests: 20,
maxInitialRequests: 20,
},
},
plugins: [
new DebugRequirePlugin(),
new BundleTracker({
filename: production
? "../webpack-stats-production.json"
: "../var/webpack-stats-dev.json",
}),
// Extract CSS from files
new MiniCssExtractPlugin({
filename: production ? "[name].[contenthash].css" : "[name].css",
chunkFilename: production ? "[contenthash].css" : "[id].css",
}),
new HtmlWebpackPlugin({
filename: "5xx.html",
template: "html/5xx.html",
chunks: ["error-styles"],
}),
],
devServer: {
devMiddleware: {
publicPath: "/webpack/",
stats: {
// We want just errors and a clear, brief notice
// whenever webpack compilation has finished.
preset: "minimal",
assets: false,
modules: false,
},
},
headers: {
"Access-Control-Allow-Origin": "*",
},
},
infrastructureLogging: {
level: "warn",
},
watchOptions: {
ignored: [
"**/node_modules/**",
// Prevent Emacs file locks from crashing webpack-dev-server
// https://github.com/webpack/webpack-dev-server/issues/2821
"**/.#*",
],
},
};
const serverConfig: webpack.Configuration = {
...baseConfig,
name: "server",
target: "node",
entry: {
"katex-cli": "shebang-loader!katex/cli",
},
output: {
path: path.resolve(__dirname, "../static/webpack-bundles"),
},
};
return [frontendConfig, serverConfig];
};

View File

@@ -1,17 +1,17 @@
{
"dev-login": ["./web/src/bundles/portico", "./web/src/portico/dev-login"],
"dev-login": ["./src/bundles/portico", "./src/portico/dev-login"],
"dev-integrations-panel": [
"./web/src/bundles/portico",
"./web/src/portico/integrations_dev_panel",
"./web/styles/portico/integrations_dev_panel.css",
"./web/src/reload_state",
"./web/src/channel"
"./src/bundles/portico",
"./src/portico/integrations_dev_panel",
"./styles/portico/integrations_dev_panel.css",
"./src/reload_state",
"./src/channel"
],
"dev-email-log": [
"./web/src/bundles/common",
"./web/src/portico/email_log",
"./web/styles/portico/email_log.css",
"./web/src/reload_state",
"./web/src/channel"
"./src/bundles/common",
"./src/portico/email_log",
"./styles/portico/email_log.css",
"./src/reload_state",
"./src/channel"
]
}