rollup-plugin-dts
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -22,10 +22,9 @@ 'use strict'; | ||
/** | ||
* Create an export for `id`: | ||
* Create a default export for `id`: | ||
* `export default id` | ||
*/ | ||
function createDefaultExport(node, range) { | ||
const id = createIdentifier(node, range); | ||
return withStartEnd({ | ||
type: "ExportDefaultDeclaration", | ||
declaration: id, | ||
declaration: createIdentifier(node), | ||
}, range); | ||
@@ -38,3 +37,3 @@ } | ||
function createExport(node, range) { | ||
const id = createIdentifier(node, range); | ||
const id = createIdentifier(node); | ||
return withStartEnd({ | ||
@@ -66,7 +65,10 @@ type: "ExportNamedDeclaration", | ||
} | ||
function createIdentifier(node, range = node) { | ||
function createIdentifier(node) { | ||
return withStartEnd({ | ||
type: "Identifier", | ||
name: node.text || String(node.escapedText), | ||
}, range); | ||
}, { | ||
start: node.getStart(), | ||
end: node.getEnd(), | ||
}); | ||
} | ||
@@ -78,3 +80,2 @@ /** | ||
function createDeclaration(id, range) { | ||
const start = getStart(range); | ||
return withStartEnd({ | ||
@@ -84,5 +85,5 @@ type: "FunctionDeclaration", | ||
type: "Identifier", | ||
name: id.text, | ||
}, { start, end: start }), | ||
params: [createReference(createIdentifier(id))], | ||
name: ts.idText(id), | ||
}, { start: id.getStart(), end: id.getEnd() }), | ||
params: [], | ||
body: { type: "BlockStatement", body: [] }, | ||
@@ -140,2 +141,6 @@ }, range); | ||
} | ||
function isInternal(node) { | ||
const tags = ts.getJSDocTags(node); | ||
return tags.some(t => ts.idText(t.tagName) === "internal"); | ||
} | ||
@@ -198,6 +203,16 @@ const IGNORE_TYPENODES = new Set([ | ||
for (const node of members) { | ||
if ((ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isIndexSignatureDeclaration(node)) && | ||
node.type) { | ||
this.convertTypeNode(node.type); | ||
// NOTE(swatinem): | ||
// Well, actually having `private`/`protected` members in the exported | ||
// definitions is quite nice, so let’s keep them. Instead we look for an | ||
// `@internal` tag | ||
// if (matchesModifier(node, ts.ModifierFlags.Private) || matchesModifier(node, ts.ModifierFlags.Protected)) { | ||
if (isInternal(node)) { | ||
this.pushRaw(removeNested({ start: node.getFullStart(), end: node.getEnd() })); | ||
continue; | ||
} | ||
if (ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isIndexSignatureDeclaration(node)) { | ||
if (node.type) { | ||
this.convertTypeNode(node.type); | ||
} | ||
} | ||
// istanbul ignore else | ||
@@ -304,5 +319,9 @@ else if (ts.isMethodDeclaration(node) || | ||
maybeMarkAsExported(node, id) { | ||
if (isInternal(node)) { | ||
return false; | ||
} | ||
if (matchesModifier(node, ts.ModifierFlags.ExportDefault)) { | ||
const start = node.pos; | ||
this.pushStatement(createDefaultExport(id, { start, end: start })); | ||
return true; | ||
} | ||
@@ -312,3 +331,5 @@ else if (matchesModifier(node, ts.ModifierFlags.Export)) { | ||
this.pushStatement(createExport(id, { start, end: start })); | ||
return true; | ||
} | ||
return false; | ||
} | ||
@@ -370,4 +391,2 @@ createDeclaration(id, range) { | ||
scope.convertHeritageClauses(node); | ||
// NOTE(swatinem): typescript loses the non-null assertion for `node.name` | ||
scope.pushIdentifierReference(node.name); | ||
scope.convertMembers(node.members); | ||
@@ -379,3 +398,2 @@ } | ||
scope.removeModifier(node); | ||
scope.pushIdentifierReference(node.name); | ||
scope.convertTypeNode(node.type); | ||
@@ -399,3 +417,2 @@ } | ||
scope.removeModifier(node); | ||
scope.pushIdentifierReference(decl.name); | ||
if (decl.type) { | ||
@@ -492,3 +509,3 @@ scope.convertTypeNode(decl.type); | ||
} | ||
const compilerOptions = Object.assign({}, options.compilerOptions, { noEmitOnError: false, noEmit: false, skipLibCheck: true, declaration: true, | ||
const compilerOptions = Object.assign({}, options.compilerOptions, { noEmitOnError: false, noEmit: false, skipLibCheck: true, declaration: true, allowJs: true, checkJs: true, resolveJsonModule: true, | ||
// hm, there are still issues with this, I couldn’t get it to work locally | ||
@@ -535,19 +552,22 @@ // See https://github.com/Microsoft/TypeScript/issues/25662 | ||
}, | ||
transform(fileName) { | ||
transform(code, fileName) { | ||
const { compiler } = lazyCreate(); | ||
const sourceFile = compiler.getSourceFile(fileName); | ||
let dtsFilename = ""; | ||
let code = ""; | ||
let dtsSource = sourceFile; | ||
let dtsFilename = fileName; | ||
let map = `{"mappings": ""}`; | ||
const baseFileName = fileName.slice(0, -path.extname(fileName).length); | ||
compiler.emit(sourceFile, (fileName, data) => { | ||
if (fileName === `${baseFileName}.d.ts`) { | ||
dtsFilename = fileName; | ||
code = data.replace(SOURCEMAPPING_URL_RE, "").trim(); | ||
} | ||
// if (fileName === `${baseFileName}.d.ts.map`) { | ||
// map = data; | ||
// } | ||
}); | ||
const dtsSource = ts.createSourceFile(dtsFilename, code, ts.ScriptTarget.Latest, true); | ||
if (!fileName.endsWith(".d.ts")) { | ||
code = ""; | ||
const baseFileName = fileName.slice(0, -path.extname(fileName).length); | ||
compiler.emit(sourceFile, (fileName, data) => { | ||
if (fileName === `${baseFileName}.d.ts`) { | ||
dtsFilename = fileName; | ||
code = data.replace(SOURCEMAPPING_URL_RE, "").trim(); | ||
} | ||
// if (fileName === `${baseFileName}.d.ts.map`) { | ||
// map = data; | ||
// } | ||
}); | ||
dtsSource = ts.createSourceFile(dtsFilename, code, ts.ScriptTarget.Latest, true); | ||
} | ||
const converter = new Transformer(dtsSource); | ||
@@ -568,3 +588,3 @@ const ast = converter.transform(); | ||
function dts(options = {}) { | ||
const filter = rollupPluginutils.createFilter(options.include || ["*.ts+(|x)", "**/*.ts+(|x)"], options.exclude || []); | ||
const filter = rollupPluginutils.createFilter(options.include || ["*.ts+(|x)", "**/*.ts+(|x)", "*.json", "**/*.json"], options.exclude || []); | ||
const compiler = getCachedCompiler({ | ||
@@ -583,3 +603,3 @@ tsconfig: options.tsconfig || process.cwd(), | ||
}, | ||
async transform(_code, id) { | ||
async transform(code, id) { | ||
// istanbul ignore if | ||
@@ -589,3 +609,3 @@ if (!filter(id)) { | ||
} | ||
return compiler.transform(id); | ||
return compiler.transform(code, id); | ||
}, | ||
@@ -592,0 +612,0 @@ }; |
import { createFilter } from 'rollup-pluginutils'; | ||
import { findConfigFile, sys, getParsedCommandLineOfConfigFile, createProgram, nodeModuleNameResolver, createSourceFile, ScriptTarget, ModifierFlags, isFunctionDeclaration, isInterfaceDeclaration, isClassDeclaration, isTypeAliasDeclaration, isVariableStatement, isExportDeclaration, isExportAssignment, isImportDeclaration, SyntaxKind, isIdentifier, isNamedImports, isLiteralExpression, getCombinedModifierFlags, isPropertyDeclaration, isPropertySignature, isIndexSignatureDeclaration, isMethodDeclaration, isMethodSignature, isConstructorDeclaration, isConstructSignatureDeclaration, isParenthesizedTypeNode, isTypeOperatorNode, isArrayTypeNode, isTupleTypeNode, isUnionTypeNode, isIntersectionTypeNode, isTypeLiteralNode, isMappedTypeNode, isConditionalTypeNode, isIndexedAccessTypeNode, isTypeReferenceNode } from 'typescript'; | ||
import { findConfigFile, sys, getParsedCommandLineOfConfigFile, createProgram, nodeModuleNameResolver, createSourceFile, ScriptTarget, ModifierFlags, isFunctionDeclaration, isInterfaceDeclaration, isClassDeclaration, isTypeAliasDeclaration, isVariableStatement, isExportDeclaration, isExportAssignment, isImportDeclaration, SyntaxKind, isIdentifier, isNamedImports, idText, isLiteralExpression, getCombinedModifierFlags, getJSDocTags, isPropertyDeclaration, isPropertySignature, isIndexSignatureDeclaration, isMethodDeclaration, isMethodSignature, isConstructorDeclaration, isConstructSignatureDeclaration, isParenthesizedTypeNode, isTypeOperatorNode, isArrayTypeNode, isTupleTypeNode, isUnionTypeNode, isIntersectionTypeNode, isTypeLiteralNode, isMappedTypeNode, isConditionalTypeNode, isIndexedAccessTypeNode, isTypeReferenceNode } from 'typescript'; | ||
import path from 'path'; | ||
@@ -18,10 +18,9 @@ | ||
/** | ||
* Create an export for `id`: | ||
* Create a default export for `id`: | ||
* `export default id` | ||
*/ | ||
function createDefaultExport(node, range) { | ||
const id = createIdentifier(node, range); | ||
return withStartEnd({ | ||
type: "ExportDefaultDeclaration", | ||
declaration: id, | ||
declaration: createIdentifier(node), | ||
}, range); | ||
@@ -34,3 +33,3 @@ } | ||
function createExport(node, range) { | ||
const id = createIdentifier(node, range); | ||
const id = createIdentifier(node); | ||
return withStartEnd({ | ||
@@ -62,7 +61,10 @@ type: "ExportNamedDeclaration", | ||
} | ||
function createIdentifier(node, range = node) { | ||
function createIdentifier(node) { | ||
return withStartEnd({ | ||
type: "Identifier", | ||
name: node.text || String(node.escapedText), | ||
}, range); | ||
}, { | ||
start: node.getStart(), | ||
end: node.getEnd(), | ||
}); | ||
} | ||
@@ -74,3 +76,2 @@ /** | ||
function createDeclaration(id, range) { | ||
const start = getStart(range); | ||
return withStartEnd({ | ||
@@ -80,5 +81,5 @@ type: "FunctionDeclaration", | ||
type: "Identifier", | ||
name: id.text, | ||
}, { start, end: start }), | ||
params: [createReference(createIdentifier(id))], | ||
name: idText(id), | ||
}, { start: id.getStart(), end: id.getEnd() }), | ||
params: [], | ||
body: { type: "BlockStatement", body: [] }, | ||
@@ -136,2 +137,6 @@ }, range); | ||
} | ||
function isInternal(node) { | ||
const tags = getJSDocTags(node); | ||
return tags.some(t => idText(t.tagName) === "internal"); | ||
} | ||
@@ -194,6 +199,16 @@ const IGNORE_TYPENODES = new Set([ | ||
for (const node of members) { | ||
if ((isPropertyDeclaration(node) || isPropertySignature(node) || isIndexSignatureDeclaration(node)) && | ||
node.type) { | ||
this.convertTypeNode(node.type); | ||
// NOTE(swatinem): | ||
// Well, actually having `private`/`protected` members in the exported | ||
// definitions is quite nice, so let’s keep them. Instead we look for an | ||
// `@internal` tag | ||
// if (matchesModifier(node, ts.ModifierFlags.Private) || matchesModifier(node, ts.ModifierFlags.Protected)) { | ||
if (isInternal(node)) { | ||
this.pushRaw(removeNested({ start: node.getFullStart(), end: node.getEnd() })); | ||
continue; | ||
} | ||
if (isPropertyDeclaration(node) || isPropertySignature(node) || isIndexSignatureDeclaration(node)) { | ||
if (node.type) { | ||
this.convertTypeNode(node.type); | ||
} | ||
} | ||
// istanbul ignore else | ||
@@ -300,5 +315,9 @@ else if (isMethodDeclaration(node) || | ||
maybeMarkAsExported(node, id) { | ||
if (isInternal(node)) { | ||
return false; | ||
} | ||
if (matchesModifier(node, ModifierFlags.ExportDefault)) { | ||
const start = node.pos; | ||
this.pushStatement(createDefaultExport(id, { start, end: start })); | ||
return true; | ||
} | ||
@@ -308,3 +327,5 @@ else if (matchesModifier(node, ModifierFlags.Export)) { | ||
this.pushStatement(createExport(id, { start, end: start })); | ||
return true; | ||
} | ||
return false; | ||
} | ||
@@ -366,4 +387,2 @@ createDeclaration(id, range) { | ||
scope.convertHeritageClauses(node); | ||
// NOTE(swatinem): typescript loses the non-null assertion for `node.name` | ||
scope.pushIdentifierReference(node.name); | ||
scope.convertMembers(node.members); | ||
@@ -375,3 +394,2 @@ } | ||
scope.removeModifier(node); | ||
scope.pushIdentifierReference(node.name); | ||
scope.convertTypeNode(node.type); | ||
@@ -395,3 +413,2 @@ } | ||
scope.removeModifier(node); | ||
scope.pushIdentifierReference(decl.name); | ||
if (decl.type) { | ||
@@ -488,3 +505,3 @@ scope.convertTypeNode(decl.type); | ||
} | ||
const compilerOptions = Object.assign({}, options.compilerOptions, { noEmitOnError: false, noEmit: false, skipLibCheck: true, declaration: true, | ||
const compilerOptions = Object.assign({}, options.compilerOptions, { noEmitOnError: false, noEmit: false, skipLibCheck: true, declaration: true, allowJs: true, checkJs: true, resolveJsonModule: true, | ||
// hm, there are still issues with this, I couldn’t get it to work locally | ||
@@ -531,19 +548,22 @@ // See https://github.com/Microsoft/TypeScript/issues/25662 | ||
}, | ||
transform(fileName) { | ||
transform(code, fileName) { | ||
const { compiler } = lazyCreate(); | ||
const sourceFile = compiler.getSourceFile(fileName); | ||
let dtsFilename = ""; | ||
let code = ""; | ||
let dtsSource = sourceFile; | ||
let dtsFilename = fileName; | ||
let map = `{"mappings": ""}`; | ||
const baseFileName = fileName.slice(0, -path.extname(fileName).length); | ||
compiler.emit(sourceFile, (fileName, data) => { | ||
if (fileName === `${baseFileName}.d.ts`) { | ||
dtsFilename = fileName; | ||
code = data.replace(SOURCEMAPPING_URL_RE, "").trim(); | ||
} | ||
// if (fileName === `${baseFileName}.d.ts.map`) { | ||
// map = data; | ||
// } | ||
}); | ||
const dtsSource = createSourceFile(dtsFilename, code, ScriptTarget.Latest, true); | ||
if (!fileName.endsWith(".d.ts")) { | ||
code = ""; | ||
const baseFileName = fileName.slice(0, -path.extname(fileName).length); | ||
compiler.emit(sourceFile, (fileName, data) => { | ||
if (fileName === `${baseFileName}.d.ts`) { | ||
dtsFilename = fileName; | ||
code = data.replace(SOURCEMAPPING_URL_RE, "").trim(); | ||
} | ||
// if (fileName === `${baseFileName}.d.ts.map`) { | ||
// map = data; | ||
// } | ||
}); | ||
dtsSource = createSourceFile(dtsFilename, code, ScriptTarget.Latest, true); | ||
} | ||
const converter = new Transformer(dtsSource); | ||
@@ -564,3 +584,3 @@ const ast = converter.transform(); | ||
function dts(options = {}) { | ||
const filter = createFilter(options.include || ["*.ts+(|x)", "**/*.ts+(|x)"], options.exclude || []); | ||
const filter = createFilter(options.include || ["*.ts+(|x)", "**/*.ts+(|x)", "*.json", "**/*.json"], options.exclude || []); | ||
const compiler = getCachedCompiler({ | ||
@@ -579,3 +599,3 @@ tsconfig: options.tsconfig || process.cwd(), | ||
}, | ||
async transform(_code, id) { | ||
async transform(code, id) { | ||
// istanbul ignore if | ||
@@ -585,3 +605,3 @@ if (!filter(id)) { | ||
} | ||
return compiler.transform(id); | ||
return compiler.transform(code, id); | ||
}, | ||
@@ -588,0 +608,0 @@ }; |
{ | ||
"name": "rollup-plugin-dts", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "An experiment to generate .d.ts rollup files", | ||
@@ -47,2 +47,6 @@ "keywords": [ | ||
"**/?(*.)+(spec|test).(ts|tsx)" | ||
], | ||
"testPathIgnorePatterns": [ | ||
"/node_modules/", | ||
"/testcases/" | ||
] | ||
@@ -49,0 +53,0 @@ }, |
@@ -49,28 +49,11 @@ # rollup-plugin-dts | ||
### Marking code for removal | ||
For things on the top-level that we want removed from our source, we generate | ||
an `IfStatement` that is always false. Rollup will figure this out and just | ||
remove that statement altogether. | ||
``` | ||
if (false) {} | ||
``` | ||
[See it live](https://rollupjs.org/repl?version=0.67.1&shareable=JTdCJTIybW9kdWxlcyUyMiUzQSU1QiU3QiUyMm5hbWUlMjIlM0ElMjJtYWluLmpzJTIyJTJDJTIyY29kZSUyMiUzQSUyMmlmJTIwKGZhbHNlKSUyMCU3QiU3RCUyMiU3RCU1RCUyQyUyMm9wdGlvbnMlMjIlM0ElN0IlMjJmb3JtYXQlMjIlM0ElMjJlc20lMjIlMkMlMjJuYW1lJTIyJTNBJTIybXlCdW5kbGUlMjIlMkMlMjJhbWQlMjIlM0ElN0IlMjJpZCUyMiUzQSUyMiUyMiU3RCU3RCUyQyUyMmV4YW1wbGUlMjIlM0FudWxsJTdE) | ||
The trick here is to annotate this `IfStatement` with a certain `start` and `end`. | ||
Rollup will then just remove all the bytes between `start` and `end`, without | ||
even looking into what those bytes actually are. | ||
**TODO**: actually, it should be easier to just generate any identifier without | ||
a side-effect, like I do for nested code. | ||
### Creating declarations | ||
For each export (`class`, `function`, `interface` or `type`), we will create | ||
a bogus `FunctionDeclaration` for rollup. Again, we annotate the | ||
`FunctionDeclaration` with a set of `start` and `end` markers, so that rollup | ||
will remove the correct parts of our code if it figures out the declaration is | ||
not referenced. | ||
a bogus `FunctionDeclaration` for rollup. | ||
The trick here is to annotate this `FunctionDeclaration` with a certain | ||
`start` and `end`. | ||
Rollup will then just remove all the bytes between `start` and `end`, without | ||
even looking into what those bytes actually are, if it figures out that the | ||
declaration is not referenced. | ||
@@ -155,2 +138,1 @@ ``` | ||
- [ ] type parameters with correct shadowing | ||
- [ ] maybe removing things from the bundle marked with `@internal` or `@hidden` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51294
1191
137