mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 02:28:28 -06:00
* Prototype TS plugins on web This prototype allows service plugins to be loaded on web TSServer Main changes: - Adds a new host entryPoint called `importServicePlugin` for overriding how plugins can be loaded. This may be async - Implement `importServicePlugin` for webServer - The web server plugin implementation looks for a `browser` field in the plugin's `package.json` - It then uses `import(...)` to load the plugin (the plugin source must be compiled to support being loaded as a module) * use default export from plugins This more or less matches how node plugins expect the plugin module to be an init function * Allow configure plugin requests against any web servers in partial semantic mode * Addressing some comments - Use result value instead of try/catch (`ImportPluginResult`) - Add awaits - Add logging * add tsserverWeb to patch in dynamic import * Remove eval We should throw instead when dynamic import is not implemented * Ensure dynamically imported plugins are loaded in the correct order * Add tests for async service plugin timing * Update src/server/editorServices.ts Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> * Partial PR feedback * Rename tsserverWeb to dynamicImportCompat * Additional PR feedback Co-authored-by: Ron Buckton <ron.buckton@microsoft.com> Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
112 lines
3.9 KiB
TypeScript
112 lines
3.9 KiB
TypeScript
/// <reference types="node" />
|
|
|
|
import childProcess = require("child_process");
|
|
import fs = require("fs-extra");
|
|
import path = require("path");
|
|
import glob = require("glob");
|
|
|
|
const root = path.join(__dirname, "..");
|
|
const source = path.join(root, "built/local");
|
|
const dest = path.join(root, "lib");
|
|
const copyright = fs.readFileSync(path.join(__dirname, "../CopyrightNotice.txt"), "utf-8");
|
|
|
|
async function produceLKG() {
|
|
console.log(`Building LKG from ${source} to ${dest}`);
|
|
await copyLibFiles();
|
|
await copyLocalizedDiagnostics();
|
|
await copyTypesMap();
|
|
await copyScriptOutputs();
|
|
await copyDeclarationOutputs();
|
|
await buildProtocol();
|
|
await writeGitAttributes();
|
|
}
|
|
|
|
async function copyLibFiles() {
|
|
await copyFilesWithGlob("lib?(.*).d.ts");
|
|
}
|
|
|
|
async function copyLocalizedDiagnostics() {
|
|
const dir = await fs.readdir(source);
|
|
const ignoredFolders = ["enu"];
|
|
|
|
for (const d of dir) {
|
|
const fileName = path.join(source, d);
|
|
if (
|
|
fs.statSync(fileName).isDirectory() &&
|
|
ignoredFolders.indexOf(d) < 0
|
|
) {
|
|
await fs.copy(fileName, path.join(dest, d));
|
|
}
|
|
}
|
|
}
|
|
|
|
async function copyTypesMap() {
|
|
await copyFromBuiltLocal("typesMap.json"); // Cannot accommodate copyright header
|
|
}
|
|
|
|
async function buildProtocol() {
|
|
const protocolScript = path.join(__dirname, "buildProtocol.js");
|
|
if (!fs.existsSync(protocolScript)) {
|
|
throw new Error(`Expected protocol script ${protocolScript} to exist`);
|
|
}
|
|
|
|
const protocolInput = path.join(__dirname, "../src/server/protocol.ts");
|
|
const protocolServices = path.join(source, "typescriptServices.d.ts");
|
|
const protocolOutput = path.join(dest, "protocol.d.ts");
|
|
|
|
console.log(`Building ${protocolOutput}...`);
|
|
await exec(protocolScript, [protocolInput, protocolServices, protocolOutput]);
|
|
}
|
|
|
|
async function copyScriptOutputs() {
|
|
await copyWithCopyright("cancellationToken.js");
|
|
await copyWithCopyright("tsc.release.js", "tsc.js");
|
|
await copyWithCopyright("tsserver.js");
|
|
await copyWithCopyright("dynamicImportCompat.js");
|
|
await copyFromBuiltLocal("tsserverlibrary.js"); // copyright added by build
|
|
await copyFromBuiltLocal("typescript.js"); // copyright added by build
|
|
await copyFromBuiltLocal("typescriptServices.js"); // copyright added by build
|
|
await copyWithCopyright("typingsInstaller.js");
|
|
await copyWithCopyright("watchGuard.js");
|
|
}
|
|
|
|
async function copyDeclarationOutputs() {
|
|
await copyFromBuiltLocal("tsserverlibrary.d.ts"); // copyright added by build
|
|
await copyFromBuiltLocal("typescript.d.ts"); // copyright added by build
|
|
await copyFromBuiltLocal("typescriptServices.d.ts"); // copyright added by build
|
|
}
|
|
|
|
async function writeGitAttributes() {
|
|
await fs.writeFile(path.join(dest, ".gitattributes"), `* text eol=lf`, "utf-8");
|
|
}
|
|
|
|
async function copyWithCopyright(fileName: string, destName = fileName) {
|
|
const content = await fs.readFile(path.join(source, fileName), "utf-8");
|
|
await fs.writeFile(path.join(dest, destName), copyright + "\n" + content);
|
|
}
|
|
|
|
async function copyFromBuiltLocal(fileName: string) {
|
|
await fs.copy(path.join(source, fileName), path.join(dest, fileName));
|
|
}
|
|
|
|
async function copyFilesWithGlob(pattern: string) {
|
|
const files = glob.sync(path.join(source, pattern)).map(f => path.basename(f));
|
|
for (const f of files) {
|
|
await copyFromBuiltLocal(f);
|
|
}
|
|
console.log(`Copied ${files.length} files matching pattern ${pattern}`);
|
|
}
|
|
|
|
async function exec(path: string, args: string[] = []) {
|
|
const cmdLine = ["node", path, ...args].join(" ");
|
|
console.log(cmdLine);
|
|
childProcess.execSync(cmdLine);
|
|
}
|
|
|
|
process.on("unhandledRejection", err => {
|
|
throw err;
|
|
});
|
|
produceLKG().then(() => console.log("Done"), err => {
|
|
throw err;
|
|
});
|