diff --git a/tools/webpack b/tools/webpack index ab21dcd9fe..f463bd06af 100755 --- a/tools/webpack +++ b/tools/webpack @@ -13,6 +13,13 @@ os.chdir(os.path.join(os.path.dirname(__file__), "../web")) from version import ZULIP_VERSION +webpack_command = [ + "node", + "--experimental-strip-types", + "--no-warnings=ExperimentalWarning", + "../node_modules/webpack-cli/bin/cli.js", +] + def build_for_prod_or_puppeteer(quiet: bool, config_name: str | None = None) -> NoReturn: """Builds for production, writing the output to disk""" @@ -21,7 +28,8 @@ def build_for_prod_or_puppeteer(quiet: bool, config_name: str | None = None) -> if int(next(meminfo).split()[1]) < 3 * 1024 * 1024: os.environ["NODE_OPTIONS"] = "--max-old-space-size=1536" webpack_args = [ - "../node_modules/.bin/webpack-cli", + *webpack_command, + "build", "--mode=production", f"--env=ZULIP_VERSION={ZULIP_VERSION}", ] @@ -45,8 +53,9 @@ def build_for_dev_server(host: str, port: str, minify: bool, disable_host_check: # This is our most dynamic configuration, which we use for our # dev server. The key piece here is that we identify changes to # files as devs make edits and serve new assets on the fly. - webpack_args = ["../node_modules/.bin/webpack-cli", "serve"] - webpack_args += [ + webpack_args = [ + *webpack_command, + "serve", # webpack-cli has a bug where it ignores --watch-poll with # multi-config, and we don't need the katex part anyway. "--config-name=frontend", diff --git a/web/debug-require-webpack-plugin.ts b/web/debug-require-webpack-plugin.ts index bea2255d8a..17a039eafa 100644 --- a/web/debug-require-webpack-plugin.ts +++ b/web/debug-require-webpack-plugin.ts @@ -5,11 +5,10 @@ import path from "node:path"; import type {ResolveRequest} from "enhanced-resolve"; -import type {Chunk, Compiler, WebpackPluginInstance} from "webpack"; -import {NormalModule, Template} from "webpack"; +import webpack from "webpack"; -export default class DebugRequirePlugin implements WebpackPluginInstance { - apply(compiler: Compiler): void { +export default class DebugRequirePlugin implements webpack.WebpackPluginInstance { + apply(compiler: webpack.Compiler): void { const resolved = new Map>(); const nameSymbol = Symbol("DebugRequirePluginName"); type NamedRequest = ResolveRequest & { @@ -63,7 +62,7 @@ export default class DebugRequirePlugin implements WebpackPluginInstance { debugRequirePath = await new Promise((resolve) => { resolver.resolve( {}, - __dirname, + import.meta.dirname, "./debug-require.js", {}, (err?: Error | null, result?: string | false) => { @@ -77,7 +76,7 @@ export default class DebugRequirePlugin implements WebpackPluginInstance { compiler.hooks.compilation.tap("DebugRequirePlugin", (compilation) => { compilation.mainTemplate.hooks.bootstrap.tap( "DebugRequirePlugin", - (source: string, chunk: Chunk) => { + (source: string, chunk: webpack.Chunk) => { if (compilation.chunkGraph === undefined) { return source; } @@ -87,7 +86,7 @@ export default class DebugRequirePlugin implements WebpackPluginInstance { compilation.chunkGraph.hasModuleInGraph( chunk, (m) => { - if (m instanceof NormalModule) { + if (m instanceof webpack.NormalModule) { const id = compilation.chunkGraph.getModuleId(m); if (id === null) { return false; @@ -113,7 +112,7 @@ export default class DebugRequirePlugin implements WebpackPluginInstance { } ids.sort(); - return Template.asString([ + return webpack.Template.asString([ source, `__webpack_require__.debugRequireIds = ${JSON.stringify( Object.fromEntries(ids), diff --git a/web/webpack.config.ts b/web/webpack.config.ts index 7fff3a083d..11a3c4c20a 100644 --- a/web/webpack.config.ts +++ b/web/webpack.config.ts @@ -1,6 +1,7 @@ /// import path from "node:path"; +import * as url from "node:url"; import type {ZopfliOptions} from "@gfx/zopfli"; import {gzip} from "@gfx/zopfli"; @@ -8,13 +9,12 @@ import CompressionPlugin from "compression-webpack-plugin"; import CssMinimizerPlugin from "css-minimizer-webpack-plugin"; import HtmlWebpackPlugin from "html-webpack-plugin"; import MiniCssExtractPlugin from "mini-css-extract-plugin"; -import {DefinePlugin} from "webpack"; -import type webpack from "webpack"; +import webpack from "webpack"; import BundleTracker from "webpack-bundle-tracker"; import DebugRequirePlugin from "./debug-require-webpack-plugin.ts"; -import assets from "./webpack.assets.json"; -import dev_assets from "./webpack.dev-assets.json"; +import assets from "./webpack.assets.json" with {type: "json"}; +import dev_assets from "./webpack.dev-assets.json" with {type: "json"}; const config = ( env: {minimize?: true; puppeteer_tests?: true; ZULIP_VERSION?: string} = {}, @@ -24,23 +24,23 @@ const config = ( const baseConfig: webpack.Configuration = { mode: production ? "production" : "development", - context: __dirname, + context: import.meta.dirname, cache: { type: "filesystem", buildDependencies: { - config: [__filename], + config: [import.meta.filename], }, }, }; const plugins: webpack.WebpackPluginInstance[] = [ - new DefinePlugin({ + new webpack.DefinePlugin({ DEVELOPMENT: JSON.stringify(!production), ZULIP_VERSION: JSON.stringify(env.ZULIP_VERSION ?? "development"), }), new DebugRequirePlugin(), new BundleTracker({ - path: path.join(__dirname, production ? ".." : "../var"), + path: path.join(import.meta.dirname, production ? ".." : "../var"), filename: production ? "webpack-stats-production.json" : "webpack-stats-dev.json", }), // Extract CSS from files @@ -79,17 +79,17 @@ const config = ( module: { rules: [ { - test: require.resolve("./src/zulip_test.ts"), + test: path.resolve(import.meta.dirname, "src/zulip_test.ts"), loader: "expose-loader", options: {exposes: "zulip_test"}, }, { - test: require.resolve("./debug-require.js"), + test: path.resolve(import.meta.dirname, "debug-require.js"), loader: "expose-loader", options: {exposes: "require"}, }, { - test: require.resolve("jquery"), + test: url.fileURLToPath(import.meta.resolve("jquery")), loader: "expose-loader", options: {exposes: ["$", "jQuery"]}, }, @@ -119,15 +119,15 @@ const config = ( { test: /\.[cm]?[jt]s$/, include: [ - path.resolve(__dirname, "shared/src"), - path.resolve(__dirname, "src"), + path.resolve(import.meta.dirname, "shared/src"), + path.resolve(import.meta.dirname, "src"), ], loader: "babel-loader", }, // regular css files { test: /\.css$/, - exclude: path.resolve(__dirname, "styles"), + exclude: path.resolve(import.meta.dirname, "styles"), use: [ MiniCssExtractPlugin.loader, { @@ -141,7 +141,7 @@ const config = ( // PostCSS loader { test: /\.css$/, - include: path.resolve(__dirname, "styles"), + include: path.resolve(import.meta.dirname, "styles"), use: [ MiniCssExtractPlugin.loader, { @@ -198,7 +198,7 @@ const config = ( ], }, output: { - path: path.resolve(__dirname, "../static/webpack-bundles"), + path: path.resolve(import.meta.dirname, "../static/webpack-bundles"), publicPath: "auto", filename: production ? "[name].[contenthash].js" : "[name].js", assetModuleFilename: production @@ -272,7 +272,7 @@ const config = ( "katex-cli": "shebang-loader!katex/cli", }, output: { - path: path.resolve(__dirname, "../static/webpack-bundles"), + path: path.resolve(import.meta.dirname, "../static/webpack-bundles"), }, };