github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/webpack.app.js (about)

     1  // Copyright 2019 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  "use strict";
    12  
    13  const path = require("path");
    14  const rimraf = require("rimraf");
    15  const webpack = require("webpack");
    16  const CopyWebpackPlugin = require("copy-webpack-plugin");
    17  const VisualizerPlugin = require("webpack-visualizer-plugin");
    18  
    19  // Remove a broken dependency that Yarn insists upon installing before every
    20  // Webpack compile. We also do this when installing dependencies via Make, but
    21  // it"s common to run e.g. `yarn add` manually without re-running Make, which
    22  // will reinstall the broken dependency. The error this dependency causes is
    23  // horribly cryptic, so it"s important to remove it aggressively.
    24  //
    25  // See: https://github.com/yarnpkg/yarn/issues/2987
    26  class RemoveBrokenDependenciesPlugin {
    27    apply(compiler) {
    28      compiler.plugin("compile", () => rimraf.sync("./node_modules/@types/node"));
    29    }
    30  }
    31  
    32  let DashboardPlugin;
    33  try {
    34    DashboardPlugin = require("./opt/node_modules/webpack-dashboard/plugin");
    35  } catch (e) {
    36    DashboardPlugin = class { apply() { /* no-op */ } };
    37  }
    38  
    39  const proxyPrefixes = ["/_admin", "/_status", "/ts", "/login", "/logout"];
    40  function shouldProxy(reqPath) {
    41    if (reqPath === "/") {
    42      return true;
    43    }
    44    return proxyPrefixes.some((prefix) => (
    45      reqPath.startsWith(prefix)
    46    ));
    47  }
    48  
    49  // tslint:disable:object-literal-sort-keys
    50  module.exports = (env, argv) => {
    51    let localRoots = [path.resolve(__dirname)];
    52    if (env.dist === "ccl") {
    53      // CCL modules shadow OSS modules.
    54      localRoots.unshift(path.resolve(__dirname, "ccl"));
    55    }
    56  
    57    return {
    58      entry: ["./src/index.tsx"],
    59      output: {
    60        filename: "bundle.js",
    61        path: path.resolve(__dirname, `dist${env.dist}`),
    62      },
    63  
    64      mode: argv.mode || "production",
    65  
    66      resolve: {
    67        // Add resolvable extensions.
    68        extensions: [".ts", ".tsx", ".js", ".json", ".styl", ".css"],
    69        // First check for local modules, then for third-party modules from
    70        // node_modules.
    71        //
    72        // These module roots are transformed into absolute paths, by
    73        // path.resolve, to ensure that only the exact directory is checked.
    74        // Relative paths would trigger the resolution behavior used by Node.js
    75        // for "node_modules", i.e., checking for a "node_modules" directory in
    76        // the current directory *or any parent directory*.
    77        modules: [
    78          ...localRoots,
    79          path.resolve(__dirname, "node_modules"),
    80        ],
    81        alias: {oss: path.resolve(__dirname)},
    82      },
    83  
    84      module: {
    85        rules: [
    86          { test: /\.css$/, use: [ "style-loader", "css-loader" ] },
    87          {
    88            test: /\.module\.styl$/,
    89            use: [
    90              "cache-loader",
    91              "style-loader",
    92              {
    93                loader: "css-loader",
    94                options: {
    95                  modules: {
    96                    localIdentName: "[local]--[hash:base64:5]",
    97                  },
    98                  importLoaders: 1,
    99                },
   100              },
   101              {
   102                loader: "stylus-loader",
   103                options: {
   104                  use: [require("nib")()],
   105                },
   106              },
   107            ],
   108          },
   109          {
   110            test: /(?<!\.module)\.styl$/,
   111            use: [
   112              "cache-loader",
   113              "style-loader",
   114              "css-loader",
   115              {
   116                loader: "stylus-loader",
   117                options: {
   118                  use: [require("nib")()],
   119                },
   120              },
   121            ],
   122          },
   123          {
   124            test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
   125            loader: "url-loader",
   126            options: {
   127              limit: 10000,
   128            },
   129          },
   130          { test: /\.html$/, loader: "file-loader" },
   131          {
   132            test: /\.js$/,
   133            include: localRoots,
   134            use: ["cache-loader", "babel-loader"],
   135          },
   136          {
   137            test: /\.(ts|tsx)?$/,
   138            include: localRoots,
   139            exclude: /\/node_modules/,
   140            use: [
   141              "cache-loader",
   142              "babel-loader",
   143              { loader: "ts-loader", options: { happyPackMode: true } },
   144            ],
   145          },
   146  
   147          // All output ".js" files will have any sourcemaps re-processed by "source-map-loader".
   148          {
   149            enforce: "pre",
   150            test: /\.js$/,
   151            loader: "source-map-loader",
   152            include: localRoots,
   153            exclude: /\/node_modules/,
   154          },
   155        ],
   156      },
   157  
   158      plugins: [
   159        new RemoveBrokenDependenciesPlugin(),
   160        // See "DLLs for speedy builds" in the README for details.
   161        new webpack.DllReferencePlugin({
   162          context: path.resolve(__dirname, `dist${env.dist}`),
   163          manifest: require(`./protos.${env.dist}.manifest.json`),
   164        }),
   165        new webpack.DllReferencePlugin({
   166          context: path.resolve(__dirname, `dist${env.dist}`),
   167          manifest: require("./vendor.oss.manifest.json"),
   168        }),
   169        new CopyWebpackPlugin([{ from: "favicon.ico", to: "favicon.ico" }]),
   170        new DashboardPlugin(),
   171        new VisualizerPlugin({ filename: `../dist/stats.${env.dist}.html` }),
   172      ],
   173  
   174      stats: "errors-only",
   175  
   176      devServer: {
   177        contentBase: path.join(__dirname, `dist${env.dist}`),
   178        index: "",
   179        proxy: {
   180          "/": {
   181            secure: false,
   182            target: process.env.TARGET,
   183          },
   184        },
   185      },
   186  
   187      watchOptions: {
   188        poll: 1000,
   189        ignored: /node_modules/,
   190      },
   191  
   192      // Max size of is set to 4Mb to disable warning message and control
   193      // the growing size of bundle over time.
   194      performance: {
   195        maxEntrypointSize: 4000000,
   196        maxAssetSize: 4000000,
   197      },
   198    };
   199  };