async addAssets(assets, dir) {
    const jsAssetRE = /^[\w-]+\.js$/;
    const names = [];
    for (const filename in assets) {
      if (!jsAssetRE.test(filename)) {
        continue;
      }

      const name = filename.replace(/\.js$/, '');
      if (!exampleDirContents.includes(name)) {
        continue;
      }

      names.push(name);
    }

    if (names.length === 0) {
      return;
    }

    const exampleData = await Promise.all(
      names.map((name) => this.parseExample(dir, name)),
    );

    const examples = exampleData.map((data) => ({
      link: data.filename,
      title: data.title,
      shortdesc: data.shortdesc,
      tags: data.tags,
    }));

    examples.sort((a, b) =>
      a.title.localeCompare(b.title, 'en', {sensitivity: 'base'}),
    );
    const tagIndex = createTagIndex(examples);
    const info = {
      examples: examples,
      // Tags for main page... TODO: implement index tag links
      // tagIndex: sortObjectByKey(tagIndex),
      wordIndex: sortObjectByKey(createWordIndex(examples)),
    };
    exampleData.forEach((data) => {
      data.tags = data.tags.map((tag) => {
        const tagExamples = tagIndex[tag.toLowerCase()];
        return {
          tag: tag,
          examples: tagExamples.map((exampleIdx) => {
            const example = examples[exampleIdx];
            return {
              link: example.link,
              title: example.title,
              isCurrent: data.filename === example.link,
            };
          }),
        };
      });
    });

    const pkg = await getPackageInfo();
    await Promise.all(
      exampleData.map(async (data) => {
        const newAssets = await this.render(data, pkg);
        for (const file in newAssets) {
          assets[file] = new RawSource(newAssets[file]);
        }
      }),
    );

    const indexSource = `const info = ${JSON.stringify(info)};`;
    assets['examples-info.js'] = new RawSource(indexSource);
  }
@param {import('webpack').CompilationAssets} assets Assets
@param {string} dir Examples dir