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

@tygr/async-loader-webpack-plugin

v1.1.1-beta

Published

Get progress updates on loading js

Downloads

13

Readme

[DEPRECATED]

I've decided no longer to support this project due to lack of interest.

If anybody is interested in using it please ask me for help at

[email protected]

Async Loader Webpack Plugin

DEMO

Is your SPA getting unwieldy? Use this plugin to give immediate content to clients while loading large scripts and styles in the background.

When using async-loader-webpack-plugin, an object named AsyncLoader is exposed which emits loading progress events. Write a loading bar in your index.html template file that subscribes to AsyncLoader. Once the scripts have been downloaded and injected and processed by the browser, AsyncLoader will emit a complete event.

This plugin is meant to be used with HtmlWebpackPlugin

Installation

npm install --save-dev @tygr/async-loader-webpack-plugin

yarn add --dev @tygr/async-loader-webpack-plugin

Plugin Options

| option | type | default | description | | :--------- | :--------- | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | chunks | string[] | null | Choose which files to load by specifiying a list of chunks where each chunk's list of files will load asyncronously | | patterns | RegExp[] | null | Choose which files to load by specifying a list of regex patterns that will test each file emitted by webpack | | files | string[] | [] | Choose files manually using a list of strings, each one will be attempted to load asynchronously regardless of whether or not it is emitted by webpack | | extensions | string[] | ['css', 'js'] | Specify which extensions you would like to load asynchronously. Files specified by 'files' option ignores this option | | scriptName | string | 'async-loader' | AsyncLoader will put a script named 'async-loader.js' in your output directory and add it into HTMLWebpackPlugin. You may specify a different name for the script here | | load | boolean | true | Choose whether or not to load files immediately or wait until AsyncLoader.load() is called |

chunks and patterns are mutually exlusive, use one or the other

AsyncLoader Events

AsyncLoader will be injected into the browser globally. To listen to an event from AsyncLoader, call AsyncLoader.addEventListener(<event-name>, <handler>). Access event parameters in your handler by calling ev.detail.<parameter>

| event | parameters | description | | :---------------- | :------------------------------ | :------------------------------------------------------------------------ | | progress | 'percentage', 'loaded', 'total' | Called every time a progress event is recorded while downloading files | | download-complete | none | Called when all files have finished downloading | | complete | none | Called after files have finished being injected and parsed by the browser |

AsyncLoader functions

| name | parameters | description | | :--- | :--------- | :---------------------------------------------------------------------------------------------- | | load | | Load all scripts and inject them. Called immediately by default if load option is set to true |

Setup

You will want to edit the HtmlWebpackPlugin options to exclude the chunks you specify in the AsyncLoader plugin. It's also required that you do not sort the chunks by specifying chunksSortMode: 'none'. You'll also want to inject the scripts in the head so they will be available to you in the body using inject: 'head'.

(webpack.config.js)

const AsyncLoader = require('@tygr/async-loader-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  ...
  plugins: [
    new AsyncLoader({
      chunks: ['app', 'chunk-vendors']
    }),
    new HtmlWebpackPlugin({
      ...,
      excludeChunks: ['app', 'chunk-vendors'],
      chunksSortMode: 'none',
      inject: 'head'
    })
  ]
}

vue CLI setup

When using the vue CLI to create your app, you'll need to edit your webpack config in a root level file named vue.config.js. This configuration also modifies the 'preload' plugin that comes built in automatically. By specifying some scripts to preload, it may slow down your initial render, so it's been modified to specify prefetch instead.

const AsyncLoader = require('@tygr/async-loader-webpack-plugin')

module.exports = {
  configureWebpack: {
    plugins: [ new AsyncLoader({
      chunks: ['app', 'chunk-vendors'],
    }) ]
  },
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => [{
        ...args[0],
        excludeChunks: ['app', 'chunk-vendors'],
        inject: 'head',
        chunksSortMode: 'none'
      }])
    config
      .plugin('preload')
      .tap(args => [{
        ...args[0],
        rel: 'prefetch',
      }])
  }
}

index.html Setup

Inside the index.html template file is where you should hook into the AsyncLoader plugin. It should look something like this:

<html>
  ...
  <body>
    <div id="app"></div>
    <!-- Use the AsyncLoader object (already injected as a global object by the plugin) here -->
    <script>
      AsyncLoader.addEventListener('progress', ev => {
        console.log(ev.detail.percentage)
      })

      AsyncLoader.addEventListener('complete', () => {
        console.log('Finished loading and injecting scripts')
      })
    </script>
  </body>
</html>

Vue tips

If you would like to add an enter website button, modify your src/main.js so that it does not mount the app immediately but instead exposes it to the window object:

// @ts-ignore
window['app'] = new Vue({
  router,
  store,
  render: (h) => h(App),
});

Then, in your public/index.html, wait for a complete event to show the enter button and set the onclick handler to $mount the app:

<html>
  ...
  <body>
    <button id="enter-btn" style="display: none;" onclick="enterApp()">Enter</button>
    <div id="app"></div>
    <script>
      AsyncLoader.addEventListener('complete', () => {
        document.getElementById('enter-btn').style.display = 'block'
      })

      const enterApp = () => {
        document.getElementById('enter-btn').style.display = 'none'
        app.$mount('#app')
      }
    </script>
  </body>
</html>