npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-app-rewire-multiple-entry-extended

v2.2.2

Published

Multiple Entry Support for Create-React-App

Downloads

2

Readme

React App Rewire Multiple Entry - Extendend Version

React App Rewire Multiple Entry Extendend is a fork of React App Rewire Multiple Entry that lets you configure multiple entries in Create React App without ejecting.

This fork allows you to omit the hash in the compiled filenames. Use the original unless you really need this functionality. This module has only been published as the PR with the changes has not been merged to React App Rewire Multiple Entry yet.

Usage

  1. Add React App Rewire Multiple Entry Extendend to your Rewired React app:

    npm install --save-dev react-app-rewired react-app-rewire-multiple-entry-extendend

    or

    yarn add -D react-app-rewired react-app-rewire-multiple-entry-extendend

    For create-react-app 1.x or react-scripts-ts with Webpack 3

    npm install --save-dev [email protected]

    or

    yarn add -D [email protected]
  2. Modify package.json

      "scripts": {
    -   "start": "react-scripts start",
    +   "start": "react-app-rewired start",
    -   "build": "react-scripts build",
    +   "build": "react-app-rewired build",
    -   "test": "react-scripts test",
    +   "test": "react-app-rewired test",
        "eject": "react-scripts eject"
    }
  3. Add React App Rewire Multiple Entry to config-overrides.js in your React app directory:

    Basic Usage

    // config-overrides.js
       
    const multipleEntry = require('react-app-rewire-multiple-entry-extended')([
      {
        entry: 'src/entry/landing.js',
        template: 'public/landing.html',
        outPath: '/landing.html'
      }
    ]);
       
    module.exports = {
      webpack: function(config, env) {
        multipleEntry.addMultiEntry(config);
        return config;
      }
    };

    Work with customize-cra

    // config-overrides.js
       
    const multipleEntry = require('react-app-rewire-multiple-entry-extended')([
      {
        entry: 'src/entry/landing.js',
        template: 'public/landing.html',
        outPath: '/landing.html'
      }
    ]);
       
    const {
      // addBundleVisualizer,
      override,
      overrideDevServer
    } = require('customize-cra');
       
    module.exports = {
      webpack: override(
        multipleEntry.addMultiEntry
        // addBundleVisualizer()
      )
    };

Extended example

When running the React build script with the example settings above the filenames will have two hashes appended to it, one appended by the React webpack and one appended by react-app-rewire-multiple-entry. To remove all hashes from the filenames and store the hashes in a JSON-file one can use the following:

// webpack-metadata-plugin - will write hashes to meta.json
const fs = require("fs");

class MetadataPlugin {
  constructor(options) {
    this.options = { filename: "meta.json", ...options };
  }

  apply(compiler) {
    compiler.hooks.done.tap(this.constructor.name, (stats) => {
      const metaInfo = {
        hash: stats.hash,
      };
      stats.compilation.chunks.forEach((chunk) => {
        metaInfo[chunk.name] = chunk.hash;
      });
      const json = JSON.stringify(metaInfo);
      return new Promise((resolve, reject) => {
        fs.writeFile(this.options.filename, json, "utf8", (error) => {
          if (error) {
            reject(error);
            return;
          }
          resolve();
        });
      });
    });
  }
}

module.exports = MetadataPlugin;
// config-overrides.js
const path = require("path");
const MetadataPlugin = require("./webpack-metadata-plugin");

const multipleEntry = require("react-app-rewire-multiple-entry-extended")([
  {
    name: "discovery",
    entry: path.resolve(__dirname, "./src/entries/entry-discovery.tsx"),
    outPath: "discovery.html",
    template: path.resolve(__dirname, "./src/entries/templates/discovery.html"),
    omitHash: true,
  },
  {
    name: "global-search",
    entry: path.resolve(__dirname, "./src/entries/entry-global-search.tsx"),
    outPath: "global-search.html",
    template: path.resolve(__dirname, "./src/entries/templates/global-search.html"),
    omitHash: true,
  },
  {
    name: "tools",
    entry: path.resolve(__dirname, "./src/entries/entry-tools.tsx"),
    outPath: "tools.html",
    template: path.resolve(__dirname, "./src/entries/templates/tools.html"),
    omitHash: true,
  },
  {
    name: "articles",
    entry: path.resolve(__dirname, "./src/entries/entry-articles.tsx"),
    outPath: "articles.html",
    template: path.resolve(__dirname, "./src/entries/templates/articles.html"),
    omitHash: true,
  },
]);

module.exports = function (config, env) {

  // Filenames
  config.output.filename = "static/js/[name].js";
  config.output.chunkFilename = "static/js/[name].js";

  // Group common vendor files in separate chunk named common
  config.optimization.splitChunks = {
    cacheGroups: {
      default: false,
      commons: {
        test: /node_modules/,
        chunks: "initial",
        name: "commons",
        enforce: true,
      },
    },
  };
  config.optimization.runtimeChunk = false;

  // Add entries
  multipleEntry.addMultiEntry(config);

  // Add metadata plugin to store hashes
  if (!config.plugins) {
    config.plugins = [];
  }
  config.plugins.push(new MetadataPlugin({ filename: "meta.json" }));

  config.plugins.forEach((item) => {
    // CSS filenames
    if (item.constructor.name === "MiniCssExtractPlugin") {
      item.options.filename = "static/css/[name].css";
      item.options.chunkFilename = "static/css/[name].css";
    }
  });

  return config;
};

Results

Files generated:

  233.96 KB  build/static/js/commons.js
  10.93 KB   build/static/js/main.js
  8.92 KB    build/static/js/entry-discovery.js
  5.36 KB    build/static/js/entry-global-search.js
  5.29 KB    build/static/js/entry-tools.js
  5.08 KB    build/static/js/entry-articles.js
  4.11 KB    build/static/css/commons.css
  722 B      build/static/css/main.css
  642 B      build/static/css/entry-discovery.css
  642 B      build/static/css/entry-global-search.css
  332 B      build/static/css/entry-articles.css
  330 B      build/static/css/entry-tools.css

Content of meta.json:

{
    "hash":"2fda073f19bb5635aedf",
    "commons":"b5e90583e0d99b8e7d9576dee51db10d",
    "entry-articles":"a267eadd80c030b7861f10139cebae21",
    "entry-discovery":"0f8b3ae0f35916868424224d023524ba",
    "entry-global-search":"fa42f87c40e6f17b64975fd8bdf14fe0",
    "entry-tools":"b1b720f91dd3bc8f3cd1e2e009684e28",
    "main":"1cff87efd698e63902b75974f4695346"
}

If one needs to have different hashes for the CSS and JS files with the same entry name, for example entry-discovery.js and entry-discovery.css, then the metadata plugin has to be changed.

API

Options

You can pass a array of entry configuration options to react-app-rewire-multiple-entry, the entry in the array has attributes below:

  • entry [Required] Webpack entry JS file. Throw error when empty.
  • template [Optional] HTML template used in plugin HtmlWebpackPlugin. Default value: public/index.html.
  • outPath: [Optional] The file wirte the HTML to. You can specify a subdirectory. If empty, it will be calculated by path.relative(process.cwd(), template)

Method

  • addMultiEntry Inject settings for multiple entry in webpack config

That’s it! Now you can control mulitple entries and omitting the hashes, enjoy coding!