diff --git a/.eslintrc b/.eslintrc index 7ea7027b..8af63901 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,7 +13,6 @@ "rules": { "semi": "error", "no-extra-semi": "error", - "newline-before-return": "error", "no-var": "error", "prefer-const": "error", "object-shorthand": "error", diff --git a/package-lock.json b/package-lock.json index 3601ca36..91b2736e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,12 +25,12 @@ "image-size": "^1.0.2", "nyc": "^15.0.0", "prettier": "^2.7.1", + "rimraf": "^5.0.0", "standard-version": "^9.5.0", - "typescript": "^4.8.4", + "typescript": "^5.0.4", "webpack": "^5.78.0", "webpack-cli": "^5.0.0", - "webpack-dev-server": "^4.13.2", - "webpack-merge": "^5.8.0" + "webpack-dev-server": "^4.13.2" }, "engines": { "node": ">=14" @@ -3331,6 +3331,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/del/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/del/node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -4398,6 +4413,21 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -5970,6 +6000,21 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -6841,6 +6886,15 @@ "node": ">=0.10.0" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -7206,6 +7260,21 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/nyc/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7759,6 +7828,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", + "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", + "dev": true, + "dependencies": { + "lru-cache": "^9.0.0", + "minipass": "^5.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz", + "integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -8745,15 +8839,60 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz", + "integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.0.0" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz", + "integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^9.0.0", + "minipass": "^5.0.0", + "path-scurry": "^1.6.4" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9329,6 +9468,21 @@ "node": ">=8" } }, + "node_modules/spawn-wrap/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -10121,16 +10275,16 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/uglify-js": { @@ -10488,6 +10642,21 @@ } } }, + "node_modules/webpack-dev-server/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/webpack-dev-server/node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -13458,6 +13627,15 @@ "slash": "^4.0.0" }, "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -14294,6 +14472,17 @@ "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { @@ -15448,6 +15637,15 @@ "requires": { "aggregate-error": "^3.0.0" } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, @@ -16101,6 +16299,12 @@ } } }, + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true + }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -16388,6 +16592,15 @@ "aggregate-error": "^3.0.0" } }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -16789,6 +17002,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", + "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", + "dev": true, + "requires": { + "lru-cache": "^9.0.0", + "minipass": "^5.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz", + "integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==", + "dev": true + } + } + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -17509,12 +17740,44 @@ "dev": true }, "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz", + "integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==", "dev": true, "requires": { - "glob": "^7.1.3" + "glob": "^10.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz", + "integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "minimatch": "^9.0.0", + "minipass": "^5.0.0", + "path-scurry": "^1.6.4" + } + }, + "minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "run-async": { @@ -17948,6 +18211,17 @@ "rimraf": "^3.0.0", "signal-exit": "^3.0.2", "which": "^2.0.1" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "spdx-correct": { @@ -18553,9 +18827,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "dev": true }, "uglify-js": { @@ -18815,6 +19089,15 @@ "ws": "^8.13.0" }, "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", diff --git a/package.json b/package.json index 219b8556..fa4586af 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,15 @@ "scripts": { "commit": "git-cz", "update-snapshots": "ava --timeout 10m --no-worker-threads -u \"test/*.test.{js,mjs}\"", - "declarations": "node_modules/.bin/tsc --declaration --allowJs src/index.js", + "declarations": "rimraf src/cache.d.ts src/hash.d.ts src/index.d.ts src/logger.d.ts src/oracle.d.ts && tsc -p ./tsconfig.json", "test": "ava --timeout 10m --no-worker-threads --fail-fast", "prettify:fix": "prettier --write \"src/*.{js,mjs}\" \"test/*.{js,mjs}\"", "prettify": "prettier --check \"src/*.{js,mjs}\" \"test/*.{js,mjs}\"", "lint:fix": "eslint \"src/*.{js,mjs}\" \"test/*.{js,mjs}\" --fix", "lint": "eslint \"src/*.{js,mjs}\" \"test/*.{js,mjs}\"", "coverage": "nyc npm test", - "release": "standard-version" + "release": "standard-version", + "prepare": "npm run declarations" }, "repository": { "type": "git", @@ -37,7 +38,8 @@ "author": "Jan Nicklas (https://github.com/jantimon)", "contributors": [ "Bruno Dutra (https://github.com/brunocodutra)", - "Jan Nicklas (https://github.com/jantimon)" + "Jan Nicklas (https://github.com/jantimon)", + "Andrey Kutejko (https://github.com/andy128k)" ], "license": "MIT", "bugs": { @@ -56,12 +58,12 @@ "image-size": "^1.0.2", "nyc": "^15.0.0", "prettier": "^2.7.1", + "rimraf": "^5.0.0", "standard-version": "^9.5.0", - "typescript": "^4.8.4", + "typescript": "^5.0.4", "webpack": "^5.78.0", "webpack-cli": "^5.0.0", - "webpack-dev-server": "^4.13.2", - "webpack-merge": "^5.8.0" + "webpack-dev-server": "^4.13.2" }, "dependencies": { "find-root": "^1.1.0", diff --git a/src/cache.d.ts b/src/cache.d.ts new file mode 100644 index 00000000..9d7037ad --- /dev/null +++ b/src/cache.d.ts @@ -0,0 +1,27 @@ +export type WebpackCompilation = import("webpack").Compilation; +export type Snapshot = ReturnType; +/** + * Executes the generator function and caches the result in memory + * The cache will be invalidated after the logo source file was modified + * + * @template TResult + * + * @param {string[]} absoluteFilePaths - file paths used used by the generator + * @param {any} pluginInstance - the plugin instance to use as cache key + * @param {boolean} useWebpackCache - Support webpack built in cache + * @param {WebpackCompilation} compilation - the current webpack compilation + * @param {string[]} eTags - eTags to verify the string + * @param {(files: { filePath: string, hash: string, content: Buffer }[]) => string} idGenerator + * @param {(files: { filePath: string, hash: string, content: Buffer }[], id: string) => Promise} generator + * + * @returns {Promise} + */ +export function runCached(absoluteFilePaths: string[], pluginInstance: any, useWebpackCache: boolean, compilation: WebpackCompilation, eTags: string[], idGenerator: (files: { + filePath: string; + hash: string; + content: Buffer; +}[]) => string, generator: (files: { + filePath: string; + hash: string; + content: Buffer; +}[], id: string) => Promise): Promise; diff --git a/src/cache.js b/src/cache.js index 811047e7..355f8fe1 100644 --- a/src/cache.js +++ b/src/cache.js @@ -2,7 +2,7 @@ // Import types /** @typedef {import("webpack").Compilation} WebpackCompilation */ -/** @typedef {Parameters[0]} Snapshot */ +/** @typedef {ReturnType} Snapshot */ const path = require('path'); const { getContentHash } = require('./hash'); diff --git a/src/hash.d.ts b/src/hash.d.ts new file mode 100644 index 00000000..1cc99933 --- /dev/null +++ b/src/hash.d.ts @@ -0,0 +1,22 @@ +export type WebpackCompilation = import("webpack").Compilation; +/** + * Returns the content hash for the given file content + * @param {...(Buffer | string | undefined)} files + */ +export function getContentHash(...files: (Buffer | string | undefined)[]): string; +/** + * Replaces [contenthash] and [fullhash] inside the given publicPath and assetPath + * + * @param {WebpackCompilation} compilation + * @param {undefined | string | ((...args:any[]) => string)} publicPath + * @param {string} assetPath + */ +export function resolvePublicPath(compilation: WebpackCompilation, publicPath: string | ((...args: any[]) => string) | undefined, assetPath: string): string; +/** + * Replaces [contenthash] and [fullhash] inside the given publicPath and assetPath + * + * @param {WebpackCompilation} compilation + * @param {string} assetPath + * @param {string} hash + */ +export function replaceContentHash(compilation: WebpackCompilation, assetPath: string, hash: string): string; diff --git a/src/index.d.ts b/src/index.d.ts index 91a37983..a7a6d7fa 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -3,24 +3,10 @@ declare class FaviconsWebpackPlugin { /** * @param {import('./options').FaviconWebpackPlugionOptions | string} args */ - constructor(args: string | import("./options").FaviconWebpackPlugionOptions); - /** @type {import('./options').FaviconWebpackPlugionInternalOptions} */ - options: import('./options').FaviconWebpackPlugionInternalOptions; - apply(compiler: any): void; + constructor(args: import('./options').FaviconWebpackPlugionOptions | string); /** - * The light mode will only add a favicon - * this is very fast but also very limited - * it is the default mode for development + * @param {import('webpack').Compiler} compiler */ - generateFaviconsLight(compiler: any, compilation: any): Promise; - /** - * The webapp mode will add a variety of icons - * this is not as fast as the light mode but - * supports all common browsers and devices - */ - generateFaviconsWebapp(compiler: any, compilation: any): Promise; - /** - * Returns wether the plugin should generate a light version or a full webapp - */ - getCurrentCompilationMode(compiler: any): "light" | "webapp"; + apply(compiler: import('webpack').Compiler): void; + #private; } diff --git a/src/index.js b/src/index.js index 8e70cc9c..91b4b13e 100644 --- a/src/index.js +++ b/src/index.js @@ -14,19 +14,19 @@ const { const { webpackLogger } = require('./logger'); class FaviconsWebpackPlugin { + /** @type {import('./options').FaviconWebpackPlugionInternalOptions} */ + #options; + /** * @param {import('./options').FaviconWebpackPlugionOptions | string} args */ constructor(args) { - /* @type {import('./options').FaviconWebpackPlugionOptions} */ + /** @type {import('./options').FaviconWebpackPlugionOptions} */ const options = typeof args === 'string' ? { logo: args } : args; - /** @type {Partial} */ - const emptyFaviconsConfig = {}; - /** @type {import('./options').FaviconWebpackPlugionInternalOptions} */ - this.options = { + this.#options = { cache: true, inject: true, - favicons: emptyFaviconsConfig, + favicons: {}, manifest: {}, prefix: 'assets/', ...options, @@ -38,14 +38,14 @@ class FaviconsWebpackPlugin { */ apply(compiler) { compiler.hooks.initialize.tap('FaviconsWebpackPlugin', () => { - this.hookIntoCompiler(compiler); + this.#hookIntoCompiler(compiler); }); } /** * @param {import('webpack').Compiler} compiler */ - hookIntoCompiler(compiler) { + #hookIntoCompiler(compiler) { const webpack = compiler.webpack; const Compilation = webpack.Compilation; const oracle = new Oracle(compiler.context); @@ -59,9 +59,9 @@ class FaviconsWebpackPlugin { version = oracle.guessVersion(), developerName = oracle.guessDeveloperName(), developerURL = oracle.guessDeveloperURL(), - } = this.options.favicons; + } = this.#options.favicons; - Object.assign(this.options.favicons, { + Object.assign(this.#options.favicons, { appName, appDescription, version, @@ -70,47 +70,51 @@ class FaviconsWebpackPlugin { }); } - if (this.options.logo === undefined) { + if (this.#options.logo === undefined) { const defaultLogo = path.resolve(compiler.context, 'logo.png'); try { + // FIXME: use asynchronous call + // @ts-ignore compiler.inputFileSystem.statSync(defaultLogo); - this.options.logo = [defaultLogo]; + this.#options.logo = [defaultLogo]; } catch (e) {} // @ts-ignore assert( - typeof this.options.logo[0] === 'string', + typeof this.#options.logo[0] === 'string', 'Could not find `logo.png` for the current webpack context' ); - } else if (this.options.logo instanceof Array) { - this.options.logo = this.options.logo.map((logo) => + } else if (this.#options.logo instanceof Array) { + this.#options.logo = this.#options.logo.map((logo) => path.resolve(compiler.context, logo) ); } else { - this.options.logo = [path.resolve(compiler.context, this.options.logo)]; + this.#options.logo = [path.resolve(compiler.context, this.#options.logo)]; } - if (this.options.logoMaskable !== undefined) { - if (typeof this.options.logoMaskable === 'string') { - this.options.logoMaskable = [this.options.logoMaskable]; - } - - // @ts-ignore - assert( - this.options.logoMaskable instanceof Array, - 'options.logoMaskable must be string or array ' - ); + /** @type {string[]} */ + let logoMaskable; + if (this.#options.logoMaskable !== undefined) { + if (typeof this.#options.logoMaskable === 'string') { + logoMaskable = [this.#options.logoMaskable]; + } else { + // @ts-ignore + assert( + this.#options.logoMaskable instanceof Array, + 'options.logoMaskable must be string or array ' + ); - this.options.logoMaskable = this.options.logoMaskable.map( - (logoMaskable) => path.resolve(compiler.context, logoMaskable) - ); + logoMaskable = this.#options.logoMaskable.map((logoMaskable) => + path.resolve(compiler.context, logoMaskable) + ); + } } else { - this.options.logoMaskable = []; + logoMaskable = []; } - if (typeof this.options.manifest === 'string') { - this.options.manifest = path.resolve( + if (typeof this.#options.manifest === 'string') { + this.#options.manifest = path.resolve( compiler.context, - this.options.manifest + this.#options.manifest ); } @@ -120,50 +124,44 @@ class FaviconsWebpackPlugin { 'FaviconsWebpackPlugin', async (compilation) => { const manifestAbsoluteFilePath = - typeof this.options.manifest === 'string' - ? this.options.manifest + typeof this.#options.manifest === 'string' + ? this.#options.manifest : ''; const faviconCompilation = runCached( - [ - ...this.options.logo, - ...this.options.logoMaskable, - manifestAbsoluteFilePath, - ], + [...this.#options.logo, ...logoMaskable, manifestAbsoluteFilePath], this, - this.options.cache, + this.#options.cache, compilation, // Options which enforce a new recompilation [ - JSON.stringify(this.options.publicPath), - JSON.stringify(this.options.mode), + JSON.stringify(this.#options.publicPath), + JSON.stringify(this.#options.mode), // Recompile filesystem cache if the user change the favicon options - JSON.stringify(this.options.favicons), + JSON.stringify(this.#options.favicons), ], // Recompile filesystem cache if any source based path change: (fileSources) => getRelativeOutputPath( getContentHash(...fileSources.map((s) => s.content)), compilation, - this.options + this.#options ), (fileSources, outputPath) => { const logoFileSources = fileSources.slice( 0, - this.options.logo.length + this.#options.logo.length ); const logoMaskableFileSources = fileSources.slice( - this.options.logo.length, - this.options.logo.length + this.options.logoMaskable.length + this.#options.logo.length, + this.#options.logo.length + logoMaskable.length ); const manifestFileSource = - fileSources[ - this.options.logo.length + this.options.logoMaskable.length - ]; + fileSources[this.#options.logo.length + logoMaskable.length]; - return this.generateFavicons( + return this.#generateFavicons( logoFileSources, logoMaskableFileSources, manifestFileSource.content, @@ -185,20 +183,20 @@ class FaviconsWebpackPlugin { ); // Watch for changes to the logo - for (const logo of this.options.logo) { + for (const logo of this.#options.logo) { compilation.fileDependencies.add(logo); } - for (const logoMaskable of this.options.logoMaskable) { - compilation.fileDependencies.add(logoMaskable); + for (const logo of logoMaskable) { + compilation.fileDependencies.add(logo); } // Watch for changes to the base manifest.webmanifest - if (typeof this.options.manifest === 'string') { - compilation.fileDependencies.add(this.options.manifest); + if (typeof this.#options.manifest === 'string') { + compilation.fileDependencies.add(this.#options.manifest); } - if (this.options.inject) { + if (this.#options.inject) { // Hook into the html-webpack-plugin processing and add the html findHtmlWebpackPlugin(compilation) ?.getHooks(compilation) @@ -208,9 +206,9 @@ class FaviconsWebpackPlugin { // Skip if a custom injectFunction returns false or if // the htmlWebpackPlugin optuons includes a `favicons: false` flag const isInjectionAllowed = - typeof this.options.inject === 'function' - ? this.options.inject(htmlPluginData.plugin) - : this.options.inject !== false && + typeof this.#options.inject === 'function' + ? this.#options.inject(htmlPluginData.plugin) + : this.#options.inject !== false && htmlPluginData.plugin.userOptions.favicon !== false && htmlPluginData.plugin.userOptions.favicons !== false; @@ -230,8 +228,8 @@ class FaviconsWebpackPlugin { // Prefix links to icons const pathReplacer = - !this.options.favicons.path || - this.getCurrentCompilationMode(compiler) === 'light' + !this.#options.favicons.path || + this.#getCurrentCompilationMode(compiler) === 'light' ? /** @param {string} url */ (url) => typeof url === 'string' ? publicPathFromHtml + url : url : /** @param {string} url */ (url) => url; @@ -296,13 +294,12 @@ class FaviconsWebpackPlugin { }, async () => { const faviconCompilation = faviconCompilations.get(compilation); - if (!faviconCompilation) { - return; + if (faviconCompilation) { + const { assets } = await faviconCompilation; + assets.forEach(({ name, contents }) => { + compilation.emitAsset(name, contents); + }); } - const faviconAssets = (await faviconCompilation).assets; - faviconAssets.forEach(({ name, contents }) => { - compilation.emitAsset(name, contents); - }); } ); } @@ -312,10 +309,11 @@ class FaviconsWebpackPlugin { compiler.hooks.afterCompile.tapPromise( 'FaviconsWebpackPlugin', async (compilation) => { - const faviconCompilation = - faviconCompilations.get(compilation) || Promise.resolve(); + const faviconCompilation = faviconCompilations.get(compilation); faviconCompilations.delete(compilation); - await faviconCompilation; + if (faviconCompilation) { + await faviconCompilation; + } } ); } @@ -328,7 +326,7 @@ class FaviconsWebpackPlugin { * @param {Buffer | string} baseManifest - the content of the file from options.manifest * @param {import('webpack').Compilation} compilation */ - generateFavicons( + #generateFavicons( logoFileSources, logoMaskableFileSources, baseManifest, @@ -348,24 +346,24 @@ class FaviconsWebpackPlugin { ...logoMaskableFileSourceContents ), compilation, - this.options + this.#options ); /** @type {{[key: string]: any}} - the parsed manifest from options.manifest */ const parsedBaseManifest = - typeof this.options.manifest === 'string' + typeof this.#options.manifest === 'string' ? JSON.parse(baseManifest.toString() || '{}') - : this.options.manifest || {}; + : this.#options.manifest || {}; - switch (this.getCurrentCompilationMode(compilation.compiler)) { + switch (this.#getCurrentCompilationMode(compilation.compiler)) { case 'light': - if (!this.options.mode) { + if (!this.#options.mode) { webpackLogger(compilation).info( 'generate only a single favicon for fast compilation time in development mode. This behaviour can be changed by setting the favicon mode option.' ); } - return this.generateFaviconsLight( + return this.#generateFaviconsLight( logoFileSourceContents, logoMaskableFileSourceContents, parsedBaseManifest, @@ -375,7 +373,7 @@ class FaviconsWebpackPlugin { default: webpackLogger(compilation).log('generate favicons'); - return this.generateFaviconsWebapp( + return this.#generateFaviconsWebapp( logoFileSourceContents, logoMaskableFileSourceContents, parsedBaseManifest, @@ -394,13 +392,13 @@ class FaviconsWebpackPlugin { * @param {{[key: string]: any}} baseManifest * @param {string} resolvedPublicPath */ - async generateFaviconsLight( + async #generateFaviconsLight( logoFileSources, logoMaskableFileSources, baseManifest, resolvedPublicPath ) { - const faviconExt = path.extname(this.options.logo[0]); + const faviconExt = path.extname(this.#options.logo[0]); const faviconName = `favicon${faviconExt}`; const tags = [``]; @@ -447,7 +445,7 @@ class FaviconsWebpackPlugin { * @param {{[key: string]: any}} baseManifest * @param {string} resolvedPublicPath */ - async generateFaviconsWebapp( + async #generateFaviconsWebapp( logoFileSources, logoMaskableFileSources, baseManifest, @@ -465,7 +463,7 @@ class FaviconsWebpackPlugin { // to allow relative manifests and to set the final public path // once it has been provided by the html-webpack-plugin path: '', - ...this.options.favicons, + ...this.#options.favicons, // set maskable icons ...(logoMaskableFileSources.length !== 0 && { manifestMaskable: logoMaskableFileSources, @@ -496,19 +494,22 @@ class FaviconsWebpackPlugin { /** * Returns wether the plugin should generate a light version or a full webapp + * + * @param {import('webpack').Compiler} compiler + * @returns {'webapp' | 'light'} */ - getCurrentCompilationMode(compiler) { + #getCurrentCompilationMode(compiler) { // From https://github.com/webpack/webpack/blob/3366421f1784c449f415cda5930a8e445086f688/lib/WebpackOptionsDefaulter.js#L12-L14 const isProductionLikeMode = compiler.options.mode === 'production' || !compiler.options.mode; // Read the current `mode` and `devMode` option const faviconDefaultMode = isProductionLikeMode ? 'webapp' : 'light'; - const mode = this.options.mode === 'auto' ? undefined : this.options.mode; + const mode = this.#options.mode === 'auto' ? undefined : this.#options.mode; return isProductionLikeMode ? mode || faviconDefaultMode - : this.options.devMode || mode || faviconDefaultMode; + : this.#options.devMode || mode || faviconDefaultMode; } } diff --git a/src/logger.d.ts b/src/logger.d.ts new file mode 100644 index 00000000..b07c6a2b --- /dev/null +++ b/src/logger.d.ts @@ -0,0 +1,12 @@ +export type WebpackCompilation = import("webpack").Compilation; +export type WebpackLogger = ReturnType; +/** @typedef {import("webpack").Compilation} WebpackCompilation */ +/** @typedef {ReturnType} WebpackLogger */ +/** + * Returns the favicon webpack logger instance + * @see https://webpack.js.org/api/logging/ + * + * @param {WebpackCompilation} compilation + * @returns {WebpackLogger} + */ +export function webpackLogger(compilation: WebpackCompilation): WebpackLogger; diff --git a/src/logger.js b/src/logger.js index 8ebd1147..712c3886 100644 --- a/src/logger.js +++ b/src/logger.js @@ -2,12 +2,14 @@ // Import types /** @typedef {import("webpack").Compilation} WebpackCompilation */ +/** @typedef {ReturnType} WebpackLogger */ /** * Returns the favicon webpack logger instance * @see https://webpack.js.org/api/logging/ * * @param {WebpackCompilation} compilation + * @returns {WebpackLogger} */ const webpackLogger = (compilation) => compilation.getLogger('favicons-webpack-plugin'); diff --git a/src/options.d.ts b/src/options.d.ts index bfc1f9d7..ef65b4fd 100644 --- a/src/options.d.ts +++ b/src/options.d.ts @@ -75,6 +75,7 @@ export interface FaviconWebpackPlugionOptions { export type FaviconWebpackPlugionInternalOptions = Required { }; export const compiler = (config) => { - config = merge( - { - entry: path.resolve(fixtures, 'entry.js'), - plugins: [], - output: {}, - infrastructureLogging: { - level: 'info', - }, + config = { + entry: path.resolve(fixtures, 'entry.js'), + plugins: [], + output: {}, + infrastructureLogging: { + level: 'info', }, - config - ); + ...config, + }; config.plugins .filter((plugin) => plugin.constructor.name === 'HtmlWebpackPlugin') diff --git a/test/oracle.test.mjs b/test/oracle.test.mjs index a466e303..9d32ee81 100644 --- a/test/oracle.test.mjs +++ b/test/oracle.test.mjs @@ -1,123 +1,116 @@ import test from 'ava'; import * as path from 'path'; -import { mkdir, writeFile } from 'fs/promises'; -import parseAuthor from 'parse-author'; +import { mkdir, writeFile, readFile } from 'fs/promises'; import FaviconsWebpackPlugin from '../src/index.js'; -import { logo, compiler, withTempDirectory } from './_util.mjs'; +import { logo, withTempDirectory, generate } from './_util.mjs'; withTempDirectory(test); -async function writeJson(path, obj, options) { - await writeFile(path, JSON.stringify(obj, options)); +async function writeJson(path, obj) { + const content = JSON.stringify(obj, null, 2); + await writeFile(path, content); } -test('should infer missing information from the nearest parent package.json', async (t) => { - const pkg = { - name: 'app', - version: '1.2.3', - description: 'Some App', - author: { - name: 'Jane Doe', - email: 'jane@doe.com', - url: 'https://jane.doe.com', - }, - }; +async function readJson(path) { + const content = await readFile(path); + return JSON.parse(content); +} + +const pkg = { + name: 'app', + version: '1.2.3', + description: 'Some App', + author: { + name: 'Jane Doe', + email: 'jane@doe.com', + url: 'https://jane.doe.com', + }, +}; +test('should infer missing information from the nearest parent package.json', async (t) => { const context = path.join(t.context.root, 'a', 'b', 'c', 'd'); + const output = path.join(t.context.root, 'output'); await mkdir(context, { recursive: true }); - await writeJson(path.join(t.context.root, 'package.json'), pkg, { - spaces: 2, - }); + await writeJson(path.join(t.context.root, 'package.json'), pkg); { - const plugin = new FaviconsWebpackPlugin(logo); - plugin.hookIntoCompiler(compiler({ context })); - - t.is(plugin.options.favicons.appName, pkg.name); - t.is(plugin.options.favicons.version, pkg.version); - t.is(plugin.options.favicons.appDescription, pkg.description); - t.is(plugin.options.favicons.developerName, pkg.author.name); - t.is(plugin.options.favicons.developerURL, pkg.author.url); + await generate({ + context, + output: { + path: output, + }, + plugins: [new FaviconsWebpackPlugin(logo)], + }); + + const manifest = await readJson( + path.join(output, 'assets', 'manifest.webmanifest') + ); + + t.is(manifest.name, 'app'); + t.is(manifest.description, 'Some App'); } - await writeJson(path.join(context, 'package.json'), {}, { spaces: 2 }); - { - const plugin = new FaviconsWebpackPlugin(logo); - plugin.hookIntoCompiler(compiler({ context })); - - t.is(plugin.options.favicons.appName, undefined); - t.is(plugin.options.favicons.version, undefined); - t.is(plugin.options.favicons.appDescription, undefined); - t.is(plugin.options.favicons.developerName, undefined); - t.is(plugin.options.favicons.developerURL, undefined); + await writeJson(path.join(context, 'package.json'), {}); + await generate({ + context, + output: { + path: output, + }, + plugins: [new FaviconsWebpackPlugin(logo)], + }); + + const manifest = await readJson( + path.join(output, 'assets', 'manifest.webmanifest') + ); + + t.is(manifest.name, undefined); + t.is(manifest.description, undefined); } }); -test('should parse author string from package.json', async (t) => { - const pkg = { author: 'John Doe (https://john.doe.com)' }; +test('should handle missing package.json gracefully', async (t) => { + const output = path.join(t.context.root, 'output'); - await writeJson(path.join(t.context.root, 'package.json'), pkg, { - spaces: 2, + await generate({ + context: t.context.root, + output: { + path: output, + }, + plugins: [new FaviconsWebpackPlugin(logo)], }); - const plugin = new FaviconsWebpackPlugin(logo); - plugin.hookIntoCompiler(compiler({ context: t.context.root })); - - t.is(plugin.options.favicons.developerName, parseAuthor(pkg.author).name); - t.is(plugin.options.favicons.developerURL, parseAuthor(pkg.author).url); -}); - -test('should handle missing package.json gracefully', async (t) => { - const plugin = new FaviconsWebpackPlugin(logo); - plugin.apply( - compiler({ - context: t.context.root, - }) + const manifest = await readJson( + path.join(output, 'assets', 'manifest.webmanifest') ); - t.is(plugin.options.favicons.appName, undefined); - t.is(plugin.options.favicons.version, undefined); - t.is(plugin.options.favicons.appDescription, undefined); - t.is(plugin.options.favicons.developerName, undefined); - t.is(plugin.options.favicons.developerURL, undefined); + t.is(manifest.name, undefined); + t.is(manifest.description, undefined); }); test('should not reach for the package.json if metadata defined', async (t) => { - const pkg = { - name: 'app', - version: '1.2.3', - description: 'Some App', - author: { - name: 'Jane Doe', - email: 'jane@doe.com', - url: 'https://jane.doe.com', - }, - }; + await writeJson(path.join(t.context.root, 'package.json'), pkg); - await writeJson(path.join(t.context.root, 'package.json'), pkg, { - spaces: 2, - }); + const output = path.join(t.context.root, 'output'); const favicons = { - appName: null, - version: null, + appName: 'another-app', appDescription: null, - developerName: null, - developerURL: null, }; - const plugin = new FaviconsWebpackPlugin({ logo, favicons }); - plugin.apply( - compiler({ - context: t.context.root, - }) + await generate({ + context: t.context.root, + output: { + path: output, + }, + plugins: [new FaviconsWebpackPlugin({ logo, favicons })], + }); + + const manifest = await readJson( + path.join(output, 'assets', 'manifest.webmanifest') ); - t.is(plugin.options.favicons.appName, null); - t.is(plugin.options.favicons.version, null); - t.is(plugin.options.favicons.appDescription, null); - t.is(plugin.options.favicons.developerName, null); - t.is(plugin.options.favicons.developerURL, null); + t.is(manifest.name, 'another-app'); + t.is(manifest.description, undefined); }); diff --git a/test/snapshots/usage.test.mjs.md b/test/snapshots/usage.test.mjs.md new file mode 100644 index 00000000..6daae4a0 --- /dev/null +++ b/test/snapshots/usage.test.mjs.md @@ -0,0 +1,813 @@ +# Snapshot report for `test/usage.test.mjs` + +The actual snapshot is saved in `usage.test.mjs.snap`. + +Generated by [AVA](https://avajs.dev). + +## should take a string as argument + +> Snapshot 1 + + [ + 'assets/android-chrome-144x144.png', + 'assets/android-chrome-192x192.png', + 'assets/android-chrome-256x256.png', + 'assets/android-chrome-36x36.png', + 'assets/android-chrome-384x384.png', + 'assets/android-chrome-48x48.png', + 'assets/android-chrome-512x512.png', + 'assets/android-chrome-72x72.png', + 'assets/android-chrome-96x96.png', + 'assets/apple-touch-icon-1024x1024.png', + 'assets/apple-touch-icon-114x114.png', + 'assets/apple-touch-icon-120x120.png', + 'assets/apple-touch-icon-144x144.png', + 'assets/apple-touch-icon-152x152.png', + 'assets/apple-touch-icon-167x167.png', + 'assets/apple-touch-icon-180x180.png', + 'assets/apple-touch-icon-57x57.png', + 'assets/apple-touch-icon-60x60.png', + 'assets/apple-touch-icon-72x72.png', + 'assets/apple-touch-icon-76x76.png', + 'assets/apple-touch-icon-precomposed.png', + 'assets/apple-touch-icon.png', + 'assets/apple-touch-startup-image-1125x2436.png', + 'assets/apple-touch-startup-image-1136x640.png', + 'assets/apple-touch-startup-image-1170x2532.png', + 'assets/apple-touch-startup-image-1242x2208.png', + 'assets/apple-touch-startup-image-1242x2688.png', + 'assets/apple-touch-startup-image-1284x2778.png', + 'assets/apple-touch-startup-image-1334x750.png', + 'assets/apple-touch-startup-image-1536x2048.png', + 'assets/apple-touch-startup-image-1620x2160.png', + 'assets/apple-touch-startup-image-1668x2224.png', + 'assets/apple-touch-startup-image-1668x2388.png', + 'assets/apple-touch-startup-image-1792x828.png', + 'assets/apple-touch-startup-image-2048x1536.png', + 'assets/apple-touch-startup-image-2048x2732.png', + 'assets/apple-touch-startup-image-2160x1620.png', + 'assets/apple-touch-startup-image-2208x1242.png', + 'assets/apple-touch-startup-image-2224x1668.png', + 'assets/apple-touch-startup-image-2388x1668.png', + 'assets/apple-touch-startup-image-2436x1125.png', + 'assets/apple-touch-startup-image-2532x1170.png', + 'assets/apple-touch-startup-image-2688x1242.png', + 'assets/apple-touch-startup-image-2732x2048.png', + 'assets/apple-touch-startup-image-2778x1284.png', + 'assets/apple-touch-startup-image-640x1136.png', + 'assets/apple-touch-startup-image-750x1334.png', + 'assets/apple-touch-startup-image-828x1792.png', + 'assets/browserconfig.xml', + 'assets/favicon-16x16.png', + 'assets/favicon-32x32.png', + 'assets/favicon-48x48.png', + 'assets/favicon.ico', + 'assets/manifest.webmanifest', + 'assets/mstile-144x144.png', + 'assets/mstile-150x150.png', + 'assets/mstile-310x150.png', + 'assets/mstile-310x310.png', + 'assets/mstile-70x70.png', + 'assets/yandex-browser-50x50.png', + 'assets/yandex-browser-manifest.json', + 'main.js', + ] + +> Snapshot 2 + + [ + { + assetName: 'assets/android-chrome-144x144.png', + content: 'png 144x144', + }, + { + assetName: 'assets/android-chrome-192x192.png', + content: 'png 192x192', + }, + { + assetName: 'assets/android-chrome-256x256.png', + content: 'png 256x256', + }, + { + assetName: 'assets/android-chrome-36x36.png', + content: 'png 36x36', + }, + { + assetName: 'assets/android-chrome-384x384.png', + content: 'png 384x384', + }, + { + assetName: 'assets/android-chrome-48x48.png', + content: 'png 48x48', + }, + { + assetName: 'assets/android-chrome-512x512.png', + content: 'png 512x512', + }, + { + assetName: 'assets/android-chrome-72x72.png', + content: 'png 72x72', + }, + { + assetName: 'assets/android-chrome-96x96.png', + content: 'png 96x96', + }, + { + assetName: 'assets/apple-touch-icon-1024x1024.png', + content: 'png 1024x1024', + }, + { + assetName: 'assets/apple-touch-icon-114x114.png', + content: 'png 114x114', + }, + { + assetName: 'assets/apple-touch-icon-120x120.png', + content: 'png 120x120', + }, + { + assetName: 'assets/apple-touch-icon-144x144.png', + content: 'png 144x144', + }, + { + assetName: 'assets/apple-touch-icon-152x152.png', + content: 'png 152x152', + }, + { + assetName: 'assets/apple-touch-icon-167x167.png', + content: 'png 167x167', + }, + { + assetName: 'assets/apple-touch-icon-180x180.png', + content: 'png 180x180', + }, + { + assetName: 'assets/apple-touch-icon-57x57.png', + content: 'png 57x57', + }, + { + assetName: 'assets/apple-touch-icon-60x60.png', + content: 'png 60x60', + }, + { + assetName: 'assets/apple-touch-icon-72x72.png', + content: 'png 72x72', + }, + { + assetName: 'assets/apple-touch-icon-76x76.png', + content: 'png 76x76', + }, + { + assetName: 'assets/apple-touch-icon-precomposed.png', + content: 'png 180x180', + }, + { + assetName: 'assets/apple-touch-icon.png', + content: 'png 180x180', + }, + { + assetName: 'assets/apple-touch-startup-image-1125x2436.png', + content: 'png 1125x2436', + }, + { + assetName: 'assets/apple-touch-startup-image-1136x640.png', + content: 'png 1136x640', + }, + { + assetName: 'assets/apple-touch-startup-image-1170x2532.png', + content: 'png 1170x2532', + }, + { + assetName: 'assets/apple-touch-startup-image-1242x2208.png', + content: 'png 1242x2208', + }, + { + assetName: 'assets/apple-touch-startup-image-1242x2688.png', + content: 'png 1242x2688', + }, + { + assetName: 'assets/apple-touch-startup-image-1284x2778.png', + content: 'png 1284x2778', + }, + { + assetName: 'assets/apple-touch-startup-image-1334x750.png', + content: 'png 1334x750', + }, + { + assetName: 'assets/apple-touch-startup-image-1536x2048.png', + content: 'png 1536x2048', + }, + { + assetName: 'assets/apple-touch-startup-image-1620x2160.png', + content: 'png 1620x2160', + }, + { + assetName: 'assets/apple-touch-startup-image-1668x2224.png', + content: 'png 1668x2224', + }, + { + assetName: 'assets/apple-touch-startup-image-1668x2388.png', + content: 'png 1668x2388', + }, + { + assetName: 'assets/apple-touch-startup-image-1792x828.png', + content: 'png 1792x828', + }, + { + assetName: 'assets/apple-touch-startup-image-2048x1536.png', + content: 'png 2048x1536', + }, + { + assetName: 'assets/apple-touch-startup-image-2048x2732.png', + content: 'png 2048x2732', + }, + { + assetName: 'assets/apple-touch-startup-image-2160x1620.png', + content: 'png 2160x1620', + }, + { + assetName: 'assets/apple-touch-startup-image-2208x1242.png', + content: 'png 2208x1242', + }, + { + assetName: 'assets/apple-touch-startup-image-2224x1668.png', + content: 'png 2224x1668', + }, + { + assetName: 'assets/apple-touch-startup-image-2388x1668.png', + content: 'png 2388x1668', + }, + { + assetName: 'assets/apple-touch-startup-image-2436x1125.png', + content: 'png 2436x1125', + }, + { + assetName: 'assets/apple-touch-startup-image-2532x1170.png', + content: 'png 2532x1170', + }, + { + assetName: 'assets/apple-touch-startup-image-2688x1242.png', + content: 'png 2688x1242', + }, + { + assetName: 'assets/apple-touch-startup-image-2732x2048.png', + content: 'png 2732x2048', + }, + { + assetName: 'assets/apple-touch-startup-image-2778x1284.png', + content: 'png 2778x1284', + }, + { + assetName: 'assets/apple-touch-startup-image-640x1136.png', + content: 'png 640x1136', + }, + { + assetName: 'assets/apple-touch-startup-image-750x1334.png', + content: 'png 750x1334', + }, + { + assetName: 'assets/apple-touch-startup-image-828x1792.png', + content: 'png 828x1792', + }, + { + assetName: 'assets/browserconfig.xml', + content: `␊ + ␊ + ␊ + ␊ + ␊ + ␊ + ␊ + ␊ + #fff␊ + ␊ + ␊ + `, + }, + { + assetName: 'assets/favicon-16x16.png', + content: 'png 16x16', + }, + { + assetName: 'assets/favicon-32x32.png', + content: 'png 32x32', + }, + { + assetName: 'assets/favicon-48x48.png', + content: 'png 48x48', + }, + { + assetName: 'assets/favicon.ico', + content: 'ico 16x16', + }, + { + assetName: 'assets/manifest.webmanifest', + content: `{␊ + "name": "favicons-webpack-plugin",␊ + "short_name": "favicons-webpack-plugin",␊ + "description": "Let webpack generate all your favicons and icons for you",␊ + "dir": "auto",␊ + "lang": "en-US",␊ + "display": "standalone",␊ + "orientation": "any",␊ + "start_url": "/?homescreen=1",␊ + "background_color": "#fff",␊ + "theme_color": "#fff",␊ + "icons": [␊ + {␊ + "src": "android-chrome-36x36.png",␊ + "sizes": "36x36",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-48x48.png",␊ + "sizes": "48x48",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-72x72.png",␊ + "sizes": "72x72",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-96x96.png",␊ + "sizes": "96x96",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-144x144.png",␊ + "sizes": "144x144",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-192x192.png",␊ + "sizes": "192x192",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-256x256.png",␊ + "sizes": "256x256",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-384x384.png",␊ + "sizes": "384x384",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-512x512.png",␊ + "sizes": "512x512",␊ + "type": "image/png",␊ + "purpose": "any"␊ + }␊ + ]␊ + }`, + }, + { + assetName: 'assets/mstile-144x144.png', + content: 'png 144x144', + }, + { + assetName: 'assets/mstile-150x150.png', + content: 'png 150x150', + }, + { + assetName: 'assets/mstile-310x150.png', + content: 'png 310x150', + }, + { + assetName: 'assets/mstile-310x310.png', + content: 'png 310x310', + }, + { + assetName: 'assets/mstile-70x70.png', + content: 'png 70x70', + }, + { + assetName: 'assets/yandex-browser-50x50.png', + content: 'png 50x50', + }, + { + assetName: 'assets/yandex-browser-manifest.json', + content: `{␊ + "version": "6.0.0",␊ + "api_version": 1,␊ + "layout": {␊ + "logo": "yandex-browser-50x50.png",␊ + "color": "#fff",␊ + "show_title": true␊ + }␊ + }`, + }, + ] + +## should take an object with just the logo as argument + +> Snapshot 1 + + [ + 'assets/android-chrome-144x144.png', + 'assets/android-chrome-192x192.png', + 'assets/android-chrome-256x256.png', + 'assets/android-chrome-36x36.png', + 'assets/android-chrome-384x384.png', + 'assets/android-chrome-48x48.png', + 'assets/android-chrome-512x512.png', + 'assets/android-chrome-72x72.png', + 'assets/android-chrome-96x96.png', + 'assets/apple-touch-icon-1024x1024.png', + 'assets/apple-touch-icon-114x114.png', + 'assets/apple-touch-icon-120x120.png', + 'assets/apple-touch-icon-144x144.png', + 'assets/apple-touch-icon-152x152.png', + 'assets/apple-touch-icon-167x167.png', + 'assets/apple-touch-icon-180x180.png', + 'assets/apple-touch-icon-57x57.png', + 'assets/apple-touch-icon-60x60.png', + 'assets/apple-touch-icon-72x72.png', + 'assets/apple-touch-icon-76x76.png', + 'assets/apple-touch-icon-precomposed.png', + 'assets/apple-touch-icon.png', + 'assets/apple-touch-startup-image-1125x2436.png', + 'assets/apple-touch-startup-image-1136x640.png', + 'assets/apple-touch-startup-image-1170x2532.png', + 'assets/apple-touch-startup-image-1242x2208.png', + 'assets/apple-touch-startup-image-1242x2688.png', + 'assets/apple-touch-startup-image-1284x2778.png', + 'assets/apple-touch-startup-image-1334x750.png', + 'assets/apple-touch-startup-image-1536x2048.png', + 'assets/apple-touch-startup-image-1620x2160.png', + 'assets/apple-touch-startup-image-1668x2224.png', + 'assets/apple-touch-startup-image-1668x2388.png', + 'assets/apple-touch-startup-image-1792x828.png', + 'assets/apple-touch-startup-image-2048x1536.png', + 'assets/apple-touch-startup-image-2048x2732.png', + 'assets/apple-touch-startup-image-2160x1620.png', + 'assets/apple-touch-startup-image-2208x1242.png', + 'assets/apple-touch-startup-image-2224x1668.png', + 'assets/apple-touch-startup-image-2388x1668.png', + 'assets/apple-touch-startup-image-2436x1125.png', + 'assets/apple-touch-startup-image-2532x1170.png', + 'assets/apple-touch-startup-image-2688x1242.png', + 'assets/apple-touch-startup-image-2732x2048.png', + 'assets/apple-touch-startup-image-2778x1284.png', + 'assets/apple-touch-startup-image-640x1136.png', + 'assets/apple-touch-startup-image-750x1334.png', + 'assets/apple-touch-startup-image-828x1792.png', + 'assets/browserconfig.xml', + 'assets/favicon-16x16.png', + 'assets/favicon-32x32.png', + 'assets/favicon-48x48.png', + 'assets/favicon.ico', + 'assets/manifest.webmanifest', + 'assets/mstile-144x144.png', + 'assets/mstile-150x150.png', + 'assets/mstile-310x150.png', + 'assets/mstile-310x310.png', + 'assets/mstile-70x70.png', + 'assets/yandex-browser-50x50.png', + 'assets/yandex-browser-manifest.json', + 'main.js', + ] + +> Snapshot 2 + + [ + { + assetName: 'assets/android-chrome-144x144.png', + content: 'png 144x144', + }, + { + assetName: 'assets/android-chrome-192x192.png', + content: 'png 192x192', + }, + { + assetName: 'assets/android-chrome-256x256.png', + content: 'png 256x256', + }, + { + assetName: 'assets/android-chrome-36x36.png', + content: 'png 36x36', + }, + { + assetName: 'assets/android-chrome-384x384.png', + content: 'png 384x384', + }, + { + assetName: 'assets/android-chrome-48x48.png', + content: 'png 48x48', + }, + { + assetName: 'assets/android-chrome-512x512.png', + content: 'png 512x512', + }, + { + assetName: 'assets/android-chrome-72x72.png', + content: 'png 72x72', + }, + { + assetName: 'assets/android-chrome-96x96.png', + content: 'png 96x96', + }, + { + assetName: 'assets/apple-touch-icon-1024x1024.png', + content: 'png 1024x1024', + }, + { + assetName: 'assets/apple-touch-icon-114x114.png', + content: 'png 114x114', + }, + { + assetName: 'assets/apple-touch-icon-120x120.png', + content: 'png 120x120', + }, + { + assetName: 'assets/apple-touch-icon-144x144.png', + content: 'png 144x144', + }, + { + assetName: 'assets/apple-touch-icon-152x152.png', + content: 'png 152x152', + }, + { + assetName: 'assets/apple-touch-icon-167x167.png', + content: 'png 167x167', + }, + { + assetName: 'assets/apple-touch-icon-180x180.png', + content: 'png 180x180', + }, + { + assetName: 'assets/apple-touch-icon-57x57.png', + content: 'png 57x57', + }, + { + assetName: 'assets/apple-touch-icon-60x60.png', + content: 'png 60x60', + }, + { + assetName: 'assets/apple-touch-icon-72x72.png', + content: 'png 72x72', + }, + { + assetName: 'assets/apple-touch-icon-76x76.png', + content: 'png 76x76', + }, + { + assetName: 'assets/apple-touch-icon-precomposed.png', + content: 'png 180x180', + }, + { + assetName: 'assets/apple-touch-icon.png', + content: 'png 180x180', + }, + { + assetName: 'assets/apple-touch-startup-image-1125x2436.png', + content: 'png 1125x2436', + }, + { + assetName: 'assets/apple-touch-startup-image-1136x640.png', + content: 'png 1136x640', + }, + { + assetName: 'assets/apple-touch-startup-image-1170x2532.png', + content: 'png 1170x2532', + }, + { + assetName: 'assets/apple-touch-startup-image-1242x2208.png', + content: 'png 1242x2208', + }, + { + assetName: 'assets/apple-touch-startup-image-1242x2688.png', + content: 'png 1242x2688', + }, + { + assetName: 'assets/apple-touch-startup-image-1284x2778.png', + content: 'png 1284x2778', + }, + { + assetName: 'assets/apple-touch-startup-image-1334x750.png', + content: 'png 1334x750', + }, + { + assetName: 'assets/apple-touch-startup-image-1536x2048.png', + content: 'png 1536x2048', + }, + { + assetName: 'assets/apple-touch-startup-image-1620x2160.png', + content: 'png 1620x2160', + }, + { + assetName: 'assets/apple-touch-startup-image-1668x2224.png', + content: 'png 1668x2224', + }, + { + assetName: 'assets/apple-touch-startup-image-1668x2388.png', + content: 'png 1668x2388', + }, + { + assetName: 'assets/apple-touch-startup-image-1792x828.png', + content: 'png 1792x828', + }, + { + assetName: 'assets/apple-touch-startup-image-2048x1536.png', + content: 'png 2048x1536', + }, + { + assetName: 'assets/apple-touch-startup-image-2048x2732.png', + content: 'png 2048x2732', + }, + { + assetName: 'assets/apple-touch-startup-image-2160x1620.png', + content: 'png 2160x1620', + }, + { + assetName: 'assets/apple-touch-startup-image-2208x1242.png', + content: 'png 2208x1242', + }, + { + assetName: 'assets/apple-touch-startup-image-2224x1668.png', + content: 'png 2224x1668', + }, + { + assetName: 'assets/apple-touch-startup-image-2388x1668.png', + content: 'png 2388x1668', + }, + { + assetName: 'assets/apple-touch-startup-image-2436x1125.png', + content: 'png 2436x1125', + }, + { + assetName: 'assets/apple-touch-startup-image-2532x1170.png', + content: 'png 2532x1170', + }, + { + assetName: 'assets/apple-touch-startup-image-2688x1242.png', + content: 'png 2688x1242', + }, + { + assetName: 'assets/apple-touch-startup-image-2732x2048.png', + content: 'png 2732x2048', + }, + { + assetName: 'assets/apple-touch-startup-image-2778x1284.png', + content: 'png 2778x1284', + }, + { + assetName: 'assets/apple-touch-startup-image-640x1136.png', + content: 'png 640x1136', + }, + { + assetName: 'assets/apple-touch-startup-image-750x1334.png', + content: 'png 750x1334', + }, + { + assetName: 'assets/apple-touch-startup-image-828x1792.png', + content: 'png 828x1792', + }, + { + assetName: 'assets/browserconfig.xml', + content: `␊ + ␊ + ␊ + ␊ + ␊ + ␊ + ␊ + ␊ + #fff␊ + ␊ + ␊ + `, + }, + { + assetName: 'assets/favicon-16x16.png', + content: 'png 16x16', + }, + { + assetName: 'assets/favicon-32x32.png', + content: 'png 32x32', + }, + { + assetName: 'assets/favicon-48x48.png', + content: 'png 48x48', + }, + { + assetName: 'assets/favicon.ico', + content: 'ico 16x16', + }, + { + assetName: 'assets/manifest.webmanifest', + content: `{␊ + "name": "favicons-webpack-plugin",␊ + "short_name": "favicons-webpack-plugin",␊ + "description": "Let webpack generate all your favicons and icons for you",␊ + "dir": "auto",␊ + "lang": "en-US",␊ + "display": "standalone",␊ + "orientation": "any",␊ + "start_url": "/?homescreen=1",␊ + "background_color": "#fff",␊ + "theme_color": "#fff",␊ + "icons": [␊ + {␊ + "src": "android-chrome-36x36.png",␊ + "sizes": "36x36",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-48x48.png",␊ + "sizes": "48x48",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-72x72.png",␊ + "sizes": "72x72",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-96x96.png",␊ + "sizes": "96x96",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-144x144.png",␊ + "sizes": "144x144",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-192x192.png",␊ + "sizes": "192x192",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-256x256.png",␊ + "sizes": "256x256",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-384x384.png",␊ + "sizes": "384x384",␊ + "type": "image/png",␊ + "purpose": "any"␊ + },␊ + {␊ + "src": "android-chrome-512x512.png",␊ + "sizes": "512x512",␊ + "type": "image/png",␊ + "purpose": "any"␊ + }␊ + ]␊ + }`, + }, + { + assetName: 'assets/mstile-144x144.png', + content: 'png 144x144', + }, + { + assetName: 'assets/mstile-150x150.png', + content: 'png 150x150', + }, + { + assetName: 'assets/mstile-310x150.png', + content: 'png 310x150', + }, + { + assetName: 'assets/mstile-310x310.png', + content: 'png 310x310', + }, + { + assetName: 'assets/mstile-70x70.png', + content: 'png 70x70', + }, + { + assetName: 'assets/yandex-browser-50x50.png', + content: 'png 50x50', + }, + { + assetName: 'assets/yandex-browser-manifest.json', + content: `{␊ + "version": "6.0.0",␊ + "api_version": 1,␊ + "layout": {␊ + "logo": "yandex-browser-50x50.png",␊ + "color": "#fff",␊ + "show_title": true␊ + }␊ + }`, + }, + ] diff --git a/test/snapshots/usage.test.mjs.snap b/test/snapshots/usage.test.mjs.snap new file mode 100644 index 00000000..0be25ced Binary files /dev/null and b/test/snapshots/usage.test.mjs.snap differ diff --git a/test/usage.test.mjs b/test/usage.test.mjs index e7fff4f9..9f207c1f 100644 --- a/test/usage.test.mjs +++ b/test/usage.test.mjs @@ -1,13 +1,37 @@ +import * as path from 'path'; import test from 'ava'; import FaviconsWebpackPlugin from '../src/index.js'; -import { logo } from './_util.mjs'; +import { + logo, + generate, + withTempDirectory, + snapshotCompilationAssets, +} from './_util.mjs'; -test('should take a string as argument', (t) => { - const plugin = new FaviconsWebpackPlugin(logo); - t.is(plugin.options.logo, logo); +withTempDirectory(test); + +test('should take a string as argument', async (t) => { + const output = path.join(t.context.root, 'output'); + + const compilationStats = await generate({ + output: { + path: output, + }, + plugins: [new FaviconsWebpackPlugin(logo)], + }); + + snapshotCompilationAssets(t, compilationStats); }); -test('should take an object with just the logo as argument', (t) => { - const plugin = new FaviconsWebpackPlugin({ logo }); - t.is(plugin.options.logo, logo); +test('should take an object with just the logo as argument', async (t) => { + const output = path.join(t.context.root, 'output'); + + const compilationStats = await generate({ + output: { + path: output, + }, + plugins: [new FaviconsWebpackPlugin({ logo })], + }); + + snapshotCompilationAssets(t, compilationStats); }); diff --git a/tsconfig.json b/tsconfig.json index 154a9892..b4912e18 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,17 @@ { + "include": ["src/**/*.js"], + "compilerOptions": { /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "target": "ES2021", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + "emitDeclarationOnly": true, /* Only emit .d.ts files; do not emit .js files. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ // "outDir": "./", /* Redirect output structure to the directory. */ @@ -17,7 +20,7 @@ // "incremental": true, /* Enable incremental compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ - "noEmit": true, /* Do not emit outputs. */ + // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */