diff --git a/examples/basic/src/test.mdx b/examples/basic/src/test.mdx deleted file mode 100644 index 703bc58..0000000 --- a/examples/basic/src/test.mdx +++ /dev/null @@ -1,5 +0,0 @@ -import { doc } from 'docz' - -export const meta = doc('Test') - -Just a test diff --git a/packages/docz-core/package.json b/packages/docz-core/package.json index e5f1fa7..1ed7b92 100644 --- a/packages/docz-core/package.json +++ b/packages/docz-core/package.json @@ -25,6 +25,7 @@ "@mdx-js/mdx": "^0.8.1", "@mdx-js/mdxast": "^0.7.2", "@sindresorhus/slugify": "^0.3.0", + "@types/shelljs": "^0.7.9", "art-template": "^4.12.2", "babel-loader": "^8.0.0-beta.1", "babel-polyfill": "^7.0.0-beta.3", @@ -44,11 +45,11 @@ "koa-static": "^4.0.2", "load-cfg": "^0.0.1", "lodash.get": "^4.4.2", - "mkdirp": "^0.5.1", "prettier": "^1.12.0", "react-hot-loader": "4.1.2", "remark-parse": "^5.0.0", "resolve": "^1.7.1", + "shelljs": "^0.8.1", "thread-loader": "^1.1.5", "ulid": "^2.3.0", "unified": "^6.2.0", @@ -66,7 +67,6 @@ "@types/del": "^3.0.1", "@types/express": "^4.11.1", "@types/html-webpack-plugin": "^2.30.3", - "@types/mkdirp": "^0.5.2", "@types/node": "10.0.4", "@types/prettier": "^1.12.1", "@types/resolve": "^0.0.7", diff --git a/packages/docz-core/src/Entries.ts b/packages/docz-core/src/Entries.ts index e3d4d16..42f2551 100644 --- a/packages/docz-core/src/Entries.ts +++ b/packages/docz-core/src/Entries.ts @@ -1,7 +1,7 @@ import * as glob from 'fast-glob' import * as fs from 'fs' import * as path from 'path' -import * as mkdir from 'mkdirp' +import { test, mkdir } from 'shelljs' import { compile } from 'art-template' import stringify from 'json-stringify-pretty-compact' @@ -13,11 +13,7 @@ import { Entry } from './Entry' import { Config } from './commands/args' const mkd = (dir: string): void => { - try { - fs.lstatSync(dir) - } catch (err) { - mkdir.sync(dir) - } + !test('-d', dir) && mkdir('-p', dir) } const touch = (file: string, raw: string) => { @@ -38,21 +34,12 @@ const html = compiled('index.tpl.html') export type EntryMap = Record export class Entries { - public files: string[] public config: Config public entries: EntryMap constructor(config: Config) { - const { files: pattern } = config - - const ignoreGlob = '!node_modules' - const files: string[] = glob.sync( - Array.isArray(pattern) ? [...pattern, ignoreGlob] : [pattern, ignoreGlob] - ) - - this.files = files this.config = config - this.entries = this.getEntries(files) + this.entries = this.getEntries(config) } public write(): void { @@ -71,9 +58,26 @@ export class Entries { public update(file: string): void { const filepath = this.entryFilepath(file) - this.entries = { - ...this.entries, - [filepath]: new Entry(file, this.config.src), + if (Entry.check(file)) { + this.entries = { + ...this.entries, + [filepath]: new Entry(file, this.config.src), + } + } + } + + public clean(dir: string): void { + if (test('-d', dir)) { + this.entries = this.getEntries(this.config) + return + } + + const { paths } = this.config + const src = path.resolve(paths.root, this.config.src) + + for (const file of Object.keys(this.entries)) { + const filepath = path.join(src, file) + if (!test('-f', filepath)) this.remove(filepath) } } @@ -82,7 +86,14 @@ export class Entries { return path.relative(srcPath, file) } - private getEntries(files: string[]): EntryMap { + private getEntries(config: Config): EntryMap { + const { files: pattern } = config + + const ignoreGlob = '!node_modules' + const files: string[] = glob.sync( + Array.isArray(pattern) ? [...pattern, ignoreGlob] : [pattern, ignoreGlob] + ) + return files.filter(Entry.check).reduce((obj, file) => { const entry = new Entry(file, this.config.src) return { ...obj, [entry.filepath]: entry } diff --git a/packages/docz-core/src/Entry.ts b/packages/docz-core/src/Entry.ts index 1d6360d..0b979d7 100644 --- a/packages/docz-core/src/Entry.ts +++ b/packages/docz-core/src/Entry.ts @@ -52,21 +52,21 @@ export class Entry { return checkImport(file) && Boolean(getNameFromDoc(file)) } - public static parseName(file: string): string | null { - return getNameFromDoc(file) + public static slug(file: string): string | null { + const name = getNameFromDoc(file) + return name ? slugify(name) : null } public id: string - public slug: string public filepath: string + public slug: string | null constructor(file: string, src: string) { const srcPath = path.resolve(paths.root, src) const filepath = path.relative(srcPath, file) - const name = Entry.parseName(file) this.id = ulid() - this.slug = slugify(name) + this.slug = Entry.slug(file) this.filepath = filepath } } diff --git a/packages/docz-core/src/bundlers/webpack/devserver.ts b/packages/docz-core/src/bundlers/webpack/devserver.ts index 536d9e4..acb02a6 100644 --- a/packages/docz-core/src/bundlers/webpack/devserver.ts +++ b/packages/docz-core/src/bundlers/webpack/devserver.ts @@ -14,16 +14,18 @@ export const devServerConfig = ( const nonExistentDir = path.resolve(__dirname, 'non-existent') return { - content: [nonExistentDir], compiler, host, - dev: { logLevel: 'warn' }, + port, + content: [nonExistentDir], + dev: { + logLevel: args.debug ? 'debug' : 'warn', + }, hot: { logLevel: 'error', reload: false, }, logLevel: 'error', - port, add: (app: any) => { app.use( convert( diff --git a/packages/docz-core/src/commands/dev.ts b/packages/docz-core/src/commands/dev.ts index e52b90f..da7a0c0 100644 --- a/packages/docz-core/src/commands/dev.ts +++ b/packages/docz-core/src/commands/dev.ts @@ -3,7 +3,6 @@ import chokidar from 'chokidar' import del from 'del' import * as paths from '../config/paths' -import { Entry } from '../Entry' import { Entries } from '../Entries' import { webpack } from '../bundlers' import { Config } from './args' @@ -11,6 +10,41 @@ import { Config } from './args' process.env.BABEL_ENV = process.env.BABEL_ENV || 'development' process.env.NODE_ENV = process.env.NODE_ENV || 'development' +const handleUpdate = (entries: Entries) => (file: string) => { + entries.update(file) + entries.rewrite() +} + +const handleRemove = (entries: Entries) => (file: string) => { + entries.remove(file) + entries.rewrite() +} + +const handleRemoveDir = (entries: Entries) => ( + event: string, + path: string, + details: any +) => { + if (details.event === 'moved' && details.type === 'directory') { + entries.clean(details.path) + entries.rewrite() + } +} + +const writeEntriesAndWatch = (config: Config) => { + const entries = new Entries(config) + const watcher = chokidar.watch(config.files, { + ignored: /(^|[\/\\])\../, + }) + + watcher + .on('change', handleUpdate(entries)) + .on('unlink', handleRemove(entries)) + .on('raw', handleRemoveDir(entries)) + + entries.write() +} + const INITIAL_CONFIG = { paths, plugins: [], @@ -18,33 +52,6 @@ const INITIAL_CONFIG = { hastPlugins: [], } -const writeEntriesAndWatch = (config: Config) => { - const watcher = chokidar.watch(config.files, { - ignored: /(^|[\/\\])\../, - }) - - const entries = new Entries(config) - - const onUnlink = (file: string) => { - entries.remove(file) - entries.rewrite() - } - - const onChange = (file: string) => { - const name = Entry.parseName(file) - - if (name) { - entries.update(file) - entries.rewrite() - } - } - - watcher.on('unlink', onUnlink) - watcher.on('change', onChange) - - entries.write() -} - export const dev = async (args: Config) => { const config = load('docz', { ...args, ...INITIAL_CONFIG }) const bundler = webpack(config) diff --git a/tslint.json b/tslint.json index c95f4ac..e9a83e2 100644 --- a/tslint.json +++ b/tslint.json @@ -1,6 +1,7 @@ { "extends": ["tslint:latest", "tslint-config-prettier"], "rules": { + "curly": false, "interface-name": [true, "never-prefix"], "ordered-imports": false, "object-literal-sort-keys": false, diff --git a/yarn.lock b/yarn.lock index 680f705..a90665c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1418,12 +1418,6 @@ version "3.0.3" resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - dependencies: - "@types/node" "*" - "@types/node@*": version "10.0.0" resolved "https://registry.npmjs.org/@types/node/-/node-10.0.0.tgz#c40f8e07dce607d3ef25a626b93a6a7cdcf97881" @@ -1481,6 +1475,13 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/shelljs@^0.7.9": + version "0.7.9" + resolved "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.7.9.tgz#3abecb72d9cad9cd4b0e7cb86ed10a97d93ba602" + dependencies: + "@types/glob" "*" + "@types/node" "*" + "@types/tapable@*": version "1.0.2" resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd"