mirror of
https://github.com/zhigang1992/docz.git
synced 2026-03-25 17:55:19 +08:00
chore: can resolve aliases, avoid cyclic imports
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -33,3 +33,4 @@ dist
|
||||
.cache
|
||||
.docz
|
||||
.idea
|
||||
.vscode
|
||||
4
packages/babel-plugin-docz/jest.config.js
Normal file
4
packages/babel-plugin-docz/jest.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
@@ -20,20 +20,24 @@
|
||||
"fix": "run-s fix:*",
|
||||
"fix:prettier": "prettier \"src/**/*.{ts,tsx}\" --write",
|
||||
"fix:tslint": "tslint --fix --project .",
|
||||
"tslint": "tslint --project ."
|
||||
"tslint": "tslint --project .",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/cli": "^7.1.2",
|
||||
"@babel/core": "^7.1.0",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"@babel/template": "^7.1.2",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-generator": "^6.26.1",
|
||||
"babel-literal-to-ast": "^2.0.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"jsdoc": "^3.5.5"
|
||||
"jsdoc": "^3.5.5",
|
||||
"ts-jest": "^23.10.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-jest": "^23.6.0",
|
||||
"jest": "^23.6.0"
|
||||
"jest": "^23.6.0",
|
||||
"@types/babel__template": "^7.0.0",
|
||||
"@types/jest": "^23.3.2",
|
||||
"@types/mocha": "^5.2.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import template from 'babel-template'
|
||||
import template from '@babel/template'
|
||||
|
||||
const buildMetaInsertion = template(`
|
||||
FN_ID.__docz = {
|
||||
name: FN_NAME,
|
||||
ID.__docz = {
|
||||
name: NAME,
|
||||
filename: FILENAME
|
||||
};
|
||||
`)
|
||||
|
||||
const insertMeta = (t: any) => (path: any, state: any): any => {
|
||||
const filename = state.file.opts.filename
|
||||
const name = path.node.id.name
|
||||
const newNode = buildMetaInsertion({
|
||||
ID: t.identifier(name),
|
||||
NAME: t.stringLiteral(name),
|
||||
FILENAME: t.stringLiteral(filename),
|
||||
})
|
||||
|
||||
path.insertAfter(newNode)
|
||||
}
|
||||
|
||||
export default function({ types: t }: any): any {
|
||||
return {
|
||||
visitor: {
|
||||
FunctionDeclaration(path: any, state: any): any {
|
||||
const filename = state.file.opts.filename
|
||||
const fnName = path.node.id.name
|
||||
const newNode = buildMetaInsertion({
|
||||
FN_ID: t.identifier(fnName),
|
||||
FN_NAME: t.stringLiteral(fnName),
|
||||
FILENAME: t.stringLiteral(filename),
|
||||
})
|
||||
|
||||
path.insertAfter(newNode)
|
||||
},
|
||||
FunctionDeclaration: insertMeta(t),
|
||||
ClassDeclaration: insertMeta(t),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`works 1`] = `
|
||||
"\\"use strict\\";
|
||||
|
||||
/**
|
||||
* Some description
|
||||
*/
|
||||
function get(object, path) {
|
||||
return object[path];
|
||||
}
|
||||
|
||||
get.__docz = {
|
||||
jsdoc: {
|
||||
\\"comment\\": \\"/**\\\\n * Some description\\\\n */\\",
|
||||
\\"meta\\": {
|
||||
\\"range\\": [28, 81],
|
||||
\\"filename\\": \\"example.js\\",
|
||||
\\"lineno\\": 4,
|
||||
\\"columnno\\": 0,
|
||||
\\"path\\": \\"/Users/marcelopiva/workspace/babel-plugin-docz/tests/fixtures\\",
|
||||
\\"code\\": {
|
||||
\\"id\\": \\"astnode100000002\\",
|
||||
\\"name\\": \\"get\\",
|
||||
\\"type\\": \\"FunctionDeclaration\\",
|
||||
\\"paramnames\\": [\\"object\\", \\"path\\"]
|
||||
}
|
||||
},
|
||||
\\"description\\": \\"Some description\\",
|
||||
\\"name\\": \\"get\\",
|
||||
\\"longname\\": \\"get\\",
|
||||
\\"kind\\": \\"function\\",
|
||||
\\"scope\\": \\"global\\",
|
||||
\\"params\\": []
|
||||
}
|
||||
};"
|
||||
`;
|
||||
@@ -0,0 +1,36 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`works 1`] = `
|
||||
"\\"use strict\\";
|
||||
|
||||
/**
|
||||
* Some description
|
||||
*/
|
||||
function get(object, path) {
|
||||
return object[path];
|
||||
}
|
||||
/**
|
||||
* Some description
|
||||
*/
|
||||
|
||||
|
||||
get.__docz = {
|
||||
name: \\"get\\",
|
||||
filename: \\"/Users/marcelopiva/workspace/docz/packages/babel-plugin-docz/tests/fixtures/example.js\\"
|
||||
};
|
||||
|
||||
class Abc {
|
||||
/**
|
||||
* Some description
|
||||
*/
|
||||
method() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Abc.__docz = {
|
||||
name: \\"Abc\\",
|
||||
filename: \\"/Users/marcelopiva/workspace/docz/packages/babel-plugin-docz/tests/fixtures/example.js\\"
|
||||
};"
|
||||
`;
|
||||
@@ -2,5 +2,17 @@
|
||||
* Some description
|
||||
*/
|
||||
function get(object, path) {
|
||||
return object[path];
|
||||
}
|
||||
return object[path]
|
||||
}
|
||||
|
||||
/**
|
||||
* Some description
|
||||
*/
|
||||
class Abc {
|
||||
/**
|
||||
* Some description
|
||||
*/
|
||||
method() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { transform } from '@babel/core';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import plugin from '../src';
|
||||
|
||||
let fixture = path.resolve('./tests/fixtures/example.js');
|
||||
|
||||
const code = fs.readFileSync(fixture);
|
||||
|
||||
it('works', () => {
|
||||
const { code: result } = transform(code, {
|
||||
plugins: [plugin],
|
||||
filename: fixture
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
17
packages/babel-plugin-docz/tests/index.test.ts
Normal file
17
packages/babel-plugin-docz/tests/index.test.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { transformSync } from '@babel/core'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import plugin from '../src'
|
||||
|
||||
const fixture = path.resolve('./tests/fixtures/example.js')
|
||||
|
||||
const code = fs.readFileSync(fixture).toString()
|
||||
|
||||
it('works', () => {
|
||||
const result = transformSync(code, {
|
||||
plugins: [plugin],
|
||||
filename: fixture,
|
||||
})
|
||||
|
||||
expect(result!.code).toMatchSnapshot()
|
||||
})
|
||||
@@ -4,7 +4,7 @@
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"declaration": true,
|
||||
"types": ["node"],
|
||||
"types": ["node", "mocha", "jest"],
|
||||
"typeRoots": ["node_modules/@types", "src/types"]
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
|
||||
@@ -57,24 +57,41 @@ const findImports = (code: string): RegExpMatchArray => {
|
||||
const imports: string[] = []
|
||||
let m
|
||||
|
||||
while (true) {
|
||||
do {
|
||||
m = regex.exec(code)
|
||||
if (m === null) break
|
||||
// This is necessary to avoid infinite loops with zero-width matches
|
||||
if (m.index === regex.lastIndex) {
|
||||
regex.lastIndex++
|
||||
if (m) {
|
||||
const [, imp] = m
|
||||
imports.push(imp)
|
||||
}
|
||||
|
||||
// The result can be accessed through the `m`-variable.
|
||||
m.forEach((match, groupIndex) => {
|
||||
if (groupIndex > 0) imports.push(match)
|
||||
})
|
||||
}
|
||||
} while (m)
|
||||
|
||||
return imports
|
||||
}
|
||||
|
||||
interface AliasConfig {
|
||||
[alias: string]: string
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://github.com/Microsoft/TypeScript/blob/9c71eaf59040ae75343da8cdff01344020f5bba2/src/compiler/moduleNameResolver.ts#L544
|
||||
*/
|
||||
const resolveAliases = (module: string, aliases: AliasConfig): string => {
|
||||
return Object.keys(aliases).reduce<string>((module, alias) => {
|
||||
const matcher = new RegExp(`^${alias.slice().replace(/\*/, '(.*)')}$`)
|
||||
const m = matcher.exec(module)
|
||||
if (!m) {
|
||||
return module
|
||||
}
|
||||
|
||||
const path = aliases[alias]
|
||||
|
||||
const [, sub] = m
|
||||
return path.slice().replace(/\*/, sub)
|
||||
}, module)
|
||||
}
|
||||
|
||||
const resolveModule = (module: string, relativePath: string): string | null => {
|
||||
module = resolveAliases(module, {}) // TODO: Read tsconfig.json and pass paths here
|
||||
const lookups = [
|
||||
`${module}.js`,
|
||||
`${module}.ts`,
|
||||
@@ -110,7 +127,9 @@ const findSourceFiles = async (
|
||||
return filepath ? findSourceFiles(config, filepath, await paths) : paths
|
||||
}
|
||||
|
||||
return imports.reduce(reducer, initial)
|
||||
return imports
|
||||
.filter(imp => found.indexOf(imp) === -1)
|
||||
.reduce(reducer, initial)
|
||||
}
|
||||
|
||||
const pathsFromEntries = (config: Config, src: string, filespaths: string[]) =>
|
||||
|
||||
Reference in New Issue
Block a user