Skip to content
Snippets Groups Projects
Commit 6b4bcdc2 authored by Eric MORAND's avatar Eric MORAND
Browse files

Merge branch 'issue-7' into 'main'

Resolve issue #7

Closes #7

See merge request !12
parents 2f1be7af fcaddf74
No related branches found
No related tags found
1 merge request!12Resolve issue #7
Pipeline #1644352178 passed
......@@ -41,7 +41,7 @@ ts-node test/cases/foo.ts
It is even possible - and recommended - to track the coverage while writing tests:
```shell
nyc ts-node test/cases/foo.ts
odz ts-node test/cases/foo.ts
```
Of course, it is also perfectly possible to pipe the result of the test to your favorite tap formatter:
......
{
"scripts": {
"build:main": "(cd src/main && rollup --config && tsc -p . --outDir target --declaration --emitDeclarationOnly)",
"build:main": "(cd src/main && rollup --config && tsc -p . --outDir target --declaration --emitDeclarationOnly --noCheck)",
"build:test": "(cd src/test && rollup --config)",
"test": "node src/test/target"
},
......
export {default, FactoryOptions, createTypeScriptPlugin} from "./lib/plugin";
export {default, type FactoryOptions, createTypeScriptPlugin, type TypeScriptPlugin} from "./lib/plugin";
......@@ -14,4 +14,6 @@ export interface Filesystem {
readFileSync(path: string, encoding?: string): Buffer | string;
writeFileSync(path: string, data: string): void;
rmSync(path: string): void;
}
\ No newline at end of file
import type {Plugin} from "rollup";
import {TransformResult} from "rollup";
import type {Plugin, SourceDescription} from "rollup";
import typeScript from "typescript";
import {createFilter} from "@rollup/pluginutils";
import {dirname, normalize, relative, resolve} from "node:path";
......@@ -32,12 +31,18 @@ export type FactoryOptions = {
log?: typeof console.log;
};
export type TypeScriptPlugin = Omit<Plugin<null>, "transform"> & {
transform(this: {
error(error: string, position?: { column: number; line: number }): void;
}, code: string, id: string): null | SourceDescription;
};
/**
* Returns a newly created instance of [Plugin](https://rollupjs.org/plugin-development/) from the passed options.
*
* @param options
*/
export const createTypeScriptPlugin = (options: FactoryOptions = {}) => {
export const createTypeScriptPlugin = (options: FactoryOptions = {}): TypeScriptPlugin => {
let passedCompilerOptions = options.compilerOptions || {};
const configFilePath = typeScript.findConfigFile(process.cwd(), typeScript.sys.fileExists);
......@@ -94,9 +99,13 @@ export const createTypeScriptPlugin = (options: FactoryOptions = {}) => {
},
writeFileSync: (path, data) => {
return volume.writeFileSync(path, data);
},
rmSync: (path) => {
return volume.rmSync(path);
}
};
const log = options.log || (() => {});
const log = options.log || (() => {
});
const compiler = createCompiler(compilerOptions, fileSystem, log);
const createModuleResolver = () => {
......@@ -147,24 +156,39 @@ export const createTypeScriptPlugin = (options: FactoryOptions = {}) => {
content: string;
name: string;
}> = [];
let compilationErrors: CompilationErrors = [];
const plugin: Plugin<null> = {
const plugin: TypeScriptPlugin = {
name: 'typescript',
buildStart() {
compilationErrors = [];
},
transform(_code, id): TransformResult {
transform(code, id) {
if (!filter(id)) {
return null;
}
const resolvedId = id;
const getTransformResult = (resolvedId: string): TransformResult => {
if (fileSystem.existsSync(resolvedId)) {
const cachedCode = fileSystem.readFileSync(resolvedId).toString();
if (cachedCode !== code) {
const outputFileNames = compiler.getOutputFileNames(resolvedId);
fileSystem.rmSync(outputFileNames.code);
log(`${resolvedId}'s cache invalidated`);
}
}
fileSystem.mkdirSync(dirname(resolvedId));
fileSystem.writeFileSync(resolvedId, code);
const getTransformResult = (resolvedId: string): null | SourceDescription => {
const outputFileNames = compiler.getOutputFileNames(resolvedId);
const code = fileSystem.existsSync(outputFileNames.code) && fileSystem.readFileSync(outputFileNames.code).toString();
......@@ -179,27 +203,27 @@ export const createTypeScriptPlugin = (options: FactoryOptions = {}) => {
};
let result = getTransformResult(resolvedId);
if (!result) {
log(`${resolvedId} was encountered for the first time`);
compilationErrors.push(...compiler.compile(resolvedId));
log(`compilationErrors are`, compilationErrors);
const files = fileSystem.getFiles();
for (const file of files) {
if (isADeclarationOutputFile(file.path)) {
const content = file.content!;
emittedDeclarationFiles.push({
name: relative(dirname(id), file.path),
content
name: relative(dirname(id), file.path),
content
});
}
}
const errorsToEmit = compilationErrors.filter((error) => {
// if error is a string, this is a global error
return typeof error === "string" || error.file === resolvedId;
......@@ -254,7 +278,6 @@ export const createTypeScriptPlugin = (options: FactoryOptions = {}) => {
return null;
},
generateBundle() {
for (const file of emittedDeclarationFiles) {
this.emitFile({
type: "asset",
......
......@@ -43,6 +43,9 @@ export const foo: number = 5 + bar;`,
},
writeFileSync: (path, data) => {
return volume.writeFileSync(path, data);
},
rmSync: (path) => {
return volume.rmSync(path);
}
};
......
......@@ -5,5 +5,6 @@ import "./compiler-options";
import "./error";
import "./filter";
import "./options";
import "./plugin";
import "./public-api";
import "./resolve";
\ No newline at end of file
import tape from "tape";
import createTypeScriptPlugin from "../../main/lib/plugin";
import {spy} from "sinon";
tape('Plugin', ({test}) => {
test('TypeScriptPlugin::transform', ({end, same, true: isTrue}) => {
const log = spy(() => {
});
const plugin = createTypeScriptPlugin({
log
});
const resultA = plugin.transform.bind({
error: () => {
}
})('5;', 'foo.ts');
same(eval(resultA!.code), 5);
log.resetHistory();
const resultB = plugin.transform.bind({
error: () => {
}
})('10;', 'foo.ts');
isTrue(log.getCalls().map((call) => call.firstArg).includes('foo.ts\'s cache invalidated'));
same(eval(resultB!.code), 10);
log.resetHistory();
const resultC = plugin.transform.bind({
error: () => {
}
})('10;', 'foo.ts');
same(eval(resultC!.code), 10);
end();
});
});
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment