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

@wide/forge

v2.3.3

Published

Zero-based configuration builder for frontend integration projects.

Downloads

30

Readme

Forge

Zero-based configuration builder for frontend integration project, made for those you want:

  • a builder made for static website, working out-of-the-box with no config needed
  • control over the source, the compilation and the destination, unlike Webpack
  • extendable low-level vanilla tasks instead of the Gulp stream-thing
  • preconfigured well-known libs such as sass, babel, parcel or twig
  • no black magic

Install

npm install @wide/forge --save-dev

Usage

Commands

Global commands

  • start server and watch changes: forge serve --open
  • build project for production: forge build --production

Specific commands

  • clear dist folder: forge nuke
  • compile specific assets: forge compile sass js
  • copy static assets to dist: forge copy

Minimal folder structure

Forge needs a specific folder structure in order to work without configuration:

src/
  assets/
    icons/*.svg
    scss/*.scss
    js/*.js
  *.twig

will be compiled into:

dist/
  assets/
    sprite.svg
    *.css
    *.js
  *.html

HTML / TWIG

  • source files: /src/**.twig
  • destination: /dist/**.html
  • compiled using twig

Path config

To changethe path config config, create/edit the .forgerc.js file at the root of your project:

module.exports = {

  // override twig path config
  twig: {

    // files to watch in /src, will trigger the compilation when changed
    observe: '**/*.{twig,html}', // watch src/index.twig and src/foo/bar.twig

    // in src/, files to compile, should be pages only
    entries: [
      '**.twig',      // build all twig into html (root = pages)
    ],

    // do not compile twig file in layouts/ nor components/
    exclude: [
      'layouts/**.twig',
      'components/**.twig'
    ],

    // in dist/, subfolder to generate HTML files into
    // ex: pages ->  dist/pages/index.html
    output: '', // no subfolder -> dist/index.html

    // if true, build all file at dist level only
    // ex: src/foo/bar.twig -> dist/bar.twig (foo subfolder is ignored)
    flatten: false,

    // commands to execute around the compilation
    hooks: {

      // run before the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      before(target, compiled) {},

      // run after the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      after(target, compiled) {}
    }
  }
}

Twig config

To edit the config of twig itself, create a .twigrc.js file at the root of your project, it accepts the following props:

module.exports = {

  // alias of path, see https://github.com/twigjs/twig.js/wiki#namespaces
  namespace: {
    'foo': 'src/foo' // {% include 'foo::index.twig' %} => {% include '/src/foo/index.twig' %}
  },

  // global data injected in all templates
  data: {
    foo: 'bar' // {{ foo }}
  },

  // custom functions, see https://github.com/twigjs/twig.js/wiki/Extending-twig.js
  functions: {
    foo() {} // {% foo() %}
  },

  // custom filters, see https://github.com/twigjs/twig.js/wiki/Extending-twig.js
  filters: {
    foo() {} // {% myvar | foo %}
  },

  // post-process middlewares
  postprocess: {
    beautify: true, // built-in post-process
    foo(html) {     // custom post-process
      return doSomething(html)
    }
  }
}

Notes:

  • postprocess: Forge comes with a set of post-process to enhance the quality of the generated HTML:
    • beautify: use js-beautify to format the whole page, accepts these values:
      • false disable the post-process
      • true enable the post-process (default)
      • {} enable and pass custom config

CSS / SASS

  • source files: /src/assets/**/*.{sass,scss}
  • destination: /dist/assets/*.css and /dist/assets/*.css.map
  • compiled using sass-embedded

Path config

To change the path config, create a .forgerc.js file at the root of your project with a sass prop:

module.exports = {
  sass: {

    // files to watch in /src, will trigger the compilation when changed
    observe: '**/*.{scss,sass}',

    // in src/, files to compile, must be root level only
    entries: [
      'assets/{scss,sass}/*.{scss,sass}'
    ],

    // in dist/, subfolder to generate CSS files into
    output: 'assets/', // -> dist/assets/main.css

    // if true, build all file at dist level only
    // ex: src/assets/foo/bar.scss -> dist/assets/bar.css (foo subfolder is ignored)
    flatten: false,

    // commands to execute around the compilation
    hooks: {

      // run before the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      before(target, compiled) {},

      // run after the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      after(target, compiled) {}
    }
  }
}

SASS config

To edit the config of sass itself, create a .sassrc.js file at the root of your project, it accepts the following props:

module.exports = {

  // path to look-up
  loadPaths: [],

  // enable of disable minification, see https://sass-lang.com/documentation/js-api/modules#OutputStyle
  style: 'compressed', // or 'expanded'

  // source map (by default enabled on dev instances)
  sourceMap: true,

  // post-process middlewares
  postprocess: {
    autoprefixer: false, // built-in post-process
    foo(css) {           // custom post-process
      return doSomething(css)
    }
  },

  // ... and all others props described here:
  // https://sass-lang.com/documentation/js-api/interfaces/Options
}

Notes:

  • loadPaths includes ./ and ./node_modules/ by default
  • style is compressed on PRODUCTION by default
  • sourceMap is disabled on PRODUCTION by default
  • postprocess: Forge comes with a set of post-process to enhance the quality of the generated CSS
    • autoprefixer: use autoprefixer to add browser-specific prefixes:
      • false disable the post-process
      • true enable the post-process (default)
      • {} enable and pass custom config, see official doc

JS / ESNEXT

  • source files: /src/assets/**/*.js
  • destination: /dist/assets/*.js and /dist/assets/*.js.map
  • compiled using parcel

Path config

To change the path config, create a .forgerc.js file at the root of your project with a js prop:

module.exports = {
  js: {

    // files to watch in /src, will trigger the compilation when changed
    observe: '**/*.js',

    // in src/, files to compile
    entries: [
      'assets/js/*.js', // build all root level files
    ],

    // exclude polyfills from compilation
    exclude: [
      'assets/js/polyfills/**.js'
    ]

    // in dist/, subfolder to generate JS files into
    output: 'assets/', // -> dist/assets/main.js

    // if true, build all file at dist level only
    // ex: src/assets/foo/bar.js -> dist/assets/bar.js (foo subfolder is ignored)
    flatten: false,

    // commands to execute around the compilation
    hooks: {

      // run before the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      before(target, compiled) {},

      // run after the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      after(target, compiled) {}
    }
  }
}

Parcel config

To edit the config of parcel itself, create a .parcelrc.js file at the root of your project:

module.exports = {
  // all props described here:
  // https://parceljs.org/api.html
}

Notes:

  • outDir and outFile are reserved, do not change
  • watch, cache, contentHash and autoinstall must remain false
  • minify is true on PRODUCTION by default
  • this file is for advanced users, don't mess up :D

Babel config

Parcel is using babel to transpile ES standards, to edit the config of babel, create a .babelrc.js file at the root of your project:

module.exports = {
  // all props described here:
  // https://babeljs.io/docs/en/6.26.3/babelrc
}

SVG Sprite

  • source files: /src/assets/icons/*.svg
  • destination: /dist/assets/sprite.svg
  • compiled using svg-sprite

Path config

To change the path config, create a .forgerc.js file at the root of your project with a svg prop:

module.exports = {
  svg: {

    // in /src, files to watch, will trigger the compilation when changed
    observe: '**/*.svg',

    // in src/, files to compile, must be root level only
    entries: [
      'assets/icons/*.svg'
    ],

    // in dist/, subfolder to generate the sprite file into
    output: 'assets/',

    // commands to execute around the compilation
    hooks: {

      // run before the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      before(target, compiled) {},

      // run after the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      after(target, compiled) {}
    }
  }
}

SVG-Sprite config

To edit the config of svg-sprite itself, create a .svgrc.js file at the root of your project:

module.exports = {
  // all props described here:
  // https://www.npmjs.com/package/svg-sprite#configuration-basics
}

Notes:

  • dest is reserved, do not change
  • mode.symbol.sprite is sprite.svg by default
  • mode.exemple is false on PRODUCTION by default

Favicons

  • source files: /src/assets/favicon.png
  • destination: /dist/assets/favicons
  • compiled using favicons

Path config

To change the path config, create a .forgerc.js file at the root of your project with a favicons prop:

module.exports = {
  favicons: {

    // in /src, files to watch, will trigger the compilation when changed
    observe: 'assets/favicon.png',

    // in src/, file to compile, must be root level only
    entries: 'assets/favicons.png',

    // in dist/, subfolder to generate the sprite file into
    output: 'assets/favicons/',

    // commands to execute around the compilation
    hooks: {

      // run before the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      before(target, compiled) {},

      // run after the compilation, can be a string "npm run something"
      // or a function receiving the current target and the compiled files
      after(target, compiled) {}
    }
  }
}

Favicons config

To edit the config of favicons itself, create a .faviconsrc.js file at the root of your project:

module.exports = {
  // all props described here:
  // https://github.com/itgalaxy/favicons#usage
}

Other assets

For all others assets (images, documents...), Forge simply copy them into the dist/ folder.

  • source files: /src/assets/**
  • destination: /dist/assets/**

Path config

To change the path config, create a .forgerc.js file at the root of your project with a copy prop:

module.exports = {
  copy: {

    // in src/, files to copy
    entries: [
      'assets/**'
    ],

    // ignore to-be-compiled assets
    exclude: [
      'assets/icons/**',
      'assets/scss/**',
      'assets/js/**'
    ]
  }
}

Advanced usage

Add a compiler

To add a new asset compiler, like Handlebars, follow this exemple:

.forgerc.js
{

  // add a new hbs compiler
  compilers: {
    
    /**
     * Compile handlebars templates
     * @param {Object} ctx
     * @param {Array}  ctx.files to compile into HTML
     * @param {String} ctx.base relative path from wildcard (ex: templates/pages/**.hbs -> templates/pages/foo/bar.hbs -> foo/)
     * @param {String} ctx.dest folder (output + hbs.output -> dist/) 
     * @return {Array<Object>} the list of generated files with their octal size [{ filename, size }]
     */
    hbs({ files, base, dest }) {
      return [{
        filename: 'compiled-file.html',
        size: 1024
      }]
    }

  },

  // rewrite targets to replace twig with hbs
  targets: ['hbs', 'scss', 'js', 'svg'],

  // define hbs target config
  hbs: {
    observe: '**/*.{hbs,html}',
    entries: [
      '**.hbs'
    ],
    exclude: [
      'layouts/**.hbs',
      'components/**.hbs'
    ],
    output: ''
  }
}

Add a command

To add a command not related to compilation, follow this exemple:

.forgerc.js
{
  commands: {
    sayhello(argv) {
      console.log('Hello', ...argv._)
    }
  }
}

Then the command is available using:

forge sayhello you # Hello you

Authors

License

This project is licensed under the MIT License - see the licence file for details