Skip to content

Instantly share code, notes, and snippets.

@Awk34
Created May 11, 2020 17:58
Show Gist options
  • Save Awk34/b105d5bd9030cfc4da8cfc213deaa4c6 to your computer and use it in GitHub Desktop.
Save Awk34/b105d5bd9030cfc4da8cfc213deaa4c6 to your computer and use it in GitHub Desktop.
// node_modules/parcel-bundler/src/assets/TypeScriptAsset.js
const Asset = require('../Asset');
const localRequire = require('../utils/localRequire');
const isAccessedVarChanged = require('../utils/isAccessedVarChanged');
const fs = require('fs');
class TypeScriptAsset extends Asset {
constructor(name, options) {
super(name, options);
this.type = 'js';
this.cacheData.env = {};
}
shouldInvalidate(cacheData) {
return isAccessedVarChanged(cacheData);
}
async generate() {
// require typescript, installed locally in the app
let ts = await localRequire('typescript', this.name);
let transpilerOptions = {
compilerOptions: {
module: this.options.scopeHoist
? ts.ModuleKind.ESNext
: ts.ModuleKind.CommonJS,
jsx: ts.JsxEmit.Preserve,
// it brings the generated output from TypeScript closer to that generated by Babel
// see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html
esModuleInterop: true
},
fileName: this.relativeName
};
let tsconfig = await this.getConfig(['tsconfig.json']);
// Overwrite default if config is found
if (tsconfig) {
transpilerOptions.compilerOptions = Object.assign(
transpilerOptions.compilerOptions,
tsconfig.compilerOptions
);
}
transpilerOptions.compilerOptions.noEmit = false;
transpilerOptions.compilerOptions.sourceMap = this.options.sourceMaps;
// Transpile Module using TypeScript and parse result as ast format through babylon
let transpiled = ts.transpileModule(
this.contents,
transpilerOptions
);
// NEW ==============
const rootFileNames = [this.name];
const files = {};
// initialize the list of files
rootFileNames.forEach(fileName => {
files[fileName] = { version: 0 };
});
console.log(tsconfig);
const options = tsconfig.compilerOptions;
const servicesHost = {
getScriptFileNames: () => rootFileNames,
getScriptVersion: fileName =>
files[fileName] && files[fileName].version.toString(),
getScriptSnapshot: fileName => {
if (!fs.existsSync(fileName)) {
return undefined;
}
return ts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString());
},
getCurrentDirectory: () => process.cwd(),
getCompilationSettings: () => options,
getDefaultLibFileName: options => ts.getDefaultLibFilePath(options),
fileExists: ts.sys.fileExists,
readFile: ts.sys.readFile,
readDirectory: ts.sys.readDirectory,
};
const services = ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
let allDiagnostics = services
.getCompilerOptionsDiagnostics()
.concat(services.getSyntacticDiagnostics(this.name))
.concat(services.getSemanticDiagnostics(this.name));
allDiagnostics.forEach(diagnostic => {
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
if (diagnostic.file) {
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
console.error(` Error ${diagnostic.file.fileName} (${line + 1},${character +1}): ${message}`);
} else {
console.error(` Error: ${message}`);
}
});
// NEW ==============
let sourceMap = transpiled.sourceMapText;
if (sourceMap) {
sourceMap = JSON.parse(sourceMap);
sourceMap.sources = [this.relativeName];
sourceMap.sourcesContent = [this.contents];
// Remove the source map URL
let content = transpiled.outputText;
transpiled.outputText = content.substring(
0,
content.lastIndexOf('//# sourceMappingURL')
);
}
return [
{
type: 'js',
value: transpiled.outputText,
map: sourceMap
}
];
}
}
module.exports = TypeScriptAsset;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment