Coder Social home page Coder Social logo

flex-development / webpack-tap-done Goto Github PK

View Code? Open in Web Editor NEW
0.0 3.0 0.0 118 KB

Execute (a)synchronous callbacks after Webpack compilations.

License: BSD 3-Clause "New" or "Revised" License

JavaScript 47.46% TypeScript 44.01% Shell 8.52%
async-callback callback-functions callbacks tapable webpack webpack-compiler webpack-compiler-hooks webpack-hooks webpack-plugin

webpack-tap-done's Introduction

Webpack Tap Done Plugin

TypeScript tested with jest

Overview

Getting Started
Installation
Usage
Built With
Contributing

Getting Started

Execute (a)synchronous callbacks after Webpack compilations. Functions will be called with the stats object.

Installation

  1. Create or edit an .npmrc file with the following information:

    @flex-development:registry=https://npm.pkg.github.com/
    //npm.pkg.github.com/:_authToken=${GH_PAT}
    

    where GH_PAT is your GitHub personal access token with read:packages scope permissions.

  2. Add development dependencies

    yarn add -D @flex-development/webpack-tap-done webpack

    If you're using TypeScript:

    yarn add -D @flex-development/webpack-tap-done webpack ts-node @types/node @types/webpack

Usage

The example below is from a Next.js project that implements an InlineStylesHead component:

const TapDoneWebpackPlugin = require('@flex-development/webpack-tap-done')
const debug = require('debug')
const fse = require('fs-extra')
const path = require('path')

/**
 * @file Next.js Configuration
 * @see https://nextjs.org/docs/api-reference/next.config.js/introduction
 */

/**
 * Copies all files in `.next/static/css` to `.next/${target}/static/css`.
 *
 * This function is required to read CSS files from the server (in Vercel
 * hosting) environments. It's used in lieu of adding a custom CSS configuration
 * to Webpack, which would disbale built-in CSS support.
 *
 * @return {boolean} True if files were succesfully copied, false otherwise
 */
const copyCSSAssets = () => {
  // Initialize logger
  const log = debug('copy-css-assets')

  // Change server directory if in Vercel environment
  const target = `server${process.env.VERCEL ? 'less' : ''}`

  // Client CSS directory
  const src = path.resolve(process.cwd(), '.next/static/css')

  // Server CSS directory
  const dest = path.resolve(process.cwd(), `.next/${target}/static/css`)

  // Copy CSS assets
  fse.copy(src, dest, err => {
    if (err) {
      log(err)
      return false
    }

    log(`Copied ${src} files to ${dest} directory.`)
    return true
  })
}

module.exports = {
  /**
   * Extends the native Webpack configuration.
   *
   * @param {import('webpack').Configuration} config - Webpack config object
   * @param {object} helpers - Next.js helpers
   * @param {boolean} helpers.dev - True if the compiling in development mode
   * @param {boolean} helpers.isServer - `true` for server-side compilation
   * @param {import('webpack')} helpers.webpack - Webpack
   * @return {import('webpack').Configuration} Altered Webpack configuration
   */
  webpack: (config, { dev, isServer }) => {
    /**
     * Callback function to hook into end of Webpack build cycle.
     *
     * In non-dev environments, CSS assets from the client will copied to the
     * server's static CSS directory.
     *
     * This allows us to inline styles via the `InlineStylesHead` component w/o
     * disabling built-in CSS support.
     *
     * @return {void}
     */
    const tapDone = () => {
      if (!dev && !isServer) copyCSSAssets()
    }

    // Add plugin to hook into end of Webpack build cycle
    config.plugins.push(new TapDoneWebpackPlugin(tapDone))
  }
}

The InlineStylesHead component:

import { existsSync, readdirSync, readFileSync } from 'fs'
import { Head } from 'next/document'
import { resolve } from 'path'

/**
 * @file Implementation - InlineStylesHead
 * @module components/InlineStylesHead
 */

/**
 * Allows Critical CSS to be delivered via inline `<style>` tags.
 *
 * This solves the following Lighthouse warning:
 *
 * > "External stylesheets are blocking the first paint of your page.
 * > Consider delivering critical CSS via `<style>` tags and deferring
 * > non-critical styles".
 *
 * @see https://github.com/vercel/next-plugins/issues/238
 * @see https://github.com/vercel/next-plugins/issues/238#issuecomment-696623272
 *
 * @class InlineStylesHead
 * @extends Head
 */
export class InlineStylesHead extends Head {
  /**
   * Returns an array of `<style>` elements containing the styles from each file
   * in the `static/css` directory.
   *
   * @see https://github.com/vercel/vercel/issues/3083#issuecomment-654244864
   * @see https://github.com/vercel/next.js/issues/8251
   */
  getCssLinks(): JSX.Element[] | null {
    const dir = `.next/server${process.env.VERCEL ? 'less' : ''}/static/css`
    const resdir = resolve(process.cwd(), dir)

    if (!existsSync(resdir)) return []

    return readdirSync(resdir).map(file => {
      const $file = resolve(process.cwd(), dir, file)
      let __html = ''

      try {
        __html = readFileSync($file, 'utf-8')
      } catch (error) {
        console.error({ 'InlineStylesHead.getCssLinks': error })
        throw error
      }

      return (
        <style
          dangerouslySetInnerHTML={{ __html }}
          key={file}
          nonce={this.props.nonce}
          type='text/css'
        />
      )
    })
  }
}

Built With

webpack-tap-done's People

Contributors

unicornware avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.