Skip to content
This repository was archived by the owner on Aug 4, 2021. It is now read-only.

[WIP] Progress towards 2.0 support and tslib #91

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/node_modules
dist
npm-debug.log
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rollup-plugin-typescript",
"version": "0.8.1",
"version": "1.0.0",
"description": "Seamless integration between Rollup and TypeScript.",
"main": "dist/rollup-plugin-typescript.cjs.js",
"module": "dist/rollup-plugin-typescript.es.js",
Expand Down Expand Up @@ -31,20 +31,19 @@
"object-assign": "^4.0.1",
"rollup-pluginutils": "^1.3.1",
"tippex": "^2.1.1",
"typescript": "^1.8.9"
"tslib": "^1.7.1",
"typescript": "^2.3.3"
},
"devDependencies": {
"@types/react": "^15.0.24",
"buble": "^0.13.1",
"eslint": "^2.13.1",
"mocha": "^3.0.0",
"rimraf": "^2.5.4",
"rollup": "^0.49.3",
"rollup-plugin-buble": "^0.13.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rollup/rollup-plugin-typescript.git"
},
"repository": "rollup/rollup-plugin-typescript",
"bugs": {
"url": "https://github.com/rollup/rollup-plugin-typescript/issues"
}
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default {
'object-assign',
'rollup-pluginutils',
'tippex',
'tslib',
'typescript'
],

Expand Down
132 changes: 132 additions & 0 deletions src/compiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import * as fs from 'fs';
import compareVersions from 'compare-versions';

export default function createCompiler ( ts, compilerOpts, entry, useLanguageService ) {
const typescript = ts;
const compilerOptions = compilerOpts;
const entryFile = entry;
let languageService = undefined;

const fileCache = new Map();
const tsFiles = new Set();

tsFiles.add( entryFile );

if ( useLanguageService ) {
initLanguageService();
}

function getFile (fileName) {
let file = fileCache.get( fileName );

if ( file === undefined ) {
const version = Date.now().toString();

if ( !fs.existsSync( fileName ) ) {
file = {
snapshot: undefined,
version
};
} else {
file = {
snapshot: typescript.ScriptSnapshot.fromString( fs.readFileSync( fileName ).toString() ),
version
};
}

fileCache.set( fileName, file );
}

return file;
}

function setFileContent ( fileName, content, override ) {
if (!override && fileCache.get( fileName )) {
return;
}

tsFiles.add( fileName );

fileCache.set( fileName, {
snapshot: typescript.ScriptSnapshot.fromString( content ),
version: Date.now().toString()
});
}

function initLanguageService () {
if (languageService) return;

fixTypeLookup();

const languageServiceHost = {
getScriptFileNames: () => Array.from( tsFiles ),
getScriptVersion: ( fileName ) => getFile( fileName ).version,
getScriptSnapshot: (fileName) => getFile( fileName ).snapshot,
getCurrentDirectory: () => process.cwd(),
getCompilationSettings: () => compilerOptions,
getDefaultLibFileName: ( options ) => typescript.getDefaultLibFilePath( options )
};

languageService = typescript.createLanguageService( languageServiceHost, typescript.createDocumentRegistry() );
}

/**
* Workaround for the LanguageService not finding typings in node_modules/@types:
* Manually set the "types" option to the folder names in node_modules/@types
*/
function fixTypeLookup () {
if ( compilerOptions.types || compilerOptions.typeRoots ) return;

if ( compareVersions( typescript.version, '2.0.0' ) < 0 ) {
return;
}

if ( fs.existsSync( './node_modules/@types' ) ) {
compilerOptions.types = fs.readdirSync('./node_modules/@types');
}
}


function compileUsingLanguageService ( fileName, content, refreshFile ) {
setFileContent( fileName, content, refreshFile );

const result = {
outputText: undefined,
diagnostics: undefined,
sourceMapText: undefined
};

const compiled = languageService.getEmitOutput( fileName );

result.diagnostics = languageService.getCompilerOptionsDiagnostics()
.concat( languageService.getSyntacticDiagnostics( fileName ) )
.concat( languageService.getSemanticDiagnostics( fileName ) );

compiled.outputFiles.forEach( outputFile => {
if ( outputFile.name.slice( -3 ) === '.js' ) {
result.outputText = outputFile.text;
} else if ( outputFile.name.slice( -4 ) === '.map' ) {
result.sourceMapText = outputFile.text;
}
});

return result;
}

function compileUsingSimpleApi ( fileName, content ) {
return typescript.transpileModule( content, {
fileName,
reportDiagnostics: true,
compilerOptions
});
}

function compileFile ( fileName, content, refreshFile ) {
return languageService
? compileUsingLanguageService( fileName, content, refreshFile )
: compileUsingSimpleApi( fileName, content );
}

return { compileFile };
}

75 changes: 62 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { endsWith } from './string';
import { getDefaultOptions, compilerOptionsFromTsConfig, adjustCompilerOptions } from './options.js';
import fixExportClass from './fixExportClass';
import resolveHost from './resolveHost';
import createCompiler from './compiler';

/*
interface Options {
Expand Down Expand Up @@ -37,14 +38,24 @@ export default function typescript ( options ) {
// Allow users to override the TypeScript version used for transpilation.
const typescript = options.typescript || ts;

if ( compareVersions( typescript.version, '1.6.0' ) < 0 ) {
throw new Error( `rollup-plugin-typescript: TypeScript version must be later than 1.6.0` );
}

delete options.typescript;

// Load options from `tsconfig.json` unless explicitly asked not to.
const tsconfig = options.tsconfig === false ? {} :
compilerOptionsFromTsConfig( typescript );
const tsconfig = options.tsconfig === false
? {}
: typeof options.tsconfig === 'string'
? compilerOptionsFromTsConfig(typescript, options.tsconfig)
: compilerOptionsFromTsConfig(typescript, 'tsconfig.json');

delete options.tsconfig;

const useLanguageService = options.useLanguageService !== false;
delete options.useLanguageService;

// Since the CompilerOptions aren't designed for the Rollup
// use case, we'll adjust them for use with Rollup.
adjustCompilerOptions( typescript, tsconfig );
Expand All @@ -68,10 +79,39 @@ export default function typescript ( options ) {

const compilerOptions = parsed.options;

const isVersionOne = compareVersions( typescript.version, '2.0.0' ) >= 0;
let isFirstRun = true;

let compiler;

return {
options (opts) {
const entryFile = path.resolve(process.cwd(), opts.input || opts.entry);
compiler = createCompiler( typescript, compilerOptions, entryFile, useLanguageService );

const definitionsFilter = createFilter(
[ '*.d.ts', '**/*.d.ts' ],
[ 'node_modules/**' ] );

function read (dir, parent) {
dir.forEach(file => {
file = path.join(parent, file);
const stats = fs.statSync(file);
if (stats.isFile() && file.indexOf('.d.ts') > -1) {
if (definitionsFilter(file)) {
compiler.compileFile(file, fs.readFileSync(file, 'utf8'), false);
}
} else if (stats.isDirectory()) {
read(fs.readdirSync(file), file);
}
});
}
read(fs.readdirSync(process.cwd()), process.cwd());
},

resolveId ( importee, importer ) {
// Handle the special `typescript-helpers` import itself.
if ( importee === helpersId ) {
if ( isVersionOne && importee === helpersId ) {
return helpersId;
}

Expand Down Expand Up @@ -100,19 +140,19 @@ export default function typescript ( options ) {
},

load ( id ) {
if ( id === helpersId ) {
if ( isVersionOne && id === helpersId ) {
return helpersSource;
}
},

transform ( code, id ) {
if ( !filter( id ) ) return null;

const transformed = typescript.transpileModule( fixExportClass( code, id ), {
fileName: id,
reportDiagnostics: true,
compilerOptions
});
if ( compilerOptions.target === undefined || compilerOptions.target < typescript.ScriptTarget.ES2015 && isVersionOne ) {
code = fixExportClass( code, id );
}

const transformed = compiler.compileFile( id, code, !isFirstRun );

// All errors except `Cannot compile modules into 'es6' when targeting 'ES5' or lower.`
const diagnostics = transformed.diagnostics ?
Expand All @@ -136,18 +176,27 @@ export default function typescript ( options ) {
}
});

if ( fatalError ) {
if ( fatalError && isFirstRun ) {
throw new Error( `There were TypeScript errors transpiling` );
}

let finalCode = transformed.outputText;

if (isVersionOne) {
// Always append an import for the helpers (for versions < 2)
finalCode += `\nimport { __assign, __awaiter, __extends, __decorate, __metadata, __param } from '${helpersId}';`;
}

return {
// Always append an import for the helpers.
code: transformed.outputText +
`\nimport { __assign, __awaiter, __extends, __decorate, __metadata, __param } from '${helpersId}';`,
code: finalCode,

// Rollup expects `map` to be an object so we must parse the string
map: transformed.sourceMapText ? JSON.parse(transformed.sourceMapText) : null
};
},

onwrite () {
isFirstRun = false;
}
};
}
8 changes: 6 additions & 2 deletions src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ function findFile ( cwd, filename ) {
return null;
}

export function compilerOptionsFromTsConfig ( typescript ) {
export function compilerOptionsFromTsConfig ( typescript, filename) {
const cwd = process.cwd();

const tsconfig = typescript.readConfigFile( findFile( cwd, 'tsconfig.json' ), path => readFileSync( path, 'utf8' ) );
const tsconfig = typescript.readConfigFile( findFile( cwd, filename ), path => readFileSync( path, 'utf8' ) );

if ( !tsconfig.config || !tsconfig.config.compilerOptions ) return {};

Expand All @@ -65,4 +65,8 @@ export function adjustCompilerOptions ( typescript, options ) {

console.warn( `rollup-plugin-typescript: 'strictNullChecks' is not supported; disabling it` );
}

if ( compareVersions( tsVersion, '2.0.0' ) >= 0) {
options.importHelpers = true;
}
}
Loading