Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit 43fa7ab

Browse files
committed
fix(docz-core): config watch for directory operations
1 parent f75881e commit 43fa7ab

File tree

8 files changed

+82
-65
lines changed

8 files changed

+82
-65
lines changed

examples/basic/src/test.mdx

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/docz-core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@mdx-js/mdx": "^0.8.1",
2626
"@mdx-js/mdxast": "^0.7.2",
2727
"@sindresorhus/slugify": "^0.3.0",
28+
"@types/shelljs": "^0.7.9",
2829
"art-template": "^4.12.2",
2930
"babel-loader": "^8.0.0-beta.1",
3031
"babel-polyfill": "^7.0.0-beta.3",
@@ -44,11 +45,11 @@
4445
"koa-static": "^4.0.2",
4546
"load-cfg": "^0.0.1",
4647
"lodash.get": "^4.4.2",
47-
"mkdirp": "^0.5.1",
4848
"prettier": "^1.12.0",
4949
"react-hot-loader": "4.1.2",
5050
"remark-parse": "^5.0.0",
5151
"resolve": "^1.7.1",
52+
"shelljs": "^0.8.1",
5253
"thread-loader": "^1.1.5",
5354
"ulid": "^2.3.0",
5455
"unified": "^6.2.0",
@@ -66,7 +67,6 @@
6667
"@types/del": "^3.0.1",
6768
"@types/express": "^4.11.1",
6869
"@types/html-webpack-plugin": "^2.30.3",
69-
"@types/mkdirp": "^0.5.2",
7070
"@types/node": "10.0.4",
7171
"@types/prettier": "^1.12.1",
7272
"@types/resolve": "^0.0.7",

packages/docz-core/src/Entries.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as glob from 'fast-glob'
22
import * as fs from 'fs'
33
import * as path from 'path'
4-
import * as mkdir from 'mkdirp'
4+
import { test, mkdir } from 'shelljs'
55
import { compile } from 'art-template'
66
import stringify from 'json-stringify-pretty-compact'
77

@@ -13,11 +13,7 @@ import { Entry } from './Entry'
1313
import { Config } from './commands/args'
1414

1515
const mkd = (dir: string): void => {
16-
try {
17-
fs.lstatSync(dir)
18-
} catch (err) {
19-
mkdir.sync(dir)
20-
}
16+
!test('-d', dir) && mkdir('-p', dir)
2117
}
2218

2319
const touch = (file: string, raw: string) => {
@@ -38,21 +34,12 @@ const html = compiled('index.tpl.html')
3834
export type EntryMap = Record<string, Entry>
3935

4036
export class Entries {
41-
public files: string[]
4237
public config: Config
4338
public entries: EntryMap
4439

4540
constructor(config: Config) {
46-
const { files: pattern } = config
47-
48-
const ignoreGlob = '!node_modules'
49-
const files: string[] = glob.sync(
50-
Array.isArray(pattern) ? [...pattern, ignoreGlob] : [pattern, ignoreGlob]
51-
)
52-
53-
this.files = files
5441
this.config = config
55-
this.entries = this.getEntries(files)
42+
this.entries = this.getEntries(config)
5643
}
5744

5845
public write(): void {
@@ -71,9 +58,26 @@ export class Entries {
7158
public update(file: string): void {
7259
const filepath = this.entryFilepath(file)
7360

74-
this.entries = {
75-
...this.entries,
76-
[filepath]: new Entry(file, this.config.src),
61+
if (Entry.check(file)) {
62+
this.entries = {
63+
...this.entries,
64+
[filepath]: new Entry(file, this.config.src),
65+
}
66+
}
67+
}
68+
69+
public clean(dir: string): void {
70+
if (test('-d', dir)) {
71+
this.entries = this.getEntries(this.config)
72+
return
73+
}
74+
75+
const { paths } = this.config
76+
const src = path.resolve(paths.root, this.config.src)
77+
78+
for (const file of Object.keys(this.entries)) {
79+
const filepath = path.join(src, file)
80+
if (!test('-f', filepath)) this.remove(filepath)
7781
}
7882
}
7983

@@ -82,7 +86,14 @@ export class Entries {
8286
return path.relative(srcPath, file)
8387
}
8488

85-
private getEntries(files: string[]): EntryMap {
89+
private getEntries(config: Config): EntryMap {
90+
const { files: pattern } = config
91+
92+
const ignoreGlob = '!node_modules'
93+
const files: string[] = glob.sync(
94+
Array.isArray(pattern) ? [...pattern, ignoreGlob] : [pattern, ignoreGlob]
95+
)
96+
8697
return files.filter(Entry.check).reduce((obj, file) => {
8798
const entry = new Entry(file, this.config.src)
8899
return { ...obj, [entry.filepath]: entry }

packages/docz-core/src/Entry.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,21 @@ export class Entry {
5252
return checkImport(file) && Boolean(getNameFromDoc(file))
5353
}
5454

55-
public static parseName(file: string): string | null {
56-
return getNameFromDoc(file)
55+
public static slug(file: string): string | null {
56+
const name = getNameFromDoc(file)
57+
return name ? slugify(name) : null
5758
}
5859

5960
public id: string
60-
public slug: string
6161
public filepath: string
62+
public slug: string | null
6263

6364
constructor(file: string, src: string) {
6465
const srcPath = path.resolve(paths.root, src)
6566
const filepath = path.relative(srcPath, file)
66-
const name = Entry.parseName(file)
6767

6868
this.id = ulid()
69-
this.slug = slugify(name)
69+
this.slug = Entry.slug(file)
7070
this.filepath = filepath
7171
}
7272
}

packages/docz-core/src/bundlers/webpack/devserver.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ export const devServerConfig = (
1414
const nonExistentDir = path.resolve(__dirname, 'non-existent')
1515

1616
return {
17-
content: [nonExistentDir],
1817
compiler,
1918
host,
20-
dev: { logLevel: 'warn' },
19+
port,
20+
content: [nonExistentDir],
21+
dev: {
22+
logLevel: args.debug ? 'debug' : 'warn',
23+
},
2124
hot: {
2225
logLevel: 'error',
2326
reload: false,
2427
},
2528
logLevel: 'error',
26-
port,
2729
add: (app: any) => {
2830
app.use(
2931
convert(

packages/docz-core/src/commands/dev.ts

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,55 @@ import chokidar from 'chokidar'
33
import del from 'del'
44

55
import * as paths from '../config/paths'
6-
import { Entry } from '../Entry'
76
import { Entries } from '../Entries'
87
import { webpack } from '../bundlers'
98
import { Config } from './args'
109

1110
process.env.BABEL_ENV = process.env.BABEL_ENV || 'development'
1211
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
1312

14-
const INITIAL_CONFIG = {
15-
paths,
16-
plugins: [],
17-
mdPlugins: [],
18-
hastPlugins: [],
13+
const handleUpdate = (entries: Entries) => (file: string) => {
14+
entries.update(file)
15+
entries.rewrite()
1916
}
2017

21-
const writeEntriesAndWatch = (config: Config) => {
22-
const watcher = chokidar.watch(config.files, {
23-
ignored: /(^|[\/\\])\../,
24-
})
25-
26-
const entries = new Entries(config)
18+
const handleRemove = (entries: Entries) => (file: string) => {
19+
entries.remove(file)
20+
entries.rewrite()
21+
}
2722

28-
const onUnlink = (file: string) => {
29-
entries.remove(file)
23+
const handleRemoveDir = (entries: Entries) => (
24+
event: string,
25+
path: string,
26+
details: any
27+
) => {
28+
if (details.event === 'moved' && details.type === 'directory') {
29+
entries.clean(details.path)
3030
entries.rewrite()
3131
}
32+
}
3233

33-
const onChange = (file: string) => {
34-
const name = Entry.parseName(file)
35-
36-
if (name) {
37-
entries.update(file)
38-
entries.rewrite()
39-
}
40-
}
34+
const writeEntriesAndWatch = (config: Config) => {
35+
const entries = new Entries(config)
36+
const watcher = chokidar.watch(config.files, {
37+
ignored: /(^|[\/\\])\../,
38+
})
4139

42-
watcher.on('unlink', onUnlink)
43-
watcher.on('change', onChange)
40+
watcher
41+
.on('change', handleUpdate(entries))
42+
.on('unlink', handleRemove(entries))
43+
.on('raw', handleRemoveDir(entries))
4444

4545
entries.write()
4646
}
4747

48+
const INITIAL_CONFIG = {
49+
paths,
50+
plugins: [],
51+
mdPlugins: [],
52+
hastPlugins: [],
53+
}
54+
4855
export const dev = async (args: Config) => {
4956
const config = load('docz', { ...args, ...INITIAL_CONFIG })
5057
const bundler = webpack(config)

tslint.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"extends": ["tslint:latest", "tslint-config-prettier"],
33
"rules": {
4+
"curly": false,
45
"interface-name": [true, "never-prefix"],
56
"ordered-imports": false,
67
"object-literal-sort-keys": false,

yarn.lock

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,12 +1418,6 @@
14181418
version "3.0.3"
14191419
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
14201420

1421-
"@types/mkdirp@^0.5.2":
1422-
version "0.5.2"
1423-
resolved "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f"
1424-
dependencies:
1425-
"@types/node" "*"
1426-
14271421
"@types/node@*":
14281422
version "10.0.0"
14291423
resolved "https://registry.npmjs.org/@types/node/-/node-10.0.0.tgz#c40f8e07dce607d3ef25a626b93a6a7cdcf97881"
@@ -1481,6 +1475,13 @@
14811475
"@types/express-serve-static-core" "*"
14821476
"@types/mime" "*"
14831477

1478+
"@types/shelljs@^0.7.9":
1479+
version "0.7.9"
1480+
resolved "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.7.9.tgz#3abecb72d9cad9cd4b0e7cb86ed10a97d93ba602"
1481+
dependencies:
1482+
"@types/glob" "*"
1483+
"@types/node" "*"
1484+
14841485
"@types/tapable@*":
14851486
version "1.0.2"
14861487
resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd"

0 commit comments

Comments
 (0)