Modules

  • 10.1 Always use modules (import/export) over a non-standard module system. You can always transpile to your preferred module system.

    Why? Modules are the future, let’s start using the future now.

    1. // bad
    2. const AirbnbStyleGuide = require('./AirbnbStyleGuide');
    3. module.exports = AirbnbStyleGuide.es6;
    4. // ok
    5. import AirbnbStyleGuide from './AirbnbStyleGuide';
    6. export default AirbnbStyleGuide.es6;
    7. // best
    8. import { es6 } from './AirbnbStyleGuide';
    9. export default es6;

  • 10.2 Do not use wildcard imports.

    Why? This makes sure you have a single default export.

    1. // bad
    2. import * as AirbnbStyleGuide from './AirbnbStyleGuide';
    3. // good
    4. import AirbnbStyleGuide from './AirbnbStyleGuide';

  • 10.3 And do not export directly from an import.

    Why? Although the one-liner is concise, having one clear way to import and one clear way to export makes things consistent.

    1. // bad
    2. // filename es6.js
    3. export { es6 as default } from './AirbnbStyleGuide';
    4. // good
    5. // filename es6.js
    6. import { es6 } from './AirbnbStyleGuide';
    7. export default es6;

  • 10.4 Only import from a path in one place.
    eslint: no-duplicate-imports

    Why? Having multiple lines that import from the same path can make code harder to maintain.

    1. // bad
    2. import foo from 'foo';
    3. // … some other imports … //
    4. import { named1, named2 } from 'foo';
    5. // good
    6. import foo, { named1, named2 } from 'foo';
    7. // good
    8. import foo, {
    9. named1,
    10. named2,
    11. } from 'foo';

  • 10.5 Do not export mutable bindings.
    eslint: import/no-mutable-exports

    Why? Mutation should be avoided in general, but in particular when exporting mutable bindings. While this technique may be needed for some special cases, in general, only constant references should be exported.

    1. // bad
    2. let foo = 3;
    3. export { foo };
    4. // good
    5. const foo = 3;
    6. export { foo };

  • 10.6 In modules with a single export, prefer default export over named export.
    eslint: import/prefer-default-export

    Why? To encourage more files that only ever export one thing, which is better for readability and maintainability.

    1. // bad
    2. export function foo() {}
    3. // good
    4. export default function foo() {}

  • 10.7 Put all imports above non-import statements.
    eslint: import/first

    Why? Since imports are hoisted, keeping them all at the top prevents surprising behavior.

    1. // bad
    2. import foo from 'foo';
    3. foo.init();
    4. import bar from 'bar';
    5. // good
    6. import foo from 'foo';
    7. import bar from 'bar';
    8. foo.init();

  • 10.8 Multiline imports should be indented just like multiline array and object literals.

    Why? The curly braces follow the same indentation rules as every other curly brace block in the style guide, as do the trailing commas.

    1. // bad
    2. import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
    3. // good
    4. import {
    5. longNameA,
    6. longNameB,
    7. longNameC,
    8. longNameD,
    9. longNameE,
    10. } from 'path';

  • 10.9 Disallow Webpack loader syntax in module import statements.
    eslint: import/no-webpack-loader-syntax

    Why? Since using Webpack syntax in the imports couples the code to a module bundler. Prefer using the loader syntax in webpack.config.js.

    1. // bad
    2. import fooSass from 'css!sass!foo.scss';
    3. import barCss from 'style!css!bar.css';
    4. // good
    5. import fooSass from 'foo.scss';
    6. import barCss from 'bar.css';