GithubHelp home page GithubHelp logo

gajus / create-index Goto Github PK

View Code? Open in Web Editor NEW
279.0 5.0 86.0 75 KB

Creates ES6 ./index.js file in target directories that imports and exports all sibling files and directories.

License: Other

JavaScript 100.00%
es-modules

create-index's Introduction

create-index

NPM version Travis build status js-canonical-style

create-index program creates (and maintains) ES6 ./index.js file in target directories that imports and exports sibling files and directories.

Example

> tree ./
./
├── bar.js
└── foo.js

0 directories, 2 files

> create-index ./
[13:17:34] Target directories [ './' ]
[13:17:34] Update index: false
[13:17:34] ./index.js [created index]
[13:17:34] Done

> tree
.
├── bar.js
├── foo.js
└── index.js

0 directories, 3 files

This created index.js with:

// @create-index

export { default as bar } from './bar.js';
export { default as foo } from './foo.js';

Lets create a new file and re-run create-index:

> touch baz.js
> tree ./
./
├── bar.js
├── baz.js
├── foo.js
└── index.js

0 directories, 4 files

> create-index ./
[13:21:55] Target directories [ './' ]
[13:21:55] Update index: false
[13:21:55] ./index.js [updated index]
[13:21:55] Done

This have updated index.js file:

// @create-index

export { default as bar } from './bar.js';
export { default as baz } from './baz.js';
export { default as foo } from './foo.js';

Usage

Using CLI Program

npm install create-index

create-index --help

Options:
  --recursive, -r          Create/update index files recursively. Halts on any
                           unsafe "index.js" files.   [boolean] [default: false]
  --ignoreUnsafe, -i       Ignores unsafe "index.js" files instead of halting.
                                                      [boolean] [default: false]
  --ignoreDirectories, -d  Ignores importing directories into the index file,
                           even if they have a safe "index.js".
                                                      [boolean] [default: false]
  --update, -u             Updates only previously created index files
                           (recursively).             [boolean] [default: false]
  --banner                 Add a custom banner at the top of the index file
                                                                        [string]
  --extensions, -x         Allows some extensions to be parsed as valid source.
                           First extension will always be preferred to homonyms
                           with another allowed extension.
                                                       [array] [default: ["js"]]
  --outputFile, -o         Output file            [string] [default: "index.js"]                                                      [array] [default: ["js"]]

Examples:
  create-index ./src ./src/utilities      Creates or updates an existing
                                          create-index index file in the target
                                          (./src, ./src/utilities) directories.
  create-index --update ./src ./tests     Finds all create-index index files in
                                          the target directories and descending
                                          directories. Updates found index
                                          files.
  create-index ./src --extensions js jsx  Creates or updates an existing
                                          create-index index file in the target
                                          (./src) directory for both .js and
                                          .jsx extensions.

Using create-index Programmatically

import {
    writeIndex
} from 'create-index';

/**
 * @type {Function}
 * @param {Array<string>} directoryPaths
 * @throws {Error} Directory "..." does not exist.
 * @throws {Error} "..." is not a directory.
 * @throws {Error} "..." unsafe index.
 * @returns {boolean}
 */
writeIndex;

Note that the writeIndex function is synchronous.

import {
    findIndexFiles
} from 'create-index';

/**
 * @type {Function}
 * @param {string} directoryPath
 * @returns {Array<string>} List of directory paths that have create-index index file.
 */
findIndexFiles;

Gulp

Since Gulp can ran arbitrary JavaScript code, there is no need for a separate plugin. See Using create-index Programmatically.

import {
    writeIndex
} from 'create-index';

gulp.task('create-index', () => {
    writeIndex(['./target_directory']);
});

Note that the writeIndex function is synchronous.

Implementation

create-index program will look into the target directory.

If there is no ./index.js, it will create a new file, e.g.

// @create-index

Created index file must start with // @create-index\n\n. This is used to make sure that create-index does not accidentally overwrite your local files.

If there are sibling files, index file will import them and export, e.g.

children-directories-and-files git:(master) ✗ ls -lah
total 0
drwxr-xr-x   5 gajus  staff   170B  6 Jan 15:39 .
drwxr-xr-x  10 gajus  staff   340B  6 Jan 15:53 ..
drwxr-xr-x   2 gajus  staff    68B  6 Jan 15:29 bar
drwxr-xr-x   2 gajus  staff    68B  6 Jan 15:29 foo
-rw-r--r--   1 gajus  staff     0B  6 Jan 15:29 foo.js

Given the above directory contents, ./index.js will be:

// @create-index

import { default as bar } from './bar';
import { default as foo } from './foo.js';

export {
    bar,
    foo
};

When file has the same name as a sibling directory, file import takes precedence.

Directories that do not have ./index.js in themselves will be excluded.

When run again, create-index will update existing ./index.js if it starts with // @create-index\n\n.

If create-index is executed against a directory that contains ./index.js, which does not start with // @create-index\n\n, an error will be thrown.

Ignore files on --update

create-index can ignore files in a directory if ./index.js contains special object with defined ignore property which takes an array of regular expressions defined as strings, e.g.

> cat index.js
// @create-index {"ignore": ["/baz.js$/"]}
> tree ./
./
├── bar.js
├── baz.js
├── foo.js
└── index.js

0 directories, 4 files

Given the above directory contents, after running create-index with --update flag, ./index.js will be:

// @create-index {"ignore": ["/baz.js$/"]}

import { default as bar } from './bar.js';
import { default as foo } from './foo.js';

export {
    bar,
    foo
};

Generate index.tsx for TypeScript

create-index src/components/Icons --extensions tsx --outputFile index.tsx

create-index's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

create-index's Issues

Functions exported as default not picked up

First off, thanks for super useful cli. Have been needing this myself for so long I was about to make it, then bumped into this!

The issue I am having is that exporting a function as default does not appear in created index.js. However async functions and object exports work as expected:

export default { someThing, someOtherThing } // WORKS => export { default as things }
export default async function someFunc() {} // WORKS => export { default as someFunc }
export default function someOtherFunc() {} // DOES NOT WORK => (no output)

Add ability to add banner to the generated file

Example:

create-index --update --banner '/* eslint-disable */\n\n' ./src/queries ./src/utilities ./src/utilities/database

This would add /* eslint-disable */ comment above // @create-index.

This is a solution for #5.

Generated code style

Currently, create-index files are identified by the string:

'create index';

This string is not linter friendly since it is not an assignment nor call. As far as I know, there is no way to define new directives like 'use strict'.

What about using a comment like eslint, flow type, and others:

/* create-index */

or

/* @create-index */

The latter would give a little more certainty when parsing comments for the flag. A flag like this in general would also allow parsing options following the flag as with eslint for instance.

Thoughts?

How to create index of named exports?

I use webpack and babel as my es6 transpiler in my dev.create-index act correct when all siblings are files. It breaks when export subdir.

For example

├── king.js
└── queen
    ├── bar.js
    └── foo.js

create-index can correctly build index.js in dir queen

export bar from './bar.js';
export foo from './foo.js';

but in the root dir ,index.js

export queen from './queen'

just export undefined.

I found that

export * as queen from './queen';

worked.

So I forked your code and change the dir export style and committed.

https://github.com/deadivan/create-index

Please tell me if I doing something wrong.

Add option to uppercase first char of export

I'd like to be able to use this for mongoose models. Typically the models are imported with their first char capitalised such as import {Comment, Post, User} from 'models'; from what I can tell the vars are exported using the filenames and I'd rather not have to rename my files Post.js, etc. as it will clash with my linting rules for file names.

Include folder name in banner

Is there any way to add current folder name in banner parameters? something like $folder translates to current folder index is created would be really helpful. This way we can add something similar to
/** @namespace $folder */ in banner for jsDoc.

--update instead of --update-index

While create-index is only about creating indexes --update-index could be shortened to --update.

Perhaps an alias -u could also be added.

Importing created subdirectory index files

Hello! Thanks so much for the great work on create-index! I apologize if this has been brought up before, after some time of searching the issues and pull requests I could not find mention of it.

I have a library project with some deeper source folders and much to my delight create-index does indeed create index.js files exactly how I was looking for, short of one thing. When creating a parent folder's index.js and using the recurse into subfolders option the parent folder's index.js will not import the child folder's. To further call the inconsistency out, subsequent runs of create-index will properly import the child folder's now created index.js.

I'd be happy to submit a PR if this seems like a feature that should be included, especially if it's something someone unfamiliar with the source can easily jump in and do, say if it's a matter of swapping the order of generation.

Thank you for your time!

Make target file extension configurable

I use .jsx in my project (for ReactJS) so this currently will not work on my components folder.

I could submit a pull request but wondered if you want to support user-configured extensions.

Change the index file format to use "export ... from"

Current format is:

'create index';

import createIndexCode from './createIndexCode.js';
import readDirectory from './readDirectory.js';
import validateTargetDirectory from './validateTargetDirectory.js';
import writeIndex from './writeIndex.js';

export {
    createIndexCode,
    readDirectory,
    validateTargetDirectory,
    writeIndex
};

It can be made shorter using export ... from syntax, e.g.

'create index';

export createIndexCode from './createIndexCode.js';
export readDirectory from './readDirectory.js';
export sortByDepth from './sortByDepth.js';
export validateTargetDirectory from './validateTargetDirectory.js';
export writeIndex from './writeIndex.js';

Recursive create

Thanks for this package, was about to make the same thing.

Currently --update-index recursively searches for index files to update. However, when creating indexes there is no recursive option. It looks like it was considered in #2 as a --deep option. I cannot find it in the source or docs though.

I'm looking for a single command to create and update index files recursively. This way I can create-index ./src --deep or more preferred create-index ./src/**/ and always count on all directories having an index.

Are you open to PRs for accepting globs or a --deep option on create-index ./src?

Support creating index with default export

Currently, this plugin only supports creating an index with named exports. I need an index file with a default-exported object.

Example:

import foo from './foo.js';
import bar from './bar.js';
import _3_x_recommended from './3-x-recommended.js'; // note unsafe variable name needs to be tweaked

export default { 
  foo, 
  bar, 
  '3-x-recommended': _3_x_recommended
};

I see this functionality is in a forked version of this tool: https://github.com/tjjfvi/create-index-better#modes

// @create-index {"mode":"default{}"}

import foo from './foo.js';
import bar from './bar.js';
export default { foo, bar };

Has it been considered for the original create-index? @tjjfvi would you consider upstreaming this functionality (and presumably any other improvements from the fork)?

Does not work with filename using dash.

Hi,

I tried your project on a directory from our project and it seems that all files that have a default export but a dash in their filename are ignored. All files without dash are correctly added to the index.js file.

Thanks.

Support exporting directly from subdirectories

I have a directory structure like so

components
├── AccordionBox
│   ├── AccordionBox.js
│   └── AccordionTab.js
├── AlertBox
│   └── AlertBox.js
└── Dropdown
    └── Dropdown.js

It would be great if could just run create-index and add an index.js to components that looked like

'create-index';

export AccordionBox from './AccordionBox/AccordionBox';
export AccordionTab from './AccordionBox/AccordionTab';
export AlertBox from './AlertBox/AlertBox';
export Dropdown from './Dropdown/Dropdown';

Scan all descending directories for index.js with 'create index';

Instead of requiring user to pass all directories, have an option that enables deep scanning of the directory tree of files containing 'create index'; directive and automatically update those indexes, e.g.

create-index --deep ./src

The latter would be equivalent to ./src/**/index.js being searching for files with 'create index';, updating their index and ignoring other directories.

Log files that are excluded

Log files that are excluded either because of unsupported file name or extension. Will prevent confusion in cases similar to #8.

Feature request: Excluding specific files

Hey,
It's just proposal of a new feature that could be very handy.

I would like to exclude some files which are added to generated index.js files, why?
I have a folder /icons witch contains all my icons (each icon is a react component).
In this folder I have also stories.js file (I'm using react-storybook). Now stories.js is always added to the end of the file and my storybook is broken.

I think that it could work also for other people in other more advanced cases.
I could implement it and add PR but before I would like to talk about proposed solutions.

1. Using a "special comment" in generated index.js file

// @create-index
// @create-index-ignore: [/stories.(js)$/]

export Abc from './Abc.js';
export Zxc from './Zxc.js';
export Qwe from './Qwe.js';

.2 Using a "special configuration file" .create-index inside a specific directory

.create-index

{
  ignore: [
    /stories.(js)$/
  ]
}

Files with hyphen are ignored.

A file named fizz-buzz.js would be ignored by npx create-index ./

If they are not supported, some kind of output would be nice. Maybe a comment in the created index file for why something was skipped?

Ideally the hyphenated name would be camel-cased.
e.g. export { default as fizzBuzz} from 'fizz-buzz'

Ignore unsafe index

--silent perhaps? or --ignore-unsafe?

An option to ignore unsafe index files instead of halting, and continue creating other indexes (indices?).

Would be helpful (probably required?) in recursive create (#4)

Dashes in filename

I seem to be having an issue with dashes in filenames. The index file gets created, but is empty.

thanks

Conflicts between files and folders with same name

I'm using React 18 and Typescript 4.7.4

I have a file named Table.tsx and a directory named table in the same directory. The generated index.js will cause an error differs from already included file name ... only in casing

For example:

├── src
    ├─ components
       ├─ Table.tsx
       ├─ table
          ├─ TableSidebar.tsx
          ├─ TableProps.ts

This will generate an index.js that looks like:

export { default as Table } from './Table.tsx';
export { default as table } from './table';

This will produce the following error:
File name 'C:/dev/src/components/Table.tsx' differs from already included file name 'C:/dev/src/components/table' only in casing.

This is due to the fact that the loader automatically "assumes" an extension if a file by that name exists. Adding index.js to the directory import fixes this issue.

export { default as Table } from './Table.tsx';
export { default as table } from './table/index.js';

In fact, a better option would be to use wildcards and to omit extension all together like this:

export * from './Table';
export * from './table/';

Can this please be added?

Requires 2 passes to include the index created in the 1st pass

If you have a directory structure like this:

foo
   bar
      baz.js

and you create index recursively using the new --recursive flag it first creates foo/bar/index.js with baz export, but when it creates foo/index.js it doesn't include the bar export that was just created. If you run the command again only then it creates/updates foo/index.js with the bar export.

I'm guessing this is because on the first pass when it walks the directory tree foo/bar/index.js doesn't exist yet.

It should include the indexes it itself will be creating in the directory tree.

Tests don't work?

> [email protected] test /Users/kud/Projects/_kud/create-index
> npm run build && npm run lint && cross-env NODE_ENV=development mocha --compilers js:babel-register


> [email protected] build /Users/kud/Projects/_kud/create-index
> cross-env NODE_ENV=production babel --source-maps --copy-files ./src --out-dir ./dist

src/bin/create-index.js -> dist/bin/create-index.js
src/index.js -> dist/index.js
src/utilities/constants.js -> dist/utilities/constants.js
src/utilities/createIndexCode.js -> dist/utilities/createIndexCode.js
src/utilities/findIndexFiles.js -> dist/utilities/findIndexFiles.js
src/utilities/hasIndex.js -> dist/utilities/hasIndex.js
src/utilities/index.js -> dist/utilities/index.js
src/utilities/log.js -> dist/utilities/log.js
src/utilities/readDirectory.js -> dist/utilities/readDirectory.js
src/utilities/readIndexConfig.js -> dist/utilities/readIndexConfig.js
src/utilities/sortByDepth.js -> dist/utilities/sortByDepth.js
src/utilities/validateTargetDirectory.js -> dist/utilities/validateTargetDirectory.js
src/utilities/writeIndex.js -> dist/utilities/writeIndex.js
src/utilities/writeIndexCli.js -> dist/utilities/writeIndexCli.js

> [email protected] lint /Users/kud/Projects/_kud/create-index
> cross-env NODE_ENV=development eslint ./src ./tests

canonical:
	Configuration for rule "import/first" is invalid:
	Value "[object Object]" is the wrong type.

Referenced from: /Users/kud/Projects/_kud/create-index/.eslintrc
Error: canonical:
	Configuration for rule "import/first" is invalid:
	Value "[object Object]" is the wrong type.

Referenced from: /Users/kud/Projects/_kud/create-index/.eslintrc
    at validateRuleOptions (/Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-validator.js:109:15)
    at /Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-validator.js:156:13
    at Array.forEach (<anonymous>)
    at Object.validate (/Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-validator.js:155:35)
    at load (/Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-file.js:559:19)
    at /Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-file.js:424:36
    at Array.reduceRight (<anonymous>)
    at applyExtends (/Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-file.js:408:28)
    at Object.load (/Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config/config-file.js:566:22)
    at loadConfig (/Users/kud/Projects/_kud/create-index/node_modules/eslint/lib/config.js:63:33)
(node:32294) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:32294) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'dirs' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'pushd' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'popd' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'echo' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'tempdir' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'pwd' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'exec' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'ls' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'find' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'grep' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'head' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'ln' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'mkdir' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'rm' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'mv' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'sed' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'set' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'sort' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'tail' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'test' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'to' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'toEnd' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'touch' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'uniq' of module exports inside circular dependency
(node:32294) Warning: Accessing non-existent property 'which' of module exports inside circular dependency
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] lint: `cross-env NODE_ENV=development eslint ./src ./tests`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kud/.npm/_logs/2020-05-12T11_34_15_533Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test: `npm run build && npm run lint && cross-env NODE_ENV=development mocha --compilers js:babel-register`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kud/.npm/_logs/2020-05-12T11_34_15_577Z-debug.log

Wrong casing in generated index.js

Several of the imports in my generated index.js file are the wrong case, they are lowercase instead of pascal case as it is on the filesystem.

ES2015 export syntax issue

Why do you use this pattern:

export Status from './Status.js'

instead of

export { default as Status } from './Status.js';

To my comprehension, the first syntax is not supported by native ES2015 and requires you to enable plugins such as this one: https://babeljs.io/docs/plugins/syntax-export-extensions/

I'm pretty lost in Babel related subjects, and i'm unable to use your tool because the extract is not valid. I am wrong ?

[bug] can't read file or folder with "-"?

Hello,

I wanted to create an index of some files or folders with "-" and I saw that an empty index with just the banner was created.

So I tried to rename my folders or files and now it works.

image

As you can see, only the one without "-" worked.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.