Skip to content

Commit

Permalink
add namespace feature
Browse files Browse the repository at this point in the history
  • Loading branch information
sw-yx committed Feb 17, 2019
1 parent d9fc9a8 commit 7633d15
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 22 deletions.
75 changes: 73 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,85 @@ It ignores files that you would normally want to ignore based on `.` in the file
- two or more dots e.g. `foo.stories.js` or `bar.spec.ts`
- starting with a dog e.g. `.somedotfile`

## `--ext {js, jsx, ts, tsx}`: Extensions
## Option: `--ext {js, jsx, ts, tsx}`

By default barrelbot assumes you want a `.tsx` extension. you can configure this with a `--extension` or `--ext` flag:
By default barrelbot assumes you want to use and output a `.tsx` extension. you can configure this with a `--extension` or `--ext` flag:

```
barrelbot watch src --extension js
```

## Option: `--namespace {none, all, defaultOnly}`

By default barrelbot assumes you export everything without a namespace, so it generates exports like:

```js
// index.js
export * from './foo';
```

This is (subjectively) ideal so as not to clutter the autocomplete space for IDEs. however, many people understandably have different styles, so you can configure this with a `--namespace` or `--n` flag:

`all`:

````js
// barrelbot watch myFolder --namespace all
```js
// index.js
import * as foo from './foo'
export {foo}
````
`defaultOnly`:
````js
// barrelbot watch myFolder --namespace defaultOnly
```js
// index.js
export {default as foo} from './foo'
````

## Visualizing what it does

Given a file structure like

```
- someFolder
- myWatchedFolder
- components
- Header
- Logo.tsx
- Title.tsx
- Logo.test.tsx
- Main.tsx
- Button.tsx
- Button.spec.ts
- App.tsx
- .somedotfile
```

When you run `barrelbot watch myWatchedFolder`, it results in:

```
- someFolder
- myWatchedFolder
- components
- Header
- Logo.tsx
- Title.tsx
- Logo.test.tsx
- index.tsx
- Main.tsx
- Button.tsx
- Button.spec.ts
- index.tsx
- App.tsx
- .somedotfile
- index.tsx
```

while ignoring the `*.test.tsx`, `*.spec.ts`, and `.somedotfile`.

## Tip!

Before running barrelbot, I advise committing your project to git first.
Expand Down
34 changes: 29 additions & 5 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import chokidar from 'chokidar';
import { checkDir } from './checks/checkDir';
import { writeIndex } from './writes/writeIndex';
import { isIndexFile } from './checks/checkIndexFile';
import { INDEXEXTENSIONS, FILETYPE } from './types';
import { INDEXEXTENSIONS, FILETYPE, NAMESPACETYPE } from './types';

const builder = (yargs: Yargs.Argv<{}>) => {
return yargs
Expand All @@ -18,7 +18,19 @@ const builder = (yargs: Yargs.Argv<{}>) => {
alias: 'ext',
describe: 'the extension of the barrel file, default tsx',
default: 'tsx'
})
.option('namespace', {
alias: 'n',
describe:
'when writing barrel, place all of each file in its own namespace, or only default exports, or no namespace (default)',
choices: ['none', 'all', 'defaultOnly'],
default: 'none'
});
// (, {
// alias: 'n',
// describe: `whether to namespace exports e.g. export { default as Input } from './input', default no`,
// default: false
// });
};
type HType = {
[argName: string]: unknown;
Expand All @@ -31,7 +43,14 @@ const handler = (/* argv: HType */) => {
async function run() {
const temp: HType = Yargs
// list of
.command('watch [folder]', 'have a watcher', builder, handler).argv;
.command(
'watch [folder]',
'start watching a folder and building barrels',
builder,
handler
)
.demandCommand()
.help().argv;
console.log({ temp });
// { _: [ 'watch' ],
// folder: 'testfolder',
Expand All @@ -40,6 +59,7 @@ async function run() {
if (!fs.existsSync(srcfolder)) {
return console.error(`path '${srcfolder}' does not exist, terminating...`);
}
const NAMESPACE = temp.namespace as NAMESPACETYPE;
const EXTENSION = temp.extension as FILETYPE;
if (!INDEXEXTENSIONS.includes(EXTENSION)) {
console.error(
Expand All @@ -48,6 +68,10 @@ async function run() {
);
return 'early termination';
}
const configs = {
NAMESPACE,
EXTENSION
};
// Something to use when events are received.
const log = console.log.bind(console);
let isLoading = true;
Expand All @@ -67,7 +91,7 @@ async function run() {
} else {
// rerun writeIndex
const dirname = path.dirname(_path);
writeIndex(dirname, EXTENSION);
writeIndex(dirname, configs);
}
}
})
Expand All @@ -88,7 +112,7 @@ async function run() {
EXTENSION
);
if (allFilesExceptIndex.length) {
writeIndex(dirname, EXTENSION);
writeIndex(dirname, configs);
} else {
// there is no longer any linkable file, lets delete index file as well if exists
if (hasIndexFile) {
Expand Down Expand Up @@ -126,7 +150,7 @@ async function run() {
`Scanned and validated ${srcfolder}. Checking and writing barrels...`
);
isLoading = false;
await Promise.all(watchedDirs.map(dir => writeIndex(dir, EXTENSION)));
await Promise.all(watchedDirs.map(dir => writeIndex(dir, configs)));
log(`Watching for changes...`);
});
// // unused
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export const COMMENTSTRING =
export type FILETYPE = 'js' | 'jsx' | 'ts' | 'tsx';
export const INDEXEXTENSIONS = ['js', 'ts', 'jsx', 'tsx'];
export const INDEXFILES = INDEXEXTENSIONS.map(x => 'index.' + x);
export type NAMESPACETYPE = 'none' | 'all' | 'defaultOnly';
59 changes: 44 additions & 15 deletions src/writes/writeIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,61 @@ import util from 'util';
const fs_writeFile = util.promisify(fs.writeFile);
import path from 'path';
import { checkDir } from '../checks/checkDir';
import { FILETYPE, COMMENTSTRING } from '../types';
import { FILETYPE, COMMENTSTRING, NAMESPACETYPE } from '../types';

type CONFIG = {
NAMESPACE: NAMESPACETYPE;
EXTENSION: FILETYPE;
};
/** return promise of a writing job */
export function writeIndex(pathToDir: string, extension: FILETYPE) {
const { indexFilePath, allFilesExceptIndex } = checkDir(pathToDir, extension);
export function writeIndex(pathToDir: string, config: CONFIG) {
const { indexFilePath, allFilesExceptIndex } = checkDir(
pathToDir,
config.EXTENSION
);
let finalString: string[] = [
COMMENTSTRING,
'',
'// for more info: https://github.com/sw-yx/barrelbot'
];
allFilesExceptIndex.forEach(filePath => {
finalString.push(createExportLine(filePath, extension));
const newLine = createExportLine(filePath, config);
if (newLine) finalString.push(newLine);
});

// console.log({ finalString });
// write
return fs_writeFile(
// path.join(pathToDir, indexFilePath)
indexFilePath,
finalString.join('\n')
// options
);
// return 'hi';
return fs_writeFile(indexFilePath, finalString.join('\n'));
}

function createExportLine(filePath: string, extension: FILETYPE) {
const basename = path.basename(filePath, '.' + extension);
return `export * from './${basename}'`;
function createExportLine(filePath: string, config: CONFIG) {
const _basename = path.basename(filePath);
let basename: string,
basenameArr = _basename.split('.');
if (basenameArr.length > 2) {
throw new Error(
`unexpected number of dots in filename ${filePath}, you shouldnt see this error`
);
}
basename = basenameArr[0];
const isMatchingTS = config.EXTENSION === 'ts' && basenameArr[1] === 'ts';
const isMatchingTSX =
config.EXTENSION === 'tsx' && ['ts', 'tsx'].includes(basenameArr[1]);
const isMatchingJS =
['js', 'jsx'].includes(basenameArr[1]) &&
['js', 'jsx'].includes(config.EXTENSION);
if (!isMatchingTS && !isMatchingTSX && !isMatchingJS) {
// not a filename we should care about
// throw new Error(
// `unrecognized extension, you shouldnt see this error, pls file a bug with ${filePath}`
// );
return null;
}
if (config.NAMESPACE == 'none') {
return `export * from './${basename}'`;
} else if (config.NAMESPACE == 'all') {
return `import * as ${basename} from './${basename}'\nexport {${basename}}`;
} else {
// (config.NAMESPACE == 'defaultOnly')
return `export {default as ${basename}} from './${basename}'`;
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 7633d15

Please sign in to comment.