Merge pull request #1434 from ankitects/sveltecheck

Svelte build improvements
This commit is contained in:
Damien Elmes 2021-10-18 13:13:54 +10:00 committed by GitHub
commit 800975b0db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 281 additions and 166 deletions

View file

@ -16,15 +16,18 @@ compile_sass(
], ],
) )
compile_svelte() _ts_deps = [
"//ts/components",
"//ts/lib",
"@npm//@fluent",
]
compile_svelte(deps = _ts_deps)
typescript( typescript(
name = "index", name = "index",
deps = [ deps = _ts_deps + [
":svelte", ":svelte",
"//ts/components",
"//ts/lib",
"@npm//@fluent",
], ],
) )

View file

@ -17,20 +17,23 @@ compile_sass(
], ],
) )
compile_svelte() _ts_deps = [
"//ts/components",
"//ts/lib",
"//ts/sveltelib",
"@npm//@fluent",
"@npm//@types/jest",
"@npm//lodash-es",
"@npm//svelte",
"@npm//marked",
]
compile_svelte(deps = _ts_deps)
typescript( typescript(
name = "index", name = "index",
deps = [ deps = _ts_deps + [
":svelte", ":svelte",
"//ts/components",
"//ts/lib",
"//ts/sveltelib",
"@npm//@fluent",
"@npm//@types/jest",
"@npm//lodash-es",
"@npm//svelte",
"@npm//svelte2tsx",
], ],
) )
@ -47,12 +50,6 @@ esbuild(
":base_css", ":base_css",
":index", ":index",
":svelte", ":svelte",
"//ts/components",
"//ts/lib",
"//ts/sveltelib",
"@npm//bootstrap",
"@npm//marked",
"@npm//protobufjs",
], ],
) )

View file

@ -3,20 +3,23 @@ load("//ts:prettier.bzl", "prettier_test")
load("//ts:eslint.bzl", "eslint_test") load("//ts:eslint.bzl", "eslint_test")
load("//ts:typescript.bzl", "typescript") load("//ts:typescript.bzl", "typescript")
_ts_deps = [
"//ts/lib",
"//ts/sveltelib",
"@npm//@popperjs/core",
"@npm//@types/bootstrap",
"@npm//bootstrap",
"@npm//svelte",
]
compile_svelte( compile_svelte(
deps = ["//sass/bootstrap"], deps = _ts_deps + ["//sass/bootstrap"],
) )
typescript( typescript(
name = "components", name = "components",
deps = [ deps = _ts_deps + [
":svelte", ":svelte",
"//ts/lib",
"//ts/sveltelib",
"@npm//@popperjs/core",
"@npm//@types/bootstrap",
"@npm//bootstrap",
"@npm//svelte",
], ],
) )

View file

@ -1,7 +1,7 @@
load("@npm//@bazel/typescript:index.bzl", "ts_library") load("@npm//@bazel/typescript:index.bzl", "ts_library")
load("//ts:prettier.bzl", "prettier_test") load("//ts:prettier.bzl", "prettier_test")
load("//ts:eslint.bzl", "eslint_test") load("//ts:eslint.bzl", "eslint_test")
load("//ts/svelte:svelte.bzl", "svelte", "svelte_check") load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
load("//ts:esbuild.bzl", "esbuild") load("//ts:esbuild.bzl", "esbuild")
load("//ts:compile_sass.bzl", "compile_sass") load("//ts:compile_sass.bzl", "compile_sass")
load("//ts:typescript.bzl", "typescript") load("//ts:typescript.bzl", "typescript")
@ -16,15 +16,14 @@ compile_sass(
], ],
) )
svelte( compile_svelte(
name = "CongratsPage", deps = ["//ts/lib"],
entry_point = "CongratsPage.svelte",
) )
typescript( typescript(
name = "index", name = "index",
deps = [ deps = [
"CongratsPage", ":svelte",
"//ts/lib", "//ts/lib",
"@npm//@fluent", "@npm//@fluent",
"@npm//svelte", "@npm//svelte",
@ -41,11 +40,9 @@ esbuild(
output_css = "congrats.css", output_css = "congrats.css",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"CongratsPage",
":base_css", ":base_css",
":index", ":index",
"//ts/lib", ":svelte",
"@npm//protobufjs",
], ],
) )

View file

@ -18,25 +18,29 @@ compile_sass(
], ],
) )
_ts_deps = [
"//ts/components",
"//ts/lib",
"//ts/sveltelib",
"@npm//@fluent",
"@npm//@popperjs",
"@npm//@types/jest",
"@npm//bootstrap-icons",
"@npm//lodash-es",
"@npm//svelte",
"@npm//marked",
]
compile_svelte( compile_svelte(
deps = [ deps = _ts_deps + [
"//sass/bootstrap", "//sass/bootstrap",
], ],
) )
typescript( typescript(
name = "index", name = "index",
deps = [ deps = _ts_deps + [
":svelte", ":svelte",
"//ts/components",
"//ts/lib",
"//ts/sveltelib",
"@npm//@fluent",
"@npm//@popperjs",
"@npm//@types/jest",
"@npm//bootstrap-icons",
"@npm//lodash-es",
"@npm//svelte",
], ],
) )
@ -50,15 +54,9 @@ esbuild(
output_css = "deck-options.css", output_css = "deck-options.css",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"index",
":base_css", ":base_css",
":index",
":svelte", ":svelte",
"//ts/components",
"//ts/lib",
"//ts/sveltelib",
"@npm//bootstrap",
"@npm//marked",
"@npm//protobufjs",
], ],
) )

View file

@ -15,20 +15,25 @@ compile_sass(
], ],
) )
compile_svelte() _ts_deps = [
"//ts/lib",
"//ts/sveltelib",
"@npm//@fluent",
"@npm//@types/d3",
"@npm//@types/lodash",
"@npm//d3",
"@npm//lodash-es",
"@npm//svelte",
]
compile_svelte(
deps = _ts_deps,
)
typescript( typescript(
name = "index", name = "index",
deps = [ deps = _ts_deps + [
":svelte", ":svelte",
"//ts/lib",
"//ts/sveltelib",
"@npm//@fluent",
"@npm//@types/d3",
"@npm//@types/lodash",
"@npm//d3",
"@npm//lodash-es",
"@npm//svelte",
], ],
) )

View file

@ -28,8 +28,6 @@ esbuild(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
":reviewer_ts", ":reviewer_ts",
"//ts/lib",
"@npm//protobufjs",
], ],
) )
@ -39,8 +37,6 @@ esbuild(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
":reviewer_ts", ":reviewer_ts",
"//ts/lib",
"@npm//protobufjs",
], ],
) )

View file

@ -1,28 +1,25 @@
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary") load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
load("@npm//@bazel/typescript:index.bzl", "ts_library") load("//ts:typescript.bzl", "typescript")
_deps = [ _deps = [
"@npm//@bazel/worker", "@npm//@bazel/worker",
"@npm//@types/node",
"@npm//sass", "@npm//sass",
"@npm//svelte", "@npm//svelte",
"@npm//svelte-preprocess", "@npm//svelte-preprocess",
"@npm//svelte2tsx", "@npm//svelte2tsx",
"@npm//typescript", "@npm//typescript",
"@npm//@types/node",
] ]
ts_library( typescript(
name = "svelte_bin_ts", name = "svelte_worker_ts",
srcs = ["svelte.ts"], srcs = ["svelte.ts"],
tsconfig = "//ts:tsconfig_bin",
deps = _deps, deps = _deps,
) )
nodejs_binary( nodejs_binary(
name = "svelte_bin", name = "svelte_bin",
data = ["svelte_bin_ts"] + _deps, data = [":svelte_worker_ts"] + _deps,
entry_point = ":svelte.ts", entry_point = ":svelte.js",
# should fix .js files being not found on subsequent worker requests
templated_args = ["--bazel_patch_module_resolver"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )

View file

@ -2,82 +2,97 @@ load("@npm//svelte-check:index.bzl", _svelte_check = "svelte_check_test")
load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "declaration_info") load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "declaration_info")
load("@io_bazel_rules_sass//:defs.bzl", "SassInfo") load("@io_bazel_rules_sass//:defs.bzl", "SassInfo")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("@bazel_skylib//lib:paths.bzl", "paths")
def _get_dep_sources(dep): def _get_declarations(dep):
if SassInfo in dep: if SassInfo in dep:
return dep[SassInfo].transitive_sources return dep[SassInfo].transitive_sources
elif DeclarationInfo in dep: elif DeclarationInfo in dep:
return dep[DeclarationInfo].transitive_declarations return dep[DeclarationInfo].transitive_declarations
else: else:
return [] fail("unexpected dep", dep)
def _get_sources(deps):
return depset([], transitive = [_get_dep_sources(dep) for dep in deps])
def _svelte(ctx): def _svelte(ctx):
args = ctx.actions.args() args = ctx.actions.args()
args.use_param_file("@%s", use_always = True) args.use_param_file("@%s", use_always = True)
args.set_param_file_format("multiline") args.set_param_file_format("multiline")
args.add(ctx.file.entry_point.path) # path to bin folder, for sass
args.add(ctx.outputs.mjs.path)
args.add(ctx.outputs.dts.path)
args.add(ctx.outputs.css.path)
args.add(ctx.var["BINDIR"]) args.add(ctx.var["BINDIR"])
args.add(ctx.var["GENDIR"]) args.add(ctx.var["GENDIR"])
args.add_all(ctx.files._shims)
deps = _get_sources(ctx.attr.deps).to_list() # svelte and ts sources
outputs = []
dts_only = []
nondts_only = []
for src in ctx.files.srcs:
args.add(src.path)
if src.path.endswith(".svelte"):
# strip off external/ankidesktop if invoked from external workspace
path = src.path
if src.path.startswith("external/ankidesktop/"):
path = path[len("external/ankidesktop/"):]
# strip off package prefix, eg ts/editor/mathjax/Foo.svelte -> mathjax/Foo.svelte
base = path[len(ctx.label.package) + 1:]
for ext in ("d.ts", "css", "mjs"):
out = ctx.actions.declare_file(base.replace(".svelte", ".svelte." + ext))
args.add(out)
outputs.append(out)
if ext == "d.ts":
dts_only.append(out)
else:
nondts_only.append(out)
# dependencies
deps = depset([], transitive = [_get_declarations(dep) for dep in ctx.attr.deps])
args.add_all(deps)
ctx.actions.run( ctx.actions.run(
execution_requirements = {"supports-workers": "1"}, execution_requirements = {"supports-workers": "1"},
executable = ctx.executable._svelte_bin, executable = ctx.executable._svelte_bin,
outputs = [ctx.outputs.mjs, ctx.outputs.dts, ctx.outputs.css], outputs = outputs,
inputs = [ctx.file.entry_point] + deps + ctx.files._shims, inputs = ctx.files.srcs + deps.to_list(),
mnemonic = "Svelte", mnemonic = "Svelte",
progress_message = "Compiling Svelte {}:{}".format(ctx.label.package, ctx.attr.name),
arguments = [args], arguments = [args],
) )
return [ return [
declaration_info(depset([ctx.outputs.dts]), deps = [ctx.attr._shims]), declaration_info(depset(dts_only), deps = ctx.attr.deps),
DefaultInfo(
files = depset(nondts_only),
runfiles = ctx.runfiles(files = outputs, transitive_files = deps),
),
] ]
svelte = rule( svelte = rule(
implementation = _svelte, implementation = _svelte,
attrs = { attrs = {
"entry_point": attr.label(allow_single_file = True), "srcs": attr.label_list(allow_files = True, doc = ".ts and .svelte files"),
"deps": attr.label_list(), "deps": attr.label_list(),
"_svelte_bin": attr.label( "_svelte_bin": attr.label(
default = Label("//ts/svelte:svelte_bin"), default = Label("//ts/svelte:svelte_bin"),
executable = True, executable = True,
cfg = "host", cfg = "host",
), ),
"_shims": attr.label(
default = Label("@npm//svelte2tsx:svelte2tsx__typings"),
allow_files = True,
),
},
outputs = {
"mjs": "%{name}.svelte.mjs",
"dts": "%{name}.svelte.d.ts",
"css": "%{name}.svelte.css",
}, },
) )
def compile_svelte(name = "svelte", srcs = None, deps = [], visibility = ["//visibility:private"]): def compile_svelte(name = "svelte", srcs = None, deps = [], visibility = ["//visibility:private"]):
if not srcs: if not srcs:
srcs = native.glob(["*.svelte"]) srcs = native.glob([
for src in srcs: "**/*.svelte",
svelte( "**/*.ts",
name = src.replace(".svelte", ""), ])
entry_point = src,
deps = deps,
visibility = visibility,
)
js_library( svelte(
name = name, name = name,
srcs = [s.replace(".svelte", "") for s in srcs], srcs = srcs,
deps = deps + [
"@npm//svelte2tsx",
],
visibility = visibility, visibility = visibility,
) )

View file

@ -8,23 +8,22 @@ import { svelte2tsx } from "svelte2tsx";
import preprocess from "svelte-preprocess"; import preprocess from "svelte-preprocess";
import { basename } from "path"; import { basename } from "path";
import * as ts from "typescript"; import * as ts from "typescript";
import * as svelte from "svelte/compiler.js"; import * as svelte from "svelte/compiler";
let parsedCommandLine: ts.ParsedCommandLine = { const parsedCommandLine: ts.ParsedCommandLine = {
fileNames: [], fileNames: [],
errors: [], errors: [],
options: { options: {
jsx: ts.JsxEmit.Preserve, jsx: ts.JsxEmit.Preserve,
declaration: true, declaration: true,
emitDeclarationOnly: true, emitDeclarationOnly: true,
skipLibCheck: true, // noEmitOnError: true,
paths: {
"*": ["*", "external/npm/node_modules/*"],
},
}, },
}; };
// We avoid hitting the filesystem for ts/d.ts files after initial startup - the
// .ts file we generate can be injected directly into our cache, and Bazel
// should restart us if the Svelte or TS typings change.
interface FileContent { interface FileContent {
text: string; text: string;
version: number; version: number;
@ -43,17 +42,17 @@ function getFileContent(path: string): FileContent {
return content; return content;
} }
function updateFileContent(path: string, text: string): void { function updateFileContent(input: InputFile): void {
let content = fileContent.get(path); let content = fileContent.get(input.path);
if (content) { if (content) {
content.text = text; content.text = input.data;
content.version += 1; content.version += 1;
} else { } else {
content = { content = {
text, text: input.data,
version: 0, version: 0,
}; };
fileContent.set(path, content); fileContent.set(input.path, content);
} }
} }
@ -65,7 +64,6 @@ const languageServiceHost: ts.LanguageServiceHost = {
return getFileContent(path).version.toString(); return getFileContent(path).version.toString();
}, },
getScriptSnapshot: (path: string): ts.IScriptSnapshot | undefined => { getScriptSnapshot: (path: string): ts.IScriptSnapshot | undefined => {
// if (!ts.sys.fileExists(fileName)) {
const text = getFileContent(path).text; const text = getFileContent(path).text;
return { return {
getText: (start: number, end: number) => { getText: (start: number, end: number) => {
@ -78,7 +76,7 @@ const languageServiceHost: ts.LanguageServiceHost = {
}, },
getLength: () => text.length, getLength: () => text.length,
getChangeRange: ( getChangeRange: (
oldSnapshot: ts.IScriptSnapshot _oldSnapshot: ts.IScriptSnapshot
): ts.TextChangeRange | undefined => { ): ts.TextChangeRange | undefined => {
return undefined; return undefined;
}, },
@ -90,14 +88,29 @@ const languageServiceHost: ts.LanguageServiceHost = {
const languageService = ts.createLanguageService(languageServiceHost); const languageService = ts.createLanguageService(languageServiceHost);
function compile(tsPath: string, tsLibs: string[]) { async function emitTypings(svelte: SvelteTsxFile[], deps: InputFile[]): Promise<void> {
parsedCommandLine.fileNames = [tsPath, ...tsLibs]; const allFiles = [...svelte, ...deps];
allFiles.forEach(updateFileContent);
parsedCommandLine.fileNames = allFiles.map((i) => i.path);
const program = languageService.getProgram()!; const program = languageService.getProgram()!;
const tsHost = ts.createCompilerHost(parsedCommandLine.options); const tsHost = ts.createCompilerHost(parsedCommandLine.options);
const createdFiles = {}; const createdFiles = {};
tsHost.writeFile = (fileName, contents) => (createdFiles[fileName] = contents); const cwd = ts.sys.getCurrentDirectory().replace(/\\/g, "/");
program.emit(undefined /* all files */, tsHost.writeFile); tsHost.writeFile = (fileName, contents) => {
return createdFiles[parsedCommandLine.fileNames[0].replace(".tsx", ".d.ts")]; // tsc makes some paths absolute for some reason
if (fileName.startsWith(cwd)) {
fileName = fileName.substring(cwd.length + 1);
}
createdFiles[fileName] = contents;
};
const result = program.emit(undefined /* all files */, tsHost.writeFile);
// for (const diag of result.diagnostics) {
// console.log(diag.messageText);
// }
for (const file of svelte) {
await writeFile(file.realDtsPath, createdFiles[file.virtualDtsPath]);
}
} }
function writeFile(file, data): Promise<void> { function writeFile(file, data): Promise<void> {
@ -124,26 +137,8 @@ function readFile(file) {
}); });
} }
async function writeDts(tsPath, dtsPath, tsLibs) { async function compileSingleSvelte(
const dtsSource = compile(tsPath, tsLibs); input: SvelteInput,
await writeFile(dtsPath, dtsSource);
}
function writeTs(svelteSource, sveltePath, tsPath): void {
let tsSource = svelte2tsx(svelteSource, {
filename: sveltePath,
isTsFile: true,
mode: "dts",
});
let codeLines = tsSource.code.split("\n");
updateFileContent(tsPath, codeLines.join("\n"));
}
async function writeJs(
source: string,
inputFilename: string,
outputJsPath: string,
outputCssPath: string,
binDir: string, binDir: string,
genDir: string genDir: string
): Promise<void> { ): Promise<void> {
@ -162,14 +157,14 @@ async function writeJs(
}); });
try { try {
const processed = await svelte.preprocess(source, preprocessOptions, { const processed = await svelte.preprocess(input.data, preprocessOptions, {
filename: inputFilename, filename: input.path,
}); });
const result = svelte.compile(processed.toString!(), { const result = svelte.compile(processed.toString!(), {
format: "esm", format: "esm",
css: false, css: false,
generate: "dom", generate: "dom",
filename: outputJsPath, filename: input.mjsPath,
}); });
// warnings are an error // warnings are an error
if (result.warnings.length > 0) { if (result.warnings.length > 0) {
@ -177,27 +172,123 @@ async function writeJs(
} }
// write out the css file // write out the css file
const outputCss = result.css.code ?? ""; const outputCss = result.css.code ?? "";
await writeFile(outputCssPath, outputCss); await writeFile(input.cssPath, outputCss);
// if it was non-empty, prepend a reference to it in the js file, so that // if it was non-empty, prepend a reference to it in the js file, so that
// it's included in the bundled .css when bundling // it's included in the bundled .css when bundling
const outputSource = const outputSource =
(outputCss ? `import "./${basename(outputCssPath)}";` : "") + (outputCss ? `import "./${basename(input.cssPath)}";` : "") +
result.js.code; result.js.code;
await writeFile(outputJsPath, outputSource); await writeFile(input.mjsPath, outputSource);
} catch (err) { } catch (err) {
console.log(`compile failed: ${err}`); console.log(`compile failed: ${err}`);
return; return;
} }
} }
async function compileSvelte(args) { interface Args {
const [sveltePath, mjsPath, dtsPath, cssPath, binDir, genDir, ...tsLibs] = args; binDir: string;
const svelteSource = (await readFile(sveltePath)) as string; genDir: string;
svelteFiles: SvelteInput[];
dependencies: InputFile[];
}
const mockTsPath = sveltePath + ".tsx"; interface InputFile {
writeTs(svelteSource, sveltePath, mockTsPath); path: string;
await writeDts(mockTsPath, dtsPath, tsLibs); data: string;
await writeJs(svelteSource, sveltePath, mjsPath, cssPath, binDir, genDir); }
interface SvelteInput extends InputFile {
dtsPath: string;
cssPath: string;
mjsPath: string;
}
async function extractArgsAndData(args: string[]): Promise<Args> {
const [binDir, genDir, ...rest] = args;
const [svelteFiles, dependencies] = await extractSvelteAndDeps(rest);
return {
binDir,
genDir,
svelteFiles,
dependencies,
};
}
async function extractSvelteAndDeps(
files: string[]
): Promise<[SvelteInput[], InputFile[]]> {
const svelte: SvelteInput[] = [];
const deps: InputFile[] = [];
files.reverse();
while (files.length) {
const file = files.pop()!;
const data = (await readFile(file)) as string;
if (file.endsWith(".svelte")) {
svelte.push({
path: file,
data,
dtsPath: files.pop()!,
cssPath: files.pop()!,
mjsPath: files.pop()!,
});
} else {
deps.push({ path: remapBinToSrcDir(file), data });
}
}
return [svelte, deps];
}
/// Our generated .tsx files sit in the bin dir, but .ts files
/// may be coming from the source folder, which breaks ./foo imports.
/// Adjust the path to make it appear they're all in the same folder.
function remapBinToSrcDir(file: string): string {
return file.replace(new RegExp("bazel-out/[-_a-z]+/bin/"), "");
}
/// Generate Svelte .mjs/.css files.
async function compileSvelte(
svelte: SvelteInput[],
binDir: string,
genDir: string
): Promise<void> {
for (const file of svelte) {
await compileSingleSvelte(file, binDir, genDir);
}
}
interface SvelteTsxFile extends InputFile {
// relative to src folder
virtualDtsPath: string;
// must go to bazel-out
realDtsPath: string;
}
function generateTsxFiles(svelteFiles: SvelteInput[]): SvelteTsxFile[] {
return svelteFiles.map((file) => {
const data = svelte2tsx(file.data, {
filename: file.path,
isTsFile: true,
mode: "dts",
}).code;
const path = file.path.replace(".svelte", ".svelte.tsx");
return {
path,
data,
virtualDtsPath: path.replace(".tsx", ".d.ts"),
realDtsPath: file.dtsPath,
};
});
}
async function compileSvelteAndGenerateTypings(argsList: string[]): Promise<boolean> {
const args = await extractArgsAndData(argsList);
// mjs/css
await compileSvelte(args.svelteFiles, args.binDir, args.genDir);
// d.ts
const tsxFiles = generateTsxFiles(args.svelteFiles);
await emitTypings(tsxFiles, args.dependencies);
return true; return true;
} }
@ -206,12 +297,12 @@ function main() {
if (worker.runAsWorker(process.argv)) { if (worker.runAsWorker(process.argv)) {
console.log = worker.log; console.log = worker.log;
worker.log("Svelte running as a Bazel worker"); worker.log("Svelte running as a Bazel worker");
worker.runWorkerLoop(compileSvelte); worker.runWorkerLoop(compileSvelteAndGenerateTypings);
} else { } else {
const paramFile = process.argv[2].replace(/^@/, ""); const paramFile = process.argv[2].replace(/^@/, "");
const commandLineArgs = fs.readFileSync(paramFile, "utf-8").trim().split("\n"); const commandLineArgs = fs.readFileSync(paramFile, "utf-8").trim().split("\n");
console.log("Svelte running as a standalone process"); console.log("Svelte running as a standalone process");
compileSvelte(commandLineArgs); compileSvelteAndGenerateTypings(commandLineArgs);
} }
} }

13
ts/svelte/tsconfig.json Normal file
View file

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"include": ["*"],
"references": [],
"compilerOptions": {
// ignore missing optional modules like postcss
"skipLibCheck": true,
// ensure node can run the resulting code
"noEmitHelpers": false,
"importHelpers": false,
"module": "commonjs",
}
}