From 740b18241d681651d400ec28a31171abb421ff9a Mon Sep 17 00:00:00 2001 From: "Felix W. Dekker" Date: Sat, 26 Oct 2019 19:29:00 +0200 Subject: [PATCH] Migrate to Grunt as build tool --- .gitattributes | 1 + .gitignore | 106 ++++++++++++++++++++++++++++++++- Gruntfile.js | 91 ++++++++++++++++++++++++++++ README.md | 19 ++++-- build.sh | 13 ---- package-lock.json | Bin 0 -> 106543 bytes package.json | 21 +++++++ {css => src/css}/main.css | 0 favicon.ico => src/favicon.ico | Bin favicon.png => src/favicon.png | Bin index.html => src/index.html | 0 {js => src/js}/commands.ts | 0 {js => src/js}/extensions.d.ts | 0 {js => src/js}/extensions.ts | 0 {js => src/js}/fs.ts | 0 {js => src/js}/shared.ts | 0 {js => src/js}/terminal.ts | 0 tsconfig.json | 17 +++--- 18 files changed, 240 insertions(+), 28 deletions(-) create mode 100644 .gitattributes create mode 100644 Gruntfile.js delete mode 100755 build.sh create mode 100644 package-lock.json create mode 100644 package.json rename {css => src/css}/main.css (100%) rename favicon.ico => src/favicon.ico (100%) rename favicon.png => src/favicon.png (100%) rename index.html => src/index.html (100%) rename {js => src/js}/commands.ts (100%) rename {js => src/js}/extensions.d.ts (100%) rename {js => src/js}/extensions.ts (100%) rename {js => src/js}/fs.ts (100%) rename {js => src/js}/shared.ts (100%) rename {js => src/js}/terminal.ts (100%) diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1a6bd45 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +package-lock.json binary diff --git a/.gitignore b/.gitignore index 56158b3..9ed75c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,104 @@ -# Output -build/* +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/ + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..9ab4584 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,91 @@ +module.exports = grunt => { + grunt.initConfig({ + pkg: grunt.file.readJSON("package.json"), + clean: { + before: ["build/"], + after: [".tscache/"] + }, + copy: { + images: { + files: [{expand: true, cwd: "src/", src: ["**/*.png", "**/*.ico"], dest: "build/"}] + }, + html: { + files: [{expand: true, cwd: "src/", src: "**/*.html", dest: "build/"}] + }, + css: { + files: [{expand: true, cwd: "src/", src: "**/*.css", dest: "build/"}] + } + }, + cssmin: { + default: { + files: [{expand: true, cwd: "build/", src: "**/*.css", dest: "build/"}] + } + }, + htmlmin: { + default: { + files: [{expand: true, cwd: "build/", src: "**/*.html", dest: "build/"}], + options: { + removeComments: true, + collapseWhitespace: true + } + } + }, + terser: { + default: { + files: [{expand: true, cwd: "build/js/", src: "*.js", dest: "build/js/"}], + options: { + compress: true, + mangle: false, + module: true + } + } + }, + ts: { + dev: { + tsconfig: "./tsconfig.json" + }, + deploy: { + tsconfig: "./tsconfig.json", + options: { + sourceMap: false + } + } + } + }); + + grunt.loadNpmTasks("grunt-contrib-clean"); + grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-contrib-cssmin"); + grunt.loadNpmTasks("grunt-contrib-htmlmin"); + grunt.loadNpmTasks("grunt-terser"); + grunt.loadNpmTasks("grunt-ts"); + + grunt.registerTask("default", [ + // Pre + "clean:before", + // Copy files + "copy:images", + "copy:html", + "copy:css", + // Compile + "ts:dev", + // Post + "clean:after" + ]); + grunt.registerTask("deploy", [ + // Pre + "clean:before", + // Copy files + "copy:images", + "copy:html", + "copy:css", + // Compile JS + "ts:deploy", + // Minify + "terser", + "cssmin", + "htmlmin", + // Post + "clean:after" + ]); +}; diff --git a/README.md b/README.md index 1230a6e..acb13c3 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,22 @@ The source code of [my personal website](https://fwdekker.com/). ## Development +### Prerequisites +* [npm](https://www.npmjs.com/) +* [grunt-cli](https://www.npmjs.com/package/grunt-cli) + +### CLI ```shell script -# Build the website in `build/` -$> ./build.sh +# Install dependencies (only needed once) +$> npm install ``` + ```shell script -# Build the website in `build/` then copy it to `example/` -$> ./build.sh "example/" +# Build the application in `build/` for development +$> grunt +``` + +```shell script +# Build the application in `build/` for deployment +$> grunt deploy ``` diff --git a/build.sh b/build.sh deleted file mode 100755 index fb60af8..0000000 --- a/build.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -mkdir -p build build/js build/css - -tsc -p ./tsconfig.json - -cp ./*.html ./build/ -cp ./css/*.css ./build/css -cp ./favicon.ico ./build/favicon.ico -cp ./favicon.png ./build/favicon.png - -if [ "$1" ]; then - cp -r ./build/ "$1" -fi diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..69ba2a60bb0cb95e3de7dda19b647151dadaa38f GIT binary patch literal 106543 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 BNTC1# literal 0 HcmV?d00001 diff --git a/package.json b/package.json new file mode 100644 index 0000000..517dfcf --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "fwdekker.com", + "version": "1.0.0", + "description": "The source code of [my personal website](https://fwdekker.com/).", + "dependencies": {}, + "devDependencies": { + "grunt": "1.0.4", + "grunt-contrib-clean": "2.0.0", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-cssmin": "3.0.0", + "grunt-contrib-htmlmin": "3.1.0", + "grunt-terser": "1.0.0", + "grunt-ts": "6.0.0-beta.22", + "typescript": "3.6.4" + }, + "repository": { + "type": "git", + "url": "git@git.fwdekker.com:FWDekker/fwdekker.com.git" + }, + "author": "Felix W. Dekker" +} diff --git a/css/main.css b/src/css/main.css similarity index 100% rename from css/main.css rename to src/css/main.css diff --git a/favicon.ico b/src/favicon.ico similarity index 100% rename from favicon.ico rename to src/favicon.ico diff --git a/favicon.png b/src/favicon.png similarity index 100% rename from favicon.png rename to src/favicon.png diff --git a/index.html b/src/index.html similarity index 100% rename from index.html rename to src/index.html diff --git a/js/commands.ts b/src/js/commands.ts similarity index 100% rename from js/commands.ts rename to src/js/commands.ts diff --git a/js/extensions.d.ts b/src/js/extensions.d.ts similarity index 100% rename from js/extensions.d.ts rename to src/js/extensions.d.ts diff --git a/js/extensions.ts b/src/js/extensions.ts similarity index 100% rename from js/extensions.ts rename to src/js/extensions.ts diff --git a/js/fs.ts b/src/js/fs.ts similarity index 100% rename from js/fs.ts rename to src/js/fs.ts diff --git a/js/shared.ts b/src/js/shared.ts similarity index 100% rename from js/shared.ts rename to src/js/shared.ts diff --git a/js/terminal.ts b/src/js/terminal.ts similarity index 100% rename from js/terminal.ts rename to src/js/terminal.ts diff --git a/tsconfig.json b/tsconfig.json index 340b6ff..587f2a8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,17 +2,16 @@ "compilerOptions": { "module": "esnext", "target": "es2019", - "sourceMap": true, "strict": true, - "removeComments": true, - "outDir": "./build/js" + "rootDir": "./src/js/", + "outDir": "./build/js/" }, "files": [ - "js/commands.ts", - "js/extensions.d.ts", - "js/extensions.ts", - "js/fs.ts", - "js/shared.ts", - "js/terminal.ts" + "src/js/commands.ts", + "src/js/extensions.d.ts", + "src/js/extensions.ts", + "src/js/fs.ts", + "src/js/shared.ts", + "src/js/terminal.ts" ] }