From 4ad3c5774a26fd78449b91d3d4aefe670f3deee2 Mon Sep 17 00:00:00 2001 From: surunzi Date: Wed, 27 Sep 2017 16:52:13 +0800 Subject: [PATCH] Add: logger --- .eslintrc.json | 3 +- script/webpack.base.js | 69 ++++++ script/webpack.dev.js | 78 +------ script/webpack.release.js | 5 +- src/index.es6 | 18 +- src/lib/logger.es6 | 12 + src/lib/util.js | 473 +++++++++++++++++++++++++++++++------- 7 files changed, 509 insertions(+), 149 deletions(-) create mode 100644 script/webpack.base.js create mode 100644 src/lib/logger.es6 diff --git a/.eslintrc.json b/.eslintrc.json index 0b1e1ca..7b934ff 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,7 +9,8 @@ "sourceType": "module" }, "globals": { - "VERSION": true + "VERSION": true, + "ENV": true }, "rules": { "quotes": [ diff --git a/script/webpack.base.js b/script/webpack.base.js new file mode 100644 index 0000000..d349342 --- /dev/null +++ b/script/webpack.base.js @@ -0,0 +1,69 @@ +var autoprefixer = require('autoprefixer'), + classPrefix = require('postcss-class-prefix'), + webpack = require('webpack'), + pkg = require('../package.json'), + path = require('path'); + +process.traceDeprecation = true; + +var nodeModDir = path.resolve('./node_modules/') + '/', + banner = pkg.name + ' v' + pkg.version + ' ' + pkg.homepage; + +var postcssLoader = { + loader: 'postcss-loader', + options: { + plugins: [classPrefix('eruda-'), autoprefixer] + } +}; + +module.exports = { + entry: './src/index.es6', + devServer: { + contentBase: './test', + port: 3000 + }, + output: { + path: path.resolve(__dirname, '../'), + publicPath: "/assets/", + library: ['eruda'], + libraryTarget: 'umd' + }, + module: { + loaders: [ + { + test: /\.es6$/, + loader: 'babel-loader', + options: { + presets: ['es2015'], + plugins: ['transform-runtime'] + } + }, + { + test: /\.scss$/, + loaders: ['css-loader', postcssLoader, 'sass-loader'] + }, + { + test: /\.css$/, + loaders: ['css-loader', postcssLoader] + }, + // https://github.com/wycats/handlebars.js/issues/1134 + { + test: /\.hbs$/, + loader: nodeModDir + 'handlebars-loader/index.js', + options: { + runtime: nodeModDir + 'handlebars/dist/handlebars.runtime.js' + } + }, + { + test: /\.json$/, + loader: 'json-loader' + } + ] + }, + plugins: [ + new webpack.BannerPlugin(banner), + new webpack.DefinePlugin({ + VERSION: '"' + pkg.version + '"' + }) + ] +}; \ No newline at end of file diff --git a/script/webpack.dev.js b/script/webpack.dev.js index 9025497..c0c8180 100644 --- a/script/webpack.dev.js +++ b/script/webpack.dev.js @@ -1,71 +1,13 @@ -var autoprefixer = require('autoprefixer'), - classPrefix = require('postcss-class-prefix'), - webpack = require('webpack'), - pkg = require('../package.json'), - path = require('path'); +var webpack = require('webpack'); -process.traceDeprecation = true; +exports = require('./webpack.base'); -var nodeModDir = path.resolve('./node_modules/') + '/', - banner = pkg.name + ' v' + pkg.version + ' ' + pkg.homepage; +exports.output.filename = 'eruda.js'; +exports.devtool = false; +exports.plugins = exports.plugins.concat([ + new webpack.DefinePlugin({ + ENV: '"development"', + }) +]); -var postcssLoader = { - loader: 'postcss-loader', - options: { - plugins: [classPrefix('eruda-'), autoprefixer] - } -}; - -module.exports = { - devtool: false, - entry: './src/index.es6', - devServer: { - contentBase: './test', - port: 3000 - }, - output: { - path: path.resolve(__dirname, '../'), - publicPath: "/assets/", - filename: 'eruda.js', - library: ['eruda'], - libraryTarget: 'umd' - }, - module: { - loaders: [ - { - test: /\.es6$/, - loader: 'babel-loader', - options: { - presets: ['es2015'], - plugins: ['transform-runtime'] - } - }, - { - test: /\.scss$/, - loaders: ['css-loader', postcssLoader, 'sass-loader'] - }, - { - test: /\.css$/, - loaders: ['css-loader', postcssLoader] - }, - // https://github.com/wycats/handlebars.js/issues/1134 - { - test: /\.hbs$/, - loader: nodeModDir + 'handlebars-loader/index.js', - options: { - runtime: nodeModDir + 'handlebars/dist/handlebars.runtime.js' - } - }, - { - test: /\.json$/, - loader: 'json-loader' - } - ] - }, - plugins: [ - new webpack.BannerPlugin(banner), - new webpack.DefinePlugin({ - VERSION: '\'' + pkg.version + '\'' - }) - ] -}; \ No newline at end of file +module.exports = exports; \ No newline at end of file diff --git a/script/webpack.release.js b/script/webpack.release.js index 7235870..b173a66 100644 --- a/script/webpack.release.js +++ b/script/webpack.release.js @@ -1,6 +1,6 @@ var webpack = require('webpack'); -exports = require('./webpack.dev'); +exports = require('./webpack.base'); exports.output.filename = 'eruda.min.js'; exports.devtool = false; @@ -10,6 +10,9 @@ exports.plugins = exports.plugins.concat([ warnings: false }, comments: /eruda/ + }), + new webpack.DefinePlugin({ + ENV: '"production"', }) ]); diff --git a/src/index.es6 b/src/index.es6 index 3609329..afcea2d 100644 --- a/src/index.es6 +++ b/src/index.es6 @@ -11,11 +11,14 @@ import Sources from './Sources/Sources.es6' import Settings from './Settings/Settings.es6' import util from './lib/util' import config from './lib/config.es6' +import logger from './lib/logger.es6' import extraUtil from './lib/extraUtil.es6' module.exports = { init({el, tool} = {}) { + this._isInit = true; + this._initContainer(el); this._initStyle(); this._initDevTools(); @@ -23,17 +26,22 @@ module.exports = { this._initSettings(); this._initTools(tool); }, + _isInit: false, version: VERSION, config, util, Console, Elements, Network, Sources, Resources, Info, Snippets, Features, get(name) { + if (!this._checkInit()) return; + let devTools = this._devTools; return name ? devTools.get(name) : devTools; }, add(tool) { + if (!this._checkInit()) return; + if (util.isFn(tool)) tool = tool(this); this._devTools.add(tool); @@ -42,18 +50,27 @@ module.exports = { }, remove(name) { + if (!this._checkInit()) return; + this._devTools.remove(name); return this; }, show(name) { + if (!this._checkInit()) return; + let devTools = this._devTools; name ? devTools.showTool(name) : devTools.show(); return this; }, + _checkInit() + { + if (!this._isInit) logger.error('Please call "eruda.init()" first'); + return this._isInit; + }, _initContainer(el) { if (!el) @@ -129,4 +146,3 @@ module.exports = { }; extraUtil(util); - diff --git a/src/lib/logger.es6 b/src/lib/logger.es6 new file mode 100644 index 0000000..170049d --- /dev/null +++ b/src/lib/logger.es6 @@ -0,0 +1,12 @@ +import util from './util' + +let logger; + +export default logger = new util.Logger('[Eruda]', ENV === 'production' ? 'warn' : 'debug'); + +logger.formatter = function (type, argList) +{ + argList.unshift(this.name); + + return argList; +}; diff --git a/src/lib/util.js b/src/lib/util.js index d2ac64a..2e96f42 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -234,6 +234,86 @@ module.exports = (function () return exports; })(); + /* ------------------------------ keys ------------------------------ */ + + var keys = _.keys = (function (exports) + { + /* Create an array of the own enumerable property names of object. + * + * |Name |Type |Desc | + * |------|------|-----------------------| + * |obj |object|Object to query | + * |return|array |Array of property names| + * + * ```javascript + * keys({a: 1}); // -> ['a'] + * ``` + */ + + /* dependencies + * has + */ + + exports = Object.keys || function (obj) + { + var ret = [], key; + + for (key in obj) + { + if (has(obj, key)) ret.push(key); + } + + return ret; + }; + + return exports; + })({}); + + /* ------------------------------ freeze ------------------------------ */ + + var freeze = _.freeze = (function () + { + /* Shortcut for Object.freeze. + * + * Use Object.defineProperties if Object.freeze is not supported. + * + * |Name |Type |Desc | + * |------|------|----------------| + * |obj |object|Object to freeze| + * |return|object|Object passed in| + * + * ```javascript + * var a = {b: 1}; + * freeze(a); + * a.b = 2; + * console.log(a); // -> {b: 1} + * ``` + */ + + /* dependencies + * keys + */ + + function exports(obj) + { + if (Object.freeze) return Object.freeze(obj); + + keys(obj).forEach(function (prop) + { + if (!Object.getOwnPropertyDescriptor(obj, prop).configurable) return; + + Object.defineProperty(obj, prop, { + writable: false, + configurable: false + }); + }); + + return obj; + } + + return exports; + })(); + /* ------------------------------ noop ------------------------------ */ var noop = _.noop = (function () @@ -486,41 +566,6 @@ module.exports = (function () return exports; })(); - /* ------------------------------ keys ------------------------------ */ - - var keys = _.keys = (function (exports) - { - /* Create an array of the own enumerable property names of object. - * - * |Name |Type |Desc | - * |------|------|-----------------------| - * |obj |object|Object to query | - * |return|array |Array of property names| - * - * ```javascript - * keys({a: 1}); // -> ['a'] - * ``` - */ - - /* dependencies - * has - */ - - exports = Object.keys || function (obj) - { - var ret = [], key; - - for (key in obj) - { - if (has(obj, key)) ret.push(key); - } - - return ret; - }; - - return exports; - })({}); - /* ------------------------------ optimizeCb ------------------------------ */ var optimizeCb = _.optimizeCb = (function () @@ -886,6 +931,95 @@ module.exports = (function () return exports; })({}); + /* ------------------------------ castPath ------------------------------ */ + + var castPath = _.castPath = (function () + { + /* Cast value into a property path array. + * + * |Name |Type |Desc | + * |------|------|-------------------| + * |str |* |Value to inspect | + * |[obj] |object|Object to query | + * |return|array |Property path array| + * + * ```javascript + * castPath('a.b.c'); // -> ['a', 'b', 'c'] + * castPath(['a']); // -> ['a'] + * castPath('a[0].b'); // -> ['a', '0', 'b'] + * castPath('a.b.c', {'a.b.c': true}); // -> ['a.b.c'] + * ``` + */ + + /* dependencies + * has isArr + */ + + function exports(str, obj) + { + if (isArr(str)) return str; + if (obj && has(obj, str)) return [str]; + + var ret = []; + + str.replace(regPropName, function(match, number, quote, str) + { + ret.push(quote ? str.replace(regEscapeChar, '$1') : (number || match)); + }); + + return ret; + } + + // Lodash _stringToPath + var regPropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, + regEscapeChar = /\\(\\)?/g; + + return exports; + })(); + + /* ------------------------------ safeGet ------------------------------ */ + + var safeGet = _.safeGet = (function () + { + /* Get object property, don't throw undefined error. + * + * |Name |Type |Desc | + * |------|------------|-------------------------| + * |obj |object |Object to query | + * |path |array string|Path of property to get | + * |return|* |Target value or undefined| + * + * ```javascript + * var obj = {a: {aa: {aaa: 1}}}; + * safeGet(obj, 'a.aa.aaa'); // -> 1 + * safeGet(obj, ['a', 'aa']); // -> {aaa: 1} + * safeGet(obj, 'a.b'); // -> undefined + * ``` + */ + + /* dependencies + * isUndef castPath + */ + + function exports(obj, path) + { + path = castPath(path, obj); + + var prop; + + /* eslint-disable no-cond-assign */ + while (prop = path.shift()) + { + obj = obj[prop]; + if (isUndef(obj)) return; + } + + return obj; + } + + return exports; + })(); + /* ------------------------------ isDate ------------------------------ */ var isDate = _.isDate = (function () @@ -1262,6 +1396,38 @@ module.exports = (function () return exports; })({}); + /* ------------------------------ clone ------------------------------ */ + + var clone = _.clone = (function () + { + /* Create a shallow-copied clone of the provided plain object. + * + * Any nested objects or arrays will be copied by reference, not duplicated. + * + * |Name |Type|Desc | + * |------|----|--------------| + * |val |* |Value to clone| + * |return|* |Cloned value | + * + * ```javascript + * clone({name: 'eustia'}); // -> {name: 'eustia'} + * ``` + */ + + /* dependencies + * isObj isArr extend + */ + + function exports(obj) + { + if (!isObj(obj)) return obj; + + return isArr(obj) ? obj.slice() : extend({}, obj); + } + + return exports; + })(); + /* ------------------------------ extendOwn ------------------------------ */ var extendOwn = _.extendOwn = (function (exports) @@ -1417,49 +1583,6 @@ module.exports = (function () return exports; })(); - /* ------------------------------ safeGet ------------------------------ */ - - var safeGet = _.safeGet = (function () - { - /* Get object property, don't throw undefined error. - * - * |Name |Type |Desc | - * |------|------------|-------------------------| - * |obj |object |Object to query | - * |path |array string|Path of property to get | - * |return|* |Target value or undefined| - * - * ```javascript - * var obj = {a: {aa: {aaa: 1}}}; - * safeGet(obj, 'a.aa.aaa'); // -> 1 - * safeGet(obj, ['a', 'aa']); // -> {aaa: 1} - * safeGet(obj, 'a.b'); // -> undefined - * ``` - */ - - /* dependencies - * isStr isUndef - */ - - function exports(obj, path) - { - if (isStr(path)) path = path.split('.'); - - var prop; - - /* eslint-disable no-cond-assign */ - while (prop = path.shift()) - { - obj = obj[prop]; - if (isUndef(obj)) return; - } - - return obj; - } - - return exports; - })(); - /* ------------------------------ isBool ------------------------------ */ _.isBool = (function () @@ -2407,6 +2530,64 @@ module.exports = (function () return exports; })(); + /* ------------------------------ Enum ------------------------------ */ + + var Enum = _.Enum = (function (exports) + { + /* Enum type implementation. + * + * ### constructor + * + * |Name|Type |Desc | + * |----|-----|----------------| + * |arr |array|Array of strings| + * + * |Name|Type |Desc | + * |----|------|----------------------| + * |obj |object|Pairs of key and value| + * + * ```javascript + * var importance = new Enum([ + * 'NONE', 'TRIVIAL', 'REGULAR', 'IMPORTANT', 'CRITICAL' + * ]); + * + * if (val === importance.CRITICAL) + * { + * // Do something. + * } + * ``` + */ + + /* dependencies + * Class freeze isArr each keys + */ + + exports = Class({ + initialize: function Enum(map) + { + if (isArr(map)) + { + this.size = map.length; + each(map, function (member, val) + { + this[member] = val; + }, this); + } else + { + this.size = keys(map).length; + each(map, function (val, member) + { + this[member] = val; + }, this); + } + + freeze(this); + } + }); + + return exports; + })({}); + /* ------------------------------ Select ------------------------------ */ var Select = _.Select = (function (exports) @@ -3952,6 +4133,142 @@ module.exports = (function () return exports; })({}); + /* ------------------------------ Logger ------------------------------ */ + + _.Logger = (function (exports) + { + /* Simple logger with level filter. + * + * ### constructor + * + * |Name |Type |Desc | + * |-------------|------|------------| + * |name |string|Logger name | + * |[level=DEBUG]|number|Logger level| + * + * ### setLevel + * + * |Name |Type |Desc | + * |-----|-------------|------------| + * |level|number string|Logger level| + * + * ### getLevel + * + * Get current level. + * + * ### trace, debug, info, warn, error + * + * Logging methods. + * + * ### Log Levels + * + * TRACE, DEBUG, INFO, WARN, ERROR and SILENT. + * + * ```javascript + * var logger = new Logger('eris', logger.level.ERROR); + * logger.trace('test'); + * + * // Format output. + * logger.formatter = function (type, argList) + * { + * argList.push(new Date().getTime()); + * + * return argList; + * }; + * + * logger.on('all', function (type, argList) + * { + * // It's not affected by log level. + * }); + * + * logger.on('debug', function (argList) + * { + * // Affected by log level. + * }); + * ``` + */ + + /* dependencies + * Emitter Enum toArr isUndef clone isStr isNum + */ + + exports = Emitter.extend({ + initialize: function Logger(name, level) + { + this.name = name; + + this.setLevel(isUndef(level) ? exports.level.DEBUG : level); + this.callSuper(Emitter, 'initialize', arguments); + }, + setLevel: function (level) + { + if (isStr(level)) + { + level = exports.level[level.toUpperCase()]; + if (level) this._level = level; + return this; + } + if (isNum(level)) this._level = level; + + return this; + }, + getLevel: function () + { + return this._level; + }, + formatter: function (type, argList) + { + return argList; + }, + trace: function () + { + return this._log('trace', arguments); + }, + debug: function () + { + return this._log('debug', arguments); + }, + info: function () + { + return this._log('info', arguments); + }, + warn: function () + { + return this._log('warn', arguments); + }, + error: function () + { + return this._log('error', arguments); + }, + _log: function (type, argList) + { + argList = toArr(argList); + if (argList.length === 0) return this; + + this.emit('all', type, clone(argList)); + + if (exports.level[type.toUpperCase()] < this._level) return this; + this.emit(type, clone(argList)); + /* eslint-disable no-console */ + var consoleMethod = type === 'debug' ? console.log : console[type]; + consoleMethod.apply(console, this.formatter(type, argList)); + + return this; + } + }, { + level: new Enum({ + TRACE: 0, + DEBUG: 1, + INFO: 2, + WARN: 3, + ERROR: 4, + SILENT: 5 + }) + }); + + return exports; + })({}); + /* ------------------------------ orientation ------------------------------ */ _.orientation = (function (exports)