diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 927e8f8..25410ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node_version: [8, 10, 12, 14, 16, 18, 20] + node_version: [10, 12, 14, 16, 18, 20] steps: - uses: actions/checkout@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f8e062..fc461ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,14 +8,14 @@ If you're filing a feature request, please remember: * Feature requests significantly expanding the scope of loglevel outside the description in [the readme](https://github.com/pimterry/loglevel/blob/master/README.md) will probably be rejected. * Features that can't be meaningfully implemented in a cross-environment compatible manner won't be implemented. * Please check the previously opened issues to see if somebody else has suggested it first. -* Consider submitting a pull request to add the feature instead, if you're confident it fits within the above +* Consider submitting a pull request to add the feature instead, if you're confident it fits within the above. If you're filing a bug, please remember: -* To provide detailed steps to reproduce the behaviour -* If possible, provide a Jasmine test which reproduces the behaviour -* Please specify the exact details of the environment in which it fails: OS + Environment (i.e. Browser or Node) + version -* Consider submitting a pull request to fix the bug instead +* To provide detailed steps to reproduce the behaviour. +* If possible, provide a Jasmine test which reproduces the behaviour. +* Please specify the exact details of the environment in which it fails: OS + Environment (i.e. Browser or Node) + version. +* Consider submitting a pull request to fix the bug instead. Helping develop loglevel ================================ @@ -26,38 +26,71 @@ Before submitting a pull request to fix a bug or add a new feature, please check To be more specific, before submitting your pull request please ensure: -* You haven't broken the existing test suite in any obvious browsers (at least check latest IE/FF/Chrome) -* You've added relevant tests for the bug you're fixing/the new feature you're adding/etc, which pass in all the relevant browsers -* JSHint is happy with your new code -* You've updated the API docs (in README.md) to detail any changes you've made to the public interface -* Your change is backward compatible (or you've explicitly said if it's not; this isn't great, but will be considered) -* You haven't changed any files in dist/ (these are auto-generated, and should only be changed on release) +* You haven't broken the existing test suite in any obvious browsers (at least check latest IE/FF/Chrome). +* You've added relevant tests for the bug you're fixing/the new feature you're adding/etc, which pass in all the relevant browsers. +* JSHint is happy with your new code. +* You've updated the API docs (in `README.md`) to detail any changes you've made to the public interface. +* Your change is backward-compatible (or you've explicitly said that it's not; this isn't great, but will be considered). +* You haven't changed any files in `dist/` (these are auto-generated, and should only be changed on release). + +Compatibility and JavaScript Runtimes +------------------------------------- + +loglevel aims to stay compatible with browsers, Node.js versions, and other JS runtimes that may be fairly old at this point! Please take care to match existing conventions and JavaScript language features wherever possible. For example, loglevel uses `var` instead of the newer `let` and `const` keywords to define variables, uses old-style `for` loops instead of the newer `for...of` loop, and so on. + +That said, loglevel's *test and development tools* utilize newer JavaScript and Node.js features. To run most tests or build releases, you will need a newer version of Node.js than is required at runtime (see details below in ["how to make your change…"](#how-to-make-your-change-and-submit-it)). Using newer features or making breaking changes to the *dev tools* is OK. Project structure ----------------- -The core project code is all in lib/loglevel.js, and this should be the only file you need to touch for functional changes themselves. +The core project code is all in [`lib/loglevel.js`](./lib/loglevel.js), and this should be the only file you need to touch for functional changes themselves. -The released code is in dist/*.js, and should not be touched by anything except releases +The released code is in `dist/*.js`, and should not be touched by anything except releases (pull requests should *not* update these files). -The test suite is entirely in test/*.js: +The test suite is entirely in `test/*.js`: -* Every file ending in '-test.js' is a unit test, is written in RequireJS, and should pass in any environment -* global-integration.js and node-integration.js are quick integration smoke tests for node and for browser global usage -* test-helpers.js contains some test utilities -* manual-test.html is a test page which includes the current loglevel build, so you can manually check it works in a given browser +* Every file ending in `-test.js` is a unit test, is written in RequireJS, and should pass in any environment. +* `global-integration.js` and `node-integration.js` are quick integration smoke tests for node and for browser global usage. +* `test-helpers.js` contains some test utilities. +* `manual-test.html` is a test page which includes the current loglevel build, so you can manually check that it works in a given browser. How to make your change and submit it ------------------------------------- -1. Fork loglevel -2. Clone your fork locally -3. Create a branch from master for your change -4. Write some tests in /test for your change, as relevant -5. Make your code changes in /lib/loglevel.js -6. Check your code all passes (run `grunt`) - if you have any issues try running `grunt jasmine:requirejs:src:build` (or a different test build instead of 'requirejs': see the jasmine config in Gruntfile.js) and debugging the generated _SpecRunner.html in a browser -7. Commit your changes -8. Open a pull request back to master in loglevel +1. Ensure you have Node.js v14 or later (some tests can run on earlier versions, but the full suite requires this version). +2. Fork loglevel. +3. Clone your fork locally. +4. Create a branch from `master` for your change. +5. Write some tests in `test/` for your change, as relevant. +6. Make your code changes in `lib/loglevel.js`. +7. Check your code all passes (run `npm test`). If you have issues and need to debug the tests, see the details on ["running tests"](#running-tests) below. +8. Commit your changes. +9. Open a pull request back to `master` in loglevel. + +Running Tests +------------- + +There are several types of tests and test tools that loglevel uses to verify different types of support in different environments. When you run `npm test`, *all* of these tests are run automatically. However, you may want to run individual types of tests during development, or run some tests manually to debug them. + +Test commands (see `"scripts"` in `package.json` for a complete list of tools): +- `npm test` — Runs all the below tests. +- `npm run test-browser` — Runs detailed tests in a headless browser. There are actually 3 sub-groups here: + - `npx grunt jasmine:global` — Tests general usage of the global `log` variable. + - `npx grunt test-browser-context` — Tests usage when loglevel is injected into an anonymous function instead of included as a regular script on the page. + - `npx grunt jasmine:requirejs` — Tests the main test suite via Jasmine & RequireJS. +- `npm run test-node` — Runs tests that check loglevel in Node.js. +- `npm run test-types` — Runs tests of the TypeScript type definitions for loglevel. + +Alternatively, you might want to run tests manually in your browser in order to use debugging tools to step through the code: +1. Run `npx grunt integration-test` to start a test server on port `8000`. +2. Your default browser should open the tests automatically, but if not, open `http://127.0.0.1:8000/_SpecRunner.html` in any browser. +3. Open your browser's dev tools and place breakpoints where you'd like to debug a test. +4. Reload the page to re-run the tests and pause on breakpoints. + +You can also open a blank webpage with loglevel pre-loaded to experiment in your browser's console: +1. Run `npx grunt integration-test` to start a test server on port `8000`. +2. In whatever browser you want to test, open `http://127.0.0.1:8000/test/manual-test.html`. +3. Play around with the global `log` object in the browser's dev console. Reporting security issues ------------------------- diff --git a/Gruntfile.js b/Gruntfile.js index 21c44a7..5af9f54 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -153,7 +153,8 @@ module.exports = function (grunt) { // Check everything is good grunt.registerTask('test', ['jshint', 'test-browser', 'test-node']); - grunt.registerTask('test-browser', ['jasmine:global', 'preprocess', 'jasmine:context', 'clean:test', 'jasmine:requirejs']); + grunt.registerTask('test-browser', ['jasmine:global', 'test-browser-context', 'jasmine:requirejs']); + grunt.registerTask('test-browser-context', ['preprocess', 'jasmine:context', 'clean:test']); grunt.registerTask('test-node', ['jasmine_node']); // Test with a live server and an actual browser diff --git a/README.md b/README.md index a523c18..31fe26c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > _Don't debug with logs alone - check out [HTTP Toolkit](https://httptoolkit.tech/javascript): beautiful, powerful & open-source tools for building, testing & debugging HTTP(S)_ -Minimal lightweight simple logging for JavaScript (browsers, node.js or elsewhere). loglevel extends console.log() & friends with level-based logging and filtering, with none of console's downsides. +Minimal lightweight simple logging for JavaScript (browsers, node.js or elsewhere). loglevel extends `console.log()` & friends with level-based logging and filtering, with none of console's downsides. Test it out live in your browser console at https://pimterry.github.io/loglevel/demo/index.html @@ -16,24 +16,24 @@ Loglevel is a barebones reliable everyday logging library. It does not do fancy ### Simple -* Log things at a given level (trace/debug/info/warn/error) to the console object (as seen in all modern browsers & node.js) -* Filter logging by level (all the above or 'silent'), so you can disable all but error logging in production, and then run log.setLevel("trace") in your console to turn it all back on for a furious debugging session -* Single file, no dependencies, weighs in at 1.1KB minified and gzipped +* Log things at a given level (trace/debug/info/warn/error) to the `console` object (as seen in all modern browsers & node.js). +* Filter logging by level (all the above or 'silent'), so you can disable all but error logging in production, and then run `log.setLevel("trace")` in your console to turn it all back on for a furious debugging session. +* Single file, no dependencies, weighs in at 1.4 KB minified and gzipped. ### Effective -* Log methods gracefully fall back to simpler console logging methods if more specific ones aren't available: so calls to log.debug() go to console.debug() if possible, or console.log() if not -* Logging calls still succeed even if there's no console object at all, so your site doesn't break when people visit with old browsers that don't support the console object (here's looking at you IE) and similar -* This then comes together giving a consistent reliable API that works in every JavaScript environment with a console available, and never breaks anything anywhere else +* Log methods gracefully fall back to simpler console logging methods if more specific ones aren't available: so calls to `log.debug()` go to `console.debug()` if possible, or `console.log()` if not. +* Logging calls still succeed even if there's no `console` object at all, so your site doesn't break when people visit with old browsers that don't support the `console` object (here's looking at you, IE) and similar. +* This then comes together giving a consistent reliable API that works in every JavaScript environment with a console available, and never breaks anything anywhere else. ### Convenient -* Log output keeps line numbers: most JS logging frameworks call console.log methods through wrapper functions, clobbering your stacktrace and making the extra info many browsers provide useless. We'll have none of that thanks. -* It works with all the standard JavaScript loading systems out of the box (CommonJS, AMD, or just as a global) -* Logging is filtered to "warn" level by default, to keep your live site clean in normal usage (or you can trivially re-enable everything with an initial log.enableAll() call) -* Magically handles situations where console logging is not initially available (IE8/9), and automatically enables logging as soon as it does become available (when developer console is opened) -* TypeScript type definitions included, so no need for extra `@types` packages -* Extensible, to add other log redirection, filtering, or formatting functionality, while keeping all the above (except you will clobber your stacktrace, see Plugins below) +* Log output keeps line numbers: most JS logging frameworks call `console.log` methods through wrapper functions, clobbering your stacktrace and making the extra info many browsers provide useless. We'll have none of that thanks. +* It works with all the standard JavaScript loading systems out of the box (CommonJS, AMD, or just as a global). +* Logging is filtered to "warn" level by default, to keep your live site clean in normal usage (or you can trivially re-enable everything with an initial `log.enableAll()` call). +* Magically handles situations where console logging is not initially available (IE8/9), and automatically enables logging as soon as it does become available (when developer console is opened). +* TypeScript type definitions included, so no need for extra `@types` packages. +* Extensible, to add other log redirection, filtering, or formatting functionality, while keeping all the above (except you will clobber your stacktrace, see [“Plugins”](#plugins) below). ## Downloading loglevel @@ -51,7 +51,7 @@ Finally, if you want to tweak loglevel to your own needs or you immediately need ## Setting it up -loglevel supports AMD (e.g. RequireJS), CommonJS (e.g. Node.js) and direct usage (e.g. loading globally with a <script> tag) loading methods. You should be able to do nearly anything, and then skip to the next section anyway and have it work. Just in case though, here's some specific examples that definitely do the right thing: +loglevel supports AMD (e.g. RequireJS), CommonJS (e.g. Node.js) and direct usage (e.g. loading globally with a `