diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..86c8f59 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[package.json] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..5bbdb80 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,25 @@ +{ + 'parser': 'babel-eslint', + 'rules': { + 'linebreak-style': [2, 'unix'], + 'semi': [2, 'always'], + 'no-console': 0, + 'no-mixed-spaces-and-tabs': 2, + 'indent': [2, 4], + 'quotes': [2, 'single'], + 'quote-props': [2, 'consistent-as-needed'], + 'no-underscore-dangle': 0, + 'arrow-body-style': 0, + }, + 'env': { + 'es6': false, + 'browser': true + }, + 'presets': [ + 'es2015' + ], + 'plugins': [ + ], + 'whitelist': [ + ] +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/LICENSE.md b/LICENSE.md index 427417b..67db858 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -173,30 +173,3 @@ defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index 3d37a0e..484a103 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [TrimKit](https://gitlab.com/explorigin/trimkit) -TrimKit is a set of DOM and API abstactions for the purpose of better Javascript minification. For example: +TrimKit is a set of DOM and API abstractions for the purpose of better Javascript minification. For example: if (a === undefined) { alert('Oops'); } @@ -16,7 +16,7 @@ If we compare against undefined more than 3 times, we can save bytes by doing th which minifies down to: - function b(a) { return a === void 0; } + function b(a){return a===void 0} if (b(a)){alert('Oops');} @@ -24,6 +24,24 @@ With enough uses of common APIs, you can win back some bytes. NOTE: TrimKit will help you obsess about Javascript file sizes but that does not always translate to smaller files after you apply compression. Because files using have more entropy, small, pre-compression gains can result in after compression losses. YMMV. + +# Abstractions + + - `undefined` + - `requestAnimationFrame` + - `Array.isArray` + - `Array.from` + - `Object.keys` + - `document` + - `typeof obj === 'function'` + - `typeof obj === 'string'` + - `typeof obj === 'number'` + - `null` + - `obj === undefined` + - `obj === null` + - `fn.apply(context, params)` + + ## Credit Created by [Timothy Farrell](https://github.com/explorigin) diff --git a/dist/trimkit.js b/dist/trimkit.js new file mode 100644 index 0000000..37dcb52 --- /dev/null +++ b/dist/trimkit.js @@ -0,0 +1,129 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.Trimkit = global.Trimkit || {}))); +}(this, function (exports) { 'use strict'; + + // Copyright (c) 2016 Timothy Farrell + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + // ES5 output: var a=void 0; + // Invocation comparison: undefined ~~~ a + // Size delta per invocation: 9 - 1 = 8 bytes + // Size saved after: ceil(13 / 8) = 2 usages + const Undefined = void 0; + + // ES5 output: var a=requestAnimationFrame; + // Invocation comparison: requestAnimationFrame(b) ~~~ a(b) + // Size delta per invocation: 24 - 4 = 20 bytes + // Size saved after: ceil(28 / 20) = 2 usages + const requestAnimationFrame = self.requestAnimationFrame; + + // ES5 output: var a=Array.isArray; + // Invocation comparison: Array.isArray(b) ~~~ a(b) + // Size delta per invocation: 16 - 4 = 12 bytes + // Size saved after: ceil(20 / 12) = 2 usages + const isArray = Array.isArray; + + // ES5 output: var a=Array.from; + // Invocation comparison: Array.from(b) ~~~ a(b) + // Size delta per invocation: 13 - 4 = 9 bytes + // Size saved after: ceil(17 / 9) = 2 usages + const asArray = Array.from; + + // ES5 output: var a=Object.keys; + // Invocation comparison: Object.Keys(b) ~~~ a(b) + // Size delta per invocation: 14 - 4 = 10 bytes + // Size saved after: ceil(18 / 10) = 2 usages + const ObjectKeys = Object.keys; + + // ES5 output: var a=self.document; + // Invocation comparison: document ~~~ a + // Size delta per invocation: 8 - 1 = 7 bytes + // Size saved after: ceil(20 / 7) = 3 usages + const DOMDocument = self.document; + + // ES5 output: function a(b){return"function"===typeof b}; + // Invocation comparison: typeof a==='function' ~~~ a(b) + // Size delta per invocation: 21 - 4 = 17 bytes + // Size saved after: ceil(43 / 17) = 3 usages + function isFunction(obj) { + return typeof obj === 'function'; + } + + // ES5 output: function a(b){return"string"===typeof b}; + // Invocation comparison: typeof a==='string' ~~~ a(b) + // Size delta per invocation: 19 - 4 = 15 bytes + // Size saved after: ceil(41 / 15) = 3 usages + function isString(obj) { + return typeof obj === 'string'; + } + + // ES5 output: function a(b){return"number"===typeof b}; + // Invocation comparison: typeof a==='number' ~~~ a(b) + // Size delta per invocation: 19 - 4 = 15 bytes + // Size saved after: ceil(41 / 15) = 3 usages + function isNumber(obj) { + return typeof obj === 'number'; + } + + // ES5 declaration: var a=null; + // Invocation comparison: null ~~~ a + // Size delta per invocation: 4 - 1 = 3 bytes + // Size saved after: ceil(11 / 3) = 4 usages + const Null = null; + + // ES5 output: function a(b){return void 0===b}; + // Invocation comparison: b===undefined ~~~ a(b) + // Size delta per invocation: 13 - 4 = 9 bytes + // Size saved after: ceil(33 / 9) = 4 usages + function isUndefined(a) { + return a === undefined; + } + + // ES5 output: function a(b,c){return a.apply(b,c)}; + // Invocation comparison A: a.apply(b,c,d) ~~~ a(b,c,d) + // Invocation comparison B: a.apply(b,c) ~~~ a(b,c) + // Size delta per invocation A: 14 - 8 = 6 bytes + // Size delta per invocation B: 12 - 6 = 6 bytes + // Size saved after: ceil(37 / 6) = 7 usages + function apply(obj, context, params) { + return obj.apply(context, params); + } + + // ES5 output: function a(b){return null===b}; + // Invocation comparison: b===null ~~~ a(b) + // Size delta per invocation: 8 - 4 = 4 bytes + // Size saved after: ceil(31 / 4) = 8 usages + function isNull(a) { + return a === null; + } + + exports.Undefined = Undefined; + exports.requestAnimationFrame = requestAnimationFrame; + exports.isArray = isArray; + exports.asArray = asArray; + exports.ObjectKeys = ObjectKeys; + exports.DOMDocument = DOMDocument; + exports.isFunction = isFunction; + exports.isString = isString; + exports.isNumber = isNumber; + exports.Null = Null; + exports.isUndefined = isUndefined; + exports.apply = apply; + exports.isNull = isNull; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); \ No newline at end of file diff --git a/dist/trimkit.min.js b/dist/trimkit.min.js new file mode 100644 index 0000000..ab97076 --- /dev/null +++ b/dist/trimkit.min.js @@ -0,0 +1 @@ +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.Trimkit=e.Trimkit||{})}(this,function(e){"use strict";function n(e){return"function"==typeof e}function t(e){return"string"==typeof e}function i(e){return"number"==typeof e}function r(e){return void 0===e}function o(e,n,t){return e.apply(n,t)}function u(e){return null===e}const f=void 0,s=self.requestAnimationFrame,c=Array.isArray,d=Array.from,y=Object.keys,l=self.document,a=null;e.Undefined=f,e.requestAnimationFrame=s,e.isArray=c,e.asArray=d,e.ObjectKeys=y,e.DOMDocument=l,e.isFunction=n,e.isString=t,e.isNumber=i,e.Null=a,e.isUndefined=r,e.apply=o,e.isNull=u,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/dist/trimkit.min.js.gz b/dist/trimkit.min.js.gz new file mode 100644 index 0000000..42dce8d Binary files /dev/null and b/dist/trimkit.min.js.gz differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..11fc076 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "trimkit", + "version": "1.0.0", + "description": "Javascript and DOM abstractions for smaller minifiable code", + "main": "src/index.js", + "files": [ + "dist", + "src" + ], + "scripts": { + "lint": "eslint src", + "clean": "rimraf dist", + "build:umd": "NODE_ENV=production rollup -c", + "build:umd:min": "npm run build:umd && uglifyjs -m --screw-ie8 -c -o dist/trimkit.min.js dist/trimkit.js", + "build:umd:gzip": "npm run build:umd:min && gzip -c9 dist/trimkit.min.js > dist/trimkit.min.js.gz", + "build": "npm run build:umd:gzip && ls -l dist/", + "prepublish": "npm run clean && npm run build" + }, + "repository": { + "type": "git", + "url": "https://gitlab.com/explorigin/trimkit.git" + }, + "keywords": [ + "javascript" + ], + "author": "Timothy Farrell (https://github.com/explorigin)", + "license": "Apache 2.0", + "bugs": { + "url": "https://gitlab.com/explorigin/trimkit/issues" + }, + "homepage": "https://gitlab.com/explorigin/trimkit", + "devDependencies": { + "babel-eslint": "^7.1.1", + "eslint": "3.2.0", + "eslint-plugin-flow-vars": "0.5.0", + "eslint-plugin-flowtype": "2.4.0", + "rimraf": "2.5.2", + "rollup-plugin-json": "2.0.1", + "uglifyjs": "2.4.10" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..c65d50b --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,10 @@ +import json from 'rollup-plugin-json'; + + +export default { + entry: 'src/index.js', + format: 'umd', + moduleName: 'Trimkit', + plugins: [ json() ], + dest: 'dist/trimkit.js' +}; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..a44ec11 --- /dev/null +++ b/src/index.js @@ -0,0 +1,105 @@ +// Copyright (c) 2016 Timothy Farrell +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// ES5 output: var a=void 0; +// Invocation comparison: undefined ~~~ a +// Size delta per invocation: 9 - 1 = 8 bytes +// Size saved after: ceil(13 / 8) = 2 usages +export const Undefined = void 0; + +// ES5 output: var a=requestAnimationFrame; +// Invocation comparison: requestAnimationFrame(b) ~~~ a(b) +// Size delta per invocation: 24 - 4 = 20 bytes +// Size saved after: ceil(28 / 20) = 2 usages +export const requestAnimationFrame = self.requestAnimationFrame; + +// ES5 output: var a=Array.isArray; +// Invocation comparison: Array.isArray(b) ~~~ a(b) +// Size delta per invocation: 16 - 4 = 12 bytes +// Size saved after: ceil(20 / 12) = 2 usages +export const isArray = Array.isArray; + +// ES5 output: var a=Array.from; +// Invocation comparison: Array.from(b) ~~~ a(b) +// Size delta per invocation: 13 - 4 = 9 bytes +// Size saved after: ceil(17 / 9) = 2 usages +export const asArray = Array.from; + +// ES5 output: var a=Object.keys; +// Invocation comparison: Object.Keys(b) ~~~ a(b) +// Size delta per invocation: 14 - 4 = 10 bytes +// Size saved after: ceil(18 / 10) = 2 usages +export const ObjectKeys = Object.keys; + +// ES5 output: var a=self.document; +// Invocation comparison: document ~~~ a +// Size delta per invocation: 8 - 1 = 7 bytes +// Size saved after: ceil(20 / 7) = 3 usages +export const DOMDocument = self.document; + +// ES5 output: function a(b){return"function"===typeof b}; +// Invocation comparison: typeof a==='function' ~~~ a(b) +// Size delta per invocation: 21 - 4 = 17 bytes +// Size saved after: ceil(43 / 17) = 3 usages +export function isFunction(obj) { + return typeof obj === 'function'; +} + +// ES5 output: function a(b){return"string"===typeof b}; +// Invocation comparison: typeof a==='string' ~~~ a(b) +// Size delta per invocation: 19 - 4 = 15 bytes +// Size saved after: ceil(41 / 15) = 3 usages +export function isString(obj) { + return typeof obj === 'string'; +} + +// ES5 output: function a(b){return"number"===typeof b}; +// Invocation comparison: typeof a==='number' ~~~ a(b) +// Size delta per invocation: 19 - 4 = 15 bytes +// Size saved after: ceil(41 / 15) = 3 usages +export function isNumber(obj) { + return typeof obj === 'number'; +} + +// ES5 declaration: var a=null; +// Invocation comparison: null ~~~ a +// Size delta per invocation: 4 - 1 = 3 bytes +// Size saved after: ceil(11 / 3) = 4 usages +export const Null = null; + +// ES5 output: function a(b){return void 0===b}; +// Invocation comparison: b===undefined ~~~ a(b) +// Size delta per invocation: 13 - 4 = 9 bytes +// Size saved after: ceil(33 / 9) = 4 usages +export function isUndefined(a) { + return a === undefined; +} + +// ES5 output: function a(b,c){return a.apply(b,c)}; +// Invocation comparison A: a.apply(b,c,d) ~~~ a(b,c,d) +// Invocation comparison B: a.apply(b,c) ~~~ a(b,c) +// Size delta per invocation A: 14 - 8 = 6 bytes +// Size delta per invocation B: 12 - 6 = 6 bytes +// Size saved after: ceil(37 / 6) = 7 usages +export function apply(fn, context, params) { + return fn.apply(context, params); +} + +// ES5 output: function a(b){return null===b}; +// Invocation comparison: b===null ~~~ a(b) +// Size delta per invocation: 8 - 4 = 4 bytes +// Size saved after: ceil(31 / 4) = 8 usages +export function isNull(a) { + return a === null; +}