├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── package.json ├── src └── index.js └── test ├── fixtures ├── destructuring │ ├── actual.js │ └── expected.js └── standard │ ├── actual.js │ └── expected.js └── test.js /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/** 2 | test/fixtures/** 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["eslint-config-semistandard"], 3 | "env": { 4 | "browser": true, 5 | "mocha": true, 6 | "node": true 7 | }, 8 | "ecmaFeatures": { 9 | }, 10 | "parser": "babel-eslint", 11 | "plugins": [ 12 | ], 13 | "rules": { 14 | "comma-dangle": [2, "always-multiline"], // disallow or enforce trailing commas 15 | "no-var": 2, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | *.log 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "4.0" 5 | - "6.0" 6 | script: 7 | - npm run lint 8 | - npm run test-mocha 9 | - npm run build 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | v3.0.0 - Tue, 15 Nov 2016 20:06:37 GMT 2 | -------------------------------------- 3 | 4 | - [d4f75a5](../../commit/d4f75a5) [fixed] Don't assert flow imports 5 | 6 | 7 | 8 | v2.1.0 - Tue, 05 Jan 2016 05:31:53 GMT 9 | -------------------------------------- 10 | 11 | - [ce69c24](../../commit/ce69c24) [changed] wrap assertion in a setTimout 12 | 13 | 14 | 15 | v2.0.0 - Fri, 13 Nov 2015 02:24:56 GMT 16 | -------------------------------------- 17 | 18 | - [69fefd4](../../commit/69fefd4) [changed] upgrade to babel 6 19 | - [ebe96ca](../../commit/ebe96ca) [added] updated README to actual output 20 | 21 | 22 | 23 | v1.0.2 - Fri, 18 Sep 2015 19:21:15 GMT 24 | -------------------------------------- 25 | 26 | - [f0076d0](../../commit/f0076d0) [fixed] again fix for npm files 27 | 28 | 29 | 30 | v1.0.1 - Fri, 18 Sep 2015 19:17:59 GMT 31 | -------------------------------------- 32 | 33 | - [bf2bcfd](../../commit/bf2bcfd) [fixed] directories for publishing 34 | 35 | 36 | 37 | v1.0.0 - Fri, 18 Sep 2015 19:11:54 GMT 38 | -------------------------------------- 39 | 40 | - [4f72a8d](../../commit/4f72a8d) [added] log to gitignore 41 | - [b963a8b](../../commit/b963a8b) [added] travis and badges 42 | - [0892cbe](../../commit/0892cbe) [added] tests 43 | - [bc39355](../../commit/bc39355) [added] description in README. 44 | - [ef3bfdb](../../commit/ef3bfdb) [added] build tools & LICENSE 45 | - [b0f2b4c](../../commit/b0f2b4c) [added] improved check for undefined, use console.assert 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Hugo Dozois 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-import-asserts 2 | Babel plugin that does the following: 3 | 4 | [![npm version][npm.img]][npm.url] 5 | [![Build Status](https://travis-ci.org/dozoisch/babel-plugin-import-asserts.svg)](https://travis-ci.org/dozoisch/babel-plugin-import-asserts) 6 | [![Dependency Status](https://david-dm.org/dozoisch/babel-plugin-import-asserts.svg)](https://david-dm.org/dozoisch/babel-plugin-import-asserts) 7 | [![devDependency Status](https://david-dm.org/dozoisch/babel-plugin-import-asserts/dev-status.svg)](https://david-dm.org/dozoisch/babel-plugin-import-asserts#info=devDependencies) 8 | [![peerDependency Status](https://david-dm.org/dozoisch/babel-plugin-import-asserts/peer-status.svg)](https://david-dm.org/dozoisch/babel-plugin-import-asserts#info=peerDependencies) 9 | 10 | For every `import baz, {foo, bar} from './baz';` it adds 11 | ``` 12 | console.assert(typeof foo !== 'undefined', '[IMPORT]: foo from ./abz is undefined'); 13 | console.assert(typeof bar !== 'undefined', '[IMPORT]: bar from ./abz is undefined'); 14 | console.assert(typeof baz !== 'undefined', '[IMPORT]: baz from ./abz is undefined'); 15 | ``` 16 | below the import statement. 17 | 18 | Motivation: 19 | 20 | 1. Catching typos in import can be hard and sometimes lead to cryptic errors. 21 | 2. Using destructuring with files containing constant can lead to weird behaviors if a constant is undefined without you knowing it. 22 | 23 | # Usage 24 | 25 | - With Babel 5.0 use version 1.X 26 | - With Babel 6.0 use version 2.X 27 | 28 | Make sure to use it only in development. 29 | 30 | In `.babelrc`: 31 | ``` 32 | { 33 | "stage": 0, 34 | "env": { 35 | "development": { 36 | "plugins": [ 37 | "import-asserts" 38 | ] 39 | } 40 | } 41 | ``` 42 | 43 | --- 44 | 45 | Inspired by: https://github.com/jonathanewerner/babel-plugin-import-asserts 46 | 47 | 48 | [npm.img]: https://badge.fury.io/js/babel-plugin-import-asserts.svg 49 | [npm.url]: http://badge.fury.io/js/babel-plugin-import-asserts 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-import-asserts", 3 | "version": "3.0.0", 4 | "description": "babel plugin that adds console.asserts which check that your imports are not undefined", 5 | "author": { 6 | "name": "Hugo Dozois-Caouette" 7 | }, 8 | "main": "lib/index.js", 9 | "directories": { 10 | "lib": "lib/" 11 | }, 12 | "files": [ 13 | "LICENSE", 14 | "README.md", 15 | "CHANGELOG.md", 16 | "lib" 17 | ], 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/dozoisch/babel-plugin-import-asserts.git" 22 | }, 23 | "scripts": { 24 | "test": "npm run lint && npm run build && npm run test-mocha", 25 | "test-mocha": "mocha --compilers js:babel-core/register", 26 | "build": "rm -rf lib && babel src --out-dir lib", 27 | "lint": "eslint ./", 28 | "patch": "release patch", 29 | "minor": "release minor", 30 | "major": "release major" 31 | }, 32 | "peerDependencies": { 33 | "babel-core": ">=6.0.0" 34 | }, 35 | "devDependencies": { 36 | "babel-cli": "^6.1.2", 37 | "babel-core": "^6.1.2", 38 | "babel-eslint": "^7.1.0", 39 | "babel-preset-es2015": "^6.1.2", 40 | "babel-preset-stage-1": "^6.3.13", 41 | "eslint": "^3.10.0", 42 | "eslint-config-semistandard": "^7.0.0", 43 | "eslint-config-standard": "^6.2.0", 44 | "eslint-plugin-babel": "^3.3.0", 45 | "eslint-plugin-promise": "^3.3.2", 46 | "eslint-plugin-standard": "^2.0.1", 47 | "mocha": "^3.1.2", 48 | "mt-changelog": "^0.6.2", 49 | "release-script": "^1.0.2" 50 | }, 51 | "keywords": [ 52 | "babel", 53 | "babel-plugin", 54 | "object", 55 | "assign", 56 | "extend", 57 | "polyfill" 58 | ], 59 | "babel": { 60 | "presets": [ 61 | "es2015", 62 | "stage-1" 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export default function (babel) { 2 | const t = babel.types; 3 | 4 | function timeout (assert) { 5 | return t.expressionStatement( 6 | t.callExpression( 7 | t.identifier('setTimeout'), 8 | [ 9 | t.functionExpression(null, [], t.blockStatement([assert])), 10 | t.numericLiteral(0), 11 | ] 12 | ) 13 | ); 14 | } 15 | 16 | function console_ (method, args) { 17 | return t.expressionStatement(t.callExpression( 18 | t.memberExpression( 19 | t.identifier('console'), 20 | t.identifier(method)), 21 | args)); 22 | } 23 | 24 | function consoleTest (thing, fromValue) { 25 | const assert = console_('assert', 26 | [ 27 | t.binaryExpression('!==', t.unaryExpression('typeof', t.identifier(thing)), t.stringLiteral('undefined')), 28 | t.stringLiteral('[IMPORT]:'), 29 | t.stringLiteral(thing), 30 | t.stringLiteral('from'), 31 | t.stringLiteral(fromValue), 32 | t.stringLiteral('is undefined.'), 33 | ] 34 | ); 35 | 36 | return timeout(assert); 37 | } 38 | 39 | return { 40 | visitor: { 41 | ImportDeclaration (path, state) { 42 | if (path.node.importKind !== 'type') { 43 | path.node.specifiers.map((specifier, idx) => { 44 | path.insertAfter(consoleTest(specifier.local.name, path.node.source.value)); 45 | }); 46 | } 47 | }, 48 | }, 49 | }; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /test/fixtures/destructuring/actual.js: -------------------------------------------------------------------------------- 1 | import { foo, baz } from 'bar'; 2 | import herp, { herpette } from 'derp'; 3 | export * from 'cueball'; 4 | -------------------------------------------------------------------------------- /test/fixtures/destructuring/expected.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _cueball = require('cueball'); 8 | 9 | Object.keys(_cueball).forEach(function (key) { 10 | if (key === "default" || key === "__esModule") return; 11 | Object.defineProperty(exports, key, { 12 | enumerable: true, 13 | get: function get() { 14 | return _cueball[key]; 15 | } 16 | }); 17 | }); 18 | 19 | var _bar = require('bar'); 20 | 21 | var _derp = require('derp'); 22 | 23 | var _derp2 = _interopRequireDefault(_derp); 24 | 25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 26 | 27 | setTimeout(function () { 28 | console.assert(typeof _bar.baz !== 'undefined', '[IMPORT]:', 'baz', 'from', 'bar', 'is undefined.'); 29 | }, 0); 30 | setTimeout(function () { 31 | console.assert(typeof _bar.foo !== 'undefined', '[IMPORT]:', 'foo', 'from', 'bar', 'is undefined.'); 32 | }, 0); 33 | setTimeout(function () { 34 | console.assert(typeof _derp.herpette !== 'undefined', '[IMPORT]:', 'herpette', 'from', 'derp', 'is undefined.'); 35 | }, 0); 36 | setTimeout(function () { 37 | console.assert(typeof _derp2.default !== 'undefined', '[IMPORT]:', 'herp', 'from', 'derp', 'is undefined.'); 38 | }, 0); 39 | -------------------------------------------------------------------------------- /test/fixtures/standard/actual.js: -------------------------------------------------------------------------------- 1 | import foo from 'bar'; 2 | import herp from 'derp'; 3 | -------------------------------------------------------------------------------- /test/fixtures/standard/expected.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _bar = require('bar'); 4 | 5 | var _bar2 = _interopRequireDefault(_bar); 6 | 7 | var _derp = require('derp'); 8 | 9 | var _derp2 = _interopRequireDefault(_derp); 10 | 11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 12 | 13 | setTimeout(function () { 14 | console.assert(typeof _bar2.default !== 'undefined', '[IMPORT]:', 'foo', 'from', 'bar', 'is undefined.'); 15 | }, 0); 16 | setTimeout(function () { 17 | console.assert(typeof _derp2.default !== 'undefined', '[IMPORT]:', 'herp', 'from', 'derp', 'is undefined.'); 18 | }, 0); 19 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import assert from 'assert'; 4 | import { transformFileSync } from 'babel-core'; 5 | import plugin from '../src'; 6 | 7 | function trim (str) { 8 | return str.replace(/^\s+|\s+$/, ''); 9 | } 10 | 11 | describe('should add asserts under imports', () => { 12 | const fixturesDir = path.join(__dirname, 'fixtures'); 13 | fs.readdirSync(fixturesDir).map((caseName) => { 14 | it(`should ${caseName.split('-').join(' ')}`, () => { 15 | const fixtureDir = path.join(fixturesDir, caseName); 16 | const actualPath = path.join(fixtureDir, 'actual.js'); 17 | const actual = transformFileSync(actualPath, { 18 | plugins: [plugin], 19 | }).code; 20 | const expected = fs.readFileSync( 21 | path.join(fixtureDir, 'expected.js') 22 | ).toString().replace(/%FIXTURE_PATH%/g, actualPath); 23 | assert.equal(trim(actual), trim(expected)); 24 | }); 25 | }); 26 | }); 27 | --------------------------------------------------------------------------------