| 1 | const {transform} = require("../dist");
|
|---|
| 2 |
|
|---|
| 3 | // Enum constants taken from the TypeScript codebase.
|
|---|
| 4 | const ModuleKindCommonJS = 1;
|
|---|
| 5 |
|
|---|
| 6 | const JsxEmitReactJSX = 4;
|
|---|
| 7 | const JsxEmitReactJSXDev = 5;
|
|---|
| 8 |
|
|---|
| 9 | /**
|
|---|
| 10 | * ts-node transpiler plugin
|
|---|
| 11 | *
|
|---|
| 12 | * This plugin hooks into ts-node so that Sucrase can handle all TS-to-JS
|
|---|
| 13 | * conversion while ts-node handles the ESM loader, require hook, REPL
|
|---|
| 14 | * integration, etc. ts-node automatically discovers the relevant tsconfig file,
|
|---|
| 15 | * so the main logic in this integration is translating tsconfig options to the
|
|---|
| 16 | * corresponding Sucrase options.
|
|---|
| 17 | *
|
|---|
| 18 | * Any tsconfig options relevant to Sucrase are translated, but some config
|
|---|
| 19 | * options outside the scope of Sucrase are ignored. For example, we assume the
|
|---|
| 20 | * isolatedModules option, and we ignore target because Sucrase doesn't provide
|
|---|
| 21 | * JS syntax downleveling (at least not in a way that is useful for Node).
|
|---|
| 22 | *
|
|---|
| 23 | * One notable caveat is that importsNotUsedAsValues and preserveValueImports
|
|---|
| 24 | * are ignored right now, since they are deprecated and don't have exact Sucrase
|
|---|
| 25 | * equivalents. To preserve imports and exports, use verbatimModuleSyntax.
|
|---|
| 26 | */
|
|---|
| 27 | function create(createOptions) {
|
|---|
| 28 | const {nodeModuleEmitKind} = createOptions;
|
|---|
| 29 | const {
|
|---|
| 30 | module,
|
|---|
| 31 | jsx,
|
|---|
| 32 | jsxFactory,
|
|---|
| 33 | jsxFragmentFactory,
|
|---|
| 34 | jsxImportSource,
|
|---|
| 35 | esModuleInterop,
|
|---|
| 36 | verbatimModuleSyntax,
|
|---|
| 37 | } = createOptions.service.config.options;
|
|---|
| 38 |
|
|---|
| 39 | return {
|
|---|
| 40 | transpile(input, transpileOptions) {
|
|---|
| 41 | const {fileName} = transpileOptions;
|
|---|
| 42 | const transforms = [];
|
|---|
| 43 | // Detect JS rather than TS so we bias toward including the typescript
|
|---|
| 44 | // transform, since almost always it doesn't hurt to include.
|
|---|
| 45 | const isJS =
|
|---|
| 46 | fileName.endsWith(".js") ||
|
|---|
| 47 | fileName.endsWith(".jsx") ||
|
|---|
| 48 | fileName.endsWith(".mjs") ||
|
|---|
| 49 | fileName.endsWith(".cjs");
|
|---|
| 50 | if (!isJS) {
|
|---|
| 51 | transforms.push("typescript");
|
|---|
| 52 | }
|
|---|
| 53 | if (module === ModuleKindCommonJS || nodeModuleEmitKind === "nodecjs") {
|
|---|
| 54 | transforms.push("imports");
|
|---|
| 55 | }
|
|---|
| 56 | if (fileName.endsWith(".tsx") || fileName.endsWith(".jsx")) {
|
|---|
| 57 | transforms.push("jsx");
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 | const {code, sourceMap} = transform(input, {
|
|---|
| 61 | transforms,
|
|---|
| 62 | disableESTransforms: true,
|
|---|
| 63 | jsxRuntime: jsx === JsxEmitReactJSX || jsx === JsxEmitReactJSXDev ? "automatic" : "classic",
|
|---|
| 64 | production: jsx === JsxEmitReactJSX,
|
|---|
| 65 | jsxImportSource,
|
|---|
| 66 | jsxPragma: jsxFactory,
|
|---|
| 67 | jsxFragmentPragma: jsxFragmentFactory,
|
|---|
| 68 | keepUnusedImports: verbatimModuleSyntax,
|
|---|
| 69 | preserveDynamicImport: nodeModuleEmitKind === "nodecjs",
|
|---|
| 70 | injectCreateRequireForImportRequire: nodeModuleEmitKind === "nodeesm",
|
|---|
| 71 | enableLegacyTypeScriptModuleInterop: !esModuleInterop,
|
|---|
| 72 | sourceMapOptions: {compiledFilename: fileName},
|
|---|
| 73 | filePath: fileName,
|
|---|
| 74 | });
|
|---|
| 75 | return {
|
|---|
| 76 | outputText: code,
|
|---|
| 77 | sourceMapText: JSON.stringify(sourceMap),
|
|---|
| 78 | };
|
|---|
| 79 | },
|
|---|
| 80 | };
|
|---|
| 81 | }
|
|---|
| 82 |
|
|---|
| 83 | exports.create = create;
|
|---|