static getCssModule(webpack) {
    /**
     * Prevent creation of multiple CssModule classes to allow other integrations to get the current CssModule.
     */
    if (cssModuleCache.has(webpack)) {
      return /** @type {CssModuleConstructor} */ (cssModuleCache.get(webpack));
    }

    class CssModule extends webpack.Module {
      /**
       * @param {CssModuleDependency} dependency
       */
      constructor({
        context,
        identifier,
        identifierIndex,
        content,
        layer,
        supports,
        media,
        sourceMap,
        assets,
        assetsInfo,
      }) {
        // @ts-ignore
        super(MODULE_TYPE, /** @type {string | undefined} */ (context));

        this.id = "";
        this._context = context;
        this._identifier = identifier;
        this._identifierIndex = identifierIndex;
        this.content = content;
        this.layer = layer;
        this.supports = supports;
        this.media = media;
        this.sourceMap = sourceMap;
        this.assets = assets;
        this.assetsInfo = assetsInfo;
        this._needBuild = true;
      }

      // no source() so webpack 4 doesn't do add stuff to the bundle

      size() {
        return this.content.length;
      }

      identifier() {
        return `css|${this._identifier}|${this._identifierIndex}|${
          this.layer || ""
        }|${this.supports || ""}|${this.media}}}`;
      }

      /**
       * @param {Parameters<Module["readableIdentifier"]>[0]} requestShortener
       * @returns {ReturnType<Module["readableIdentifier"]>}
       */
      readableIdentifier(requestShortener) {
        return `css ${requestShortener.shorten(this._identifier)}${
          this._identifierIndex ? ` (${this._identifierIndex})` : ""
        }${this.layer ? ` (layer ${this.layer})` : ""}${
          this.supports ? ` (supports ${this.supports})` : ""
        }${this.media ? ` (media ${this.media})` : ""}`;
      }

      // eslint-disable-next-line class-methods-use-this
      getSourceTypes() {
        return TYPES;
      }

      // eslint-disable-next-line class-methods-use-this
      codeGeneration() {
        return CODE_GENERATION_RESULT;
      }

      nameForCondition() {
        const resource =
          /** @type {string} */
          (this._identifier.split("!").pop());
        const idx = resource.indexOf("?");

        if (idx >= 0) {
          return resource.substring(0, idx);
        }

        return resource;
      }

      /**
       * @param {Module} module
       */
      updateCacheModule(module) {
        if (
          !this.content.equals(/** @type {CssModule} */ (module).content) ||
          this.layer !== /** @type {CssModule} */ (module).layer ||
          this.supports !== /** @type {CssModule} */ (module).supports ||
          this.media !== /** @type {CssModule} */ (module).media ||
          (this.sourceMap
            ? !this.sourceMap.equals(
                /** @type {Uint8Array} **/
                (/** @type {CssModule} */ (module).sourceMap)
              )
            : false) ||
          this.assets !== /** @type {CssModule} */ (module).assets ||
          this.assetsInfo !== /** @type {CssModule} */ (module).assetsInfo
        ) {
          this._needBuild = true;

          this.content = /** @type {CssModule} */ (module).content;
          this.layer = /** @type {CssModule} */ (module).layer;
          this.supports = /** @type {CssModule} */ (module).supports;
          this.media = /** @type {CssModule} */ (module).media;
          this.sourceMap = /** @type {CssModule} */ (module).sourceMap;
          this.assets = /** @type {CssModule} */ (module).assets;
          this.assetsInfo = /** @type {CssModule} */ (module).assetsInfo;
        }
      }

      // eslint-disable-next-line class-methods-use-this
      needRebuild() {
        return this._needBuild;
      }

      // eslint-disable-next-line class-methods-use-this
      /**
       * @param {Parameters<Module["needBuild"]>[0]} context context info
       * @param {Parameters<Module["needBuild"]>[1]} callback callback function, returns true, if the module needs a rebuild
       */
      needBuild(context, callback) {
        // eslint-disable-next-line no-undefined
        callback(undefined, this._needBuild);
      }

      /**
       * @param {Parameters<Module["build"]>[0]} options
       * @param {Parameters<Module["build"]>[1]} compilation
       * @param {Parameters<Module["build"]>[2]} resolver
       * @param {Parameters<Module["build"]>[3]} fileSystem
       * @param {Parameters<Module["build"]>[4]} callback
       */
      build(options, compilation, resolver, fileSystem, callback) {
        this.buildInfo = {
          assets: this.assets,
          assetsInfo: this.assetsInfo,
          cacheable: true,
          hash: this._computeHash(
            /** @type {string} */ (compilation.outputOptions.hashFunction)
          ),
        };
        this.buildMeta = {};
        this._needBuild = false;

        callback();
      }

      /**
       * @private
       * @param {string} hashFunction
       * @returns {string | Buffer}
       */
      _computeHash(hashFunction) {
        const hash = webpack.util.createHash(hashFunction);

        hash.update(this.content);

        if (this.layer) {
          hash.update(this.layer);
        }

        hash.update(this.supports || "");
        hash.update(this.media || "");
        hash.update(this.sourceMap || "");

        return hash.digest("hex");
      }

      /**
       * @param {Parameters<Module["updateHash"]>[0]} hash
       * @param {Parameters<Module["updateHash"]>[1]} context
       */
      updateHash(hash, context) {
        super.updateHash(hash, context);

        hash.update(
          /** @type {NonNullable<Module["buildInfo"]>} */ (this.buildInfo).hash
        );
      }

      /**
       * @param {Parameters<Module["serialize"]>[0]} context
       */
      serialize(context) {
        const { write } = context;

        write(this._context);
        write(this._identifier);
        write(this._identifierIndex);
        write(this.content);
        write(this.layer);
        write(this.supports);
        write(this.media);
        write(this.sourceMap);
        write(this.assets);
        write(this.assetsInfo);

        write(this._needBuild);

        super.serialize(context);
      }

      /**
       * @param {Parameters<Module["deserialize"]>[0]} context
       */
      deserialize(context) {
        this._needBuild = context.read();

        super.deserialize(context);
      }
    }

    cssModuleCache.set(webpack, CssModule);

    webpack.util.serialization.register(
      CssModule,
      path.resolve(__dirname, "CssModule"),
      // @ts-ignore
      null,
      {
        serialize(instance, context) {
          instance.serialize(context);
        },
        deserialize(context) {
          const { read } = context;

          const contextModule = read();
          const identifier = read();
          const identifierIndex = read();
          const content = read();
          const layer = read();
          const supports = read();
          const media = read();
          const sourceMap = read();
          const assets = read();
          const assetsInfo = read();
          const dep = new CssModule({
            context: contextModule,
            identifier,
            identifierIndex,
            content,
            layer,
            supports,
            media,
            sourceMap,
            assets,
            assetsInfo,
          });

          dep.deserialize(context);

          return dep;
        },
      }
    );

    return CssModule;
  }
@param {Compiler["webpack"]} webpack
@returns {CssModuleConstructor}