Skip to content

Commit

Permalink
Initial release of ThemedProgressPlugin 🌈 (#1)
Browse files Browse the repository at this point in the history
* Build beta version of ThemedProgressPlugin 🌈

* Fixed unit tests against compiled code πŸ”§

* Added documentation to the README πŸ“™

* Corrected the image URLs in the README πŸŽ‡

* Release 0.0.1-beta.1 1️⃣

* Add extensions to imports to fix commonJS imports 😐

* Switch to a named export πŸ“›

* Prepare version 1.0.0 release 🌊
  • Loading branch information
01taylop committed Jun 8, 2024
1 parent d42057e commit f120e5e
Show file tree
Hide file tree
Showing 15 changed files with 4,059 additions and 6 deletions.
1 change: 1 addition & 0 deletions .depcheckrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ignores: [
"rimraf"
]
skip-missing: true
39 changes: 39 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Test

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
name: Test
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [16.x, 18.x, 20.x, 22.x]

steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Use Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Install Dependencies
run: yarn install --immutable

- name: Run Tests
run: yarn test --coverage

- name: Run Tests for Compiled Bundles
run: |
yarn build
yarn test:bundles
- name: Depcheck
run: npx depcheck
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,73 @@
[![CodeQL Analysis](https://github.com/01taylop/themed-progress-plugin/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/01taylop/themed-progress-plugin/actions/workflows/codeql-analysis.yml)

A webpack plugin featuring an emoji-themed loading bar for a fun and aesthetic build process.

- [Motivation](#motivation)
- [Example](#example)
- [Usage](#usage)
- [Installation](#installation)
- [Configuration](#configuration)

## Motivation

Traditional compilation processes can often be mundane and provide little visual feedback. `ThemedProgressPlugin` aims to bring a touch of light-hearted fun to everyday coding tasks by introducing a dynamic, emoji-themed loading bar which changes based on the date.

This brings an element of surprise and novelty to the typically routine compilation process, making it a more enjoyable part of the developer's day.

## Example

Normal:

![Progress Bar Normal](https://github.com/01taylop/themed-progress-plugin/blob/main/assets/progress-normal.jpg?raw=true)

During Halloween:

![Progress Bar Themed](https://github.com/01taylop/themed-progress-plugin/blob/main/assets/progress-theme.jpg?raw=true)

## Usage

### Installation

First, install the package as a dependency:

```bash
# Using yarn
yarn add themed-progress-plugin

# Using npm
npm install themed-progress-plugin
```

### Configuration

Configuring `ThemedProgressPlugin` is straightforward. After importing it, you simply need to add it to the plugins array in your webpack configuration.

You can import `ThemedProgressPlugin` using either CommonJS or ES Modules. Here's an example of how to do this:

For CommonJS:

```js
const { ThemedProgressPlugin } = require('themed-progress-plugin')

module.exports = {
// other webpack configuration...
plugins: [
new ThemedProgressPlugin(),
// other plugins...
],
}
```

For ES Modules:

```js
import { ThemedProgressPlugin } from 'themed-progress-plugin'

export default {
// other webpack configuration...
plugins: [
new ThemedProgressPlugin(),
// other plugins...
],
}
```
Binary file added assets/progress-normal.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/progress-theme.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions babel.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"presets": [
["@babel/preset-env", { "targets": { "node": "current" } }]
],
"env": {
"cjs": {
"presets": [["@babel/preset-env", { "modules": "commonjs" }]],
"plugins": [
["babel-plugin-add-import-extension", { "extension": "cjs" }]
]
},
"esm": {
"presets": [["@babel/preset-env", { "modules": false }]],
"plugins": [
["babel-plugin-add-import-extension", { "extension": "js" }]
]
}
}
}
16 changes: 16 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export default {
clearMocks: true,
collectCoverageFrom: [
'src/**/*.js',
],
coverageDirectory: 'coverage',
coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: 100,
},
},
testMatch: ['**/*.spec.js'],
}
10 changes: 10 additions & 0 deletions jest/cjs.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import baseConfig from '../jest.config.js'

export default {
...baseConfig,
moduleNameMapper: {
'<rootDir>/src/config$': '<rootDir>/lib/config.cjs',
'<rootDir>/src/index$': '<rootDir>/lib/index.cjs',
},
rootDir: '../',
}
10 changes: 10 additions & 0 deletions jest/esm.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import baseConfig from '../jest.config.js'

export default {
...baseConfig,
moduleNameMapper: {
'<rootDir>/src/config$': '<rootDir>/lib/config.js',
'<rootDir>/src/index$': '<rootDir>/lib/index.js',
},
rootDir: '../',
}
40 changes: 34 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
{
"name": "themed-progress-plugin",
"description": "A webpack plugin featuring an emoji-themed loading bar for a fun and aesthetic build process.",
"description": "A Webpack plugin featuring an emoji-themed loading bar for a fun and aesthetic build process.",
"repository": {
"type": "git",
"url": "https://github.com/01taylop/themed-progress-plugin"
},
"version": "0.0.1",
"version": "1.0.0",
"type": "module",
"main": "./lib/index.js",
"exports": {
".": {
"import": "./lib/index.js",
"require": "./lib/index.cjs"
}
},
"files": [
"lib"
],
"scripts": {
"build:cjs": "babel src -d lib --env-name cjs --out-file-extension .cjs",
"build:esm": "babel src -d lib --env-name esm --out-file-extension .js",
"build": "rimraf lib && yarn run build:cjs && yarn run build:esm",
"prepublishOnly": "yarn test --coverage && yarn build && yarn test:bundles",
"test": "jest",
"test:bundles": "jest --config ./jest/cjs.config.js && jest --config ./jest/esm.config.js"
},
"peerDependencies": {
"webpack": "^5.0.0"
},
"dependencies": {
"chalk": "4.1.2"
},
"devDependencies": {
"@babel/cli": "7.24.6",
"@babel/core": "7.24.6",
"@babel/preset-env": "7.24.6",
"babel-plugin-add-import-extension": "1.6.0",
"jest": "29.7.0",
"rimraf": "5.0.7",
"webpack": "5.91.0"
},
"author": "Patrick Taylor <[email protected]>",
"keywords": [
"emoji",
"loading",
"plugin",
"progress",
"progress-plugin",
"themed-progress-plugin",
"webpack",
"webpack-plugin"
"themed",
"webpack"
]
}
48 changes: 48 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import chalk from 'chalk'

const dateConfigurations = {
'01-01': ['πŸŽ‰', '⬜️'], // New Year's Day
'02-14': ['🌹', 'πŸ₯€'], // Valentine's Day
'03-17': ['πŸ€', '⬜️'], // St Patrick's Day
'04-01': ['πŸƒ', '⬜️'], // April Fool's Day
'04-10-2025_04-20-2025': ['🐣', 'πŸ₯š'], // Easter 2024
'04-22': ['🌎', '⬜️'], // Earth Day
'06-05': ['🌳', '⬜️'], // World Environment Day
'06-08': ['🌊', '⬜️'], // World Oceans Day
'06-19_06-23': ['β˜€οΈ', '☁️'], // Summer Solstice (21st June)
'07-04': ['πŸŽ†', '⬜️'], // Independence Day (US)
'07-01-2024_07-14-2024': ['🎾', '⬜️'], // Wimbledon 2024 (UK)
'09-05': ['πŸ’–', '🀍'], // International Charity Day
'10-01': ['β˜•οΈ', '⬜️'], // International Coffee Day
'10-24_10-31': ['πŸŽƒ', 'πŸ¦‡'], // Halloween
'12-01_12-31': ['⛄️', '🧊'], // Winter
}

const getProgressConfig = () => {
const currentDate = new Date()
const today = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()).getTime()

const matchingConfig = Object.entries(dateConfigurations).find(([dateRange]) => {
const [startDateString, endDateString] = dateRange.split('_')

const [startMonth, startDay, startYear = currentDate.getFullYear()] = startDateString.split('-').map(Number)
const startDate = new Date(startYear, startMonth - 1, startDay).getTime()

if (!endDateString) {
return startDate === today
}

const [endMonth, endDay, endYear = currentDate.getFullYear()] = endDateString.split('-').map(Number)
const endDate = new Date(endYear, endMonth - 1, endDay).getTime()

return startDate <= today && endDate >= today
})

return matchingConfig
? [matchingConfig[1], 20].flat()
: [chalk.green('\u2588'), chalk.bgWhite(' '), 40]
}

export {
getProgressConfig,
}
38 changes: 38 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import readline from 'readline'
import { ProgressPlugin } from 'webpack'

import { getProgressConfig } from './config'

class ThemedProgressPlugin {
constructor() {
this.progressConfig = getProgressConfig()
this.progressPlugin = new ProgressPlugin(this.handler.bind(this))
}

handler(...args) {
this.progress(...args)
}

progress(percentage, message) {
const [startChar, endChar, progressLength] = this.progressConfig

const percent = (percentage * 100).toFixed()
const segments = Math.floor(progressLength * percentage)
const emptySegments = progressLength - segments

const complete = startChar.repeat(segments)
const incomplete = endChar.repeat(emptySegments)

readline.clearLine(process.stdout, 0)
readline.cursorTo(process.stdout, 0)
process.stdout.write(`${complete}${incomplete} | ${percent}% ${message}`)
}

apply(compiler) {
return this.progressPlugin.apply(compiler)
}
}

export {
ThemedProgressPlugin,
}
41 changes: 41 additions & 0 deletions tests/config.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import chalk from 'chalk'

import { getProgressConfig } from '../src/config'

jest.mock('chalk', () => ({
bgWhite: jest.fn().mockImplementation(text => text),
green: jest.fn().mockImplementation(text => text),
}))

describe('getProgressConfig', () => {

test.each([
['2025-01-01', ['πŸŽ‰', '⬜️', 20]],
['2025-01-02', ['\u2588', ' ', 40]],
['2025-02-14', ['🌹', 'πŸ₯€', 20]],
['2025-03-17', ['πŸ€', '⬜️', 20]],
['2025-04-10', ['🐣', 'πŸ₯š', 20]],
['2025-04-20', ['🐣', 'πŸ₯š', 20]],
['2025-04-22', ['🌎', '⬜️', 20]],
['2025-06-05', ['🌳', '⬜️', 20]],
['2025-06-08', ['🌊', '⬜️', 20]],
['2025-06-19', ['β˜€οΈ', '☁️', 20]],
['2025-06-23', ['β˜€οΈ', '☁️', 20]],
['2025-07-04', ['πŸŽ†', '⬜️', 20]],
['2024-07-01', ['🎾', '⬜️', 20]],
['2024-07-14', ['🎾', '⬜️', 20]],
['2025-09-05', ['πŸ’–', '🀍', 20]],
['2025-10-01', ['β˜•οΈ', '⬜️', 20]],
['2025-10-24', ['πŸŽƒ', 'πŸ¦‡', 20]],
['2025-10-31', ['πŸŽƒ', 'πŸ¦‡', 20]],
['2025-12-01', ['⛄️', '🧊', 20]],
['2025-12-31', ['⛄️', '🧊', 20]],
])('returns the correct configuration for %s', (date, expectedResult) => {
jest.useFakeTimers().setSystemTime(new Date(date))

const config = getProgressConfig()

expect(config).toEqual(expectedResult)
})

})
Loading

0 comments on commit f120e5e

Please sign in to comment.