Skip to content

Commit

Permalink
improve standalone typings (#14630)
Browse files Browse the repository at this point in the history
* babel-standalone

* address review comment
  • Loading branch information
JLHwung committed Jun 21, 2022
1 parent 772f686 commit 9789a13
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 19 deletions.
26 changes: 17 additions & 9 deletions packages/babel-standalone/src/index.ts
Expand Up @@ -26,6 +26,7 @@ import presetEnv from "@babel/preset-env";
import presetFlow from "@babel/preset-flow";
import presetReact from "@babel/preset-react";
import presetTypescript from "@babel/preset-typescript";
import type { InputOptions } from "@babel/core";

import { runScripts } from "./transformScriptTags";

Expand All @@ -40,7 +41,7 @@ const isArray =
* Returns undefined if the preset or plugin is not available; passes through
* name unmodified if it (or the first element of the pair) is not a string.
*/
function loadBuiltin(builtinTable, name) {
function loadBuiltin(builtinTable: Record<string, unknown>, name: any) {
if (isArray(name) && typeof name[0] === "string") {
if (Object.prototype.hasOwnProperty.call(builtinTable, name[0])) {
return [builtinTable[name[0]]].concat(name.slice(1));
Expand All @@ -56,7 +57,7 @@ function loadBuiltin(builtinTable, name) {
/**
* Parses plugin names and presets from the specified options.
*/
function processOptions(options) {
function processOptions(options: InputOptions) {
// Parse preset names
const presets = (options.presets || []).map(presetName => {
const preset = loadBuiltin(availablePresets, presetName);
Expand Down Expand Up @@ -100,15 +101,19 @@ function processOptions(options) {
};
}

export function transform(code: string, options: any) {
export function transform(code: string, options: InputOptions) {
return babelTransformSync(code, processOptions(options));
}

export function transformFromAst(ast: any, code: string, options: any) {
export function transformFromAst(
ast: Parameters<typeof babelTransformFromAst>[0],
code: string,
options: InputOptions,
) {
return babelTransformFromAstSync(ast, code, processOptions(options));
}
export const availablePlugins = {};
export const availablePresets = {};
export const availablePlugins: typeof all = {};

export const buildExternalHelpers = babelBuildExternalHelpers;
/**
* Registers a named plugin for use with Babel.
Expand Down Expand Up @@ -148,6 +153,7 @@ export function registerPreset(name: string, preset: any | Function): void {
);
}
}
// @ts-expect-error mutating available presets
availablePresets[name] = preset;
}
/**
Expand All @@ -170,7 +176,7 @@ registerPlugins(all);
// All the presets we should bundle
// Want to get rid of this list of allowed presets?
// Wait! Please read https://github.com/babel/babel/pull/6177 first.
registerPresets({
export const availablePresets = {
env: presetEnv,
es2015: preset2015,
es2016: () => {
Expand All @@ -197,7 +203,7 @@ registerPresets({
},
typescript: presetTypescript,
flow: presetFlow,
});
};

// @ts-ignore VERSION is to be replaced by rollup
export const version: string = VERSION;
Expand All @@ -216,7 +222,9 @@ if (typeof window !== "undefined" && window?.addEventListener) {
* Transform <script> tags with "text/babel" type.
* @param {Array} scriptTags specify script tags to transform, transform all in the <head> if not given
*/
export function transformScriptTags(scriptTags?: Array<any>) {
export function transformScriptTags(
scriptTags?: HTMLCollectionOf<HTMLScriptElement>,
) {
runScripts(transform, scriptTags);
}

Expand Down
52 changes: 42 additions & 10 deletions packages/babel-standalone/src/transformScriptTags.ts
Expand Up @@ -8,13 +8,32 @@

const scriptTypes = ["text/jsx", "text/babel"];

let headEl;
import { transform } from "./index";
import type { InputOptions } from "@babel/core";

let headEl: HTMLHeadElement;
let inlineScriptCount = 0;

type CompilationResult = {
async: boolean;
type: string;
error: boolean;
loaded: boolean;
content: string | null;
executed: boolean;
// todo: refine plugins/presets
plugins: InputOptions["plugins"];
presets: InputOptions["presets"];
url: string | null;
};

/**
* Actually transform the code.
*/
function transformCode(transformFn, script) {
function transformCode(
transformFn: typeof transform,
script: CompilationResult,
) {
let source;
if (script.url != null) {
source = script.url;
Expand All @@ -33,7 +52,7 @@ function transformCode(transformFn, script) {
* Builds the Babel options for transforming the specified script, using some
* sensible default presets and plugins if none were explicitly provided.
*/
function buildBabelOptions(script, filename) {
function buildBabelOptions(script: CompilationResult, filename: string) {
let presets = script.presets;
if (!presets) {
if (script.type === "module") {
Expand Down Expand Up @@ -62,7 +81,7 @@ function buildBabelOptions(script, filename) {
"proposal-object-rest-spread",
"transform-flow-strip-types",
],
sourceMaps: "inline",
sourceMaps: "inline" as const,
sourceFileName: filename,
};
}
Expand All @@ -71,7 +90,7 @@ function buildBabelOptions(script, filename) {
* Appends a script element at the end of the <head> with the content of code,
* after transforming it.
*/
function run(transformFn, script) {
function run(transformFn: typeof transform, script: CompilationResult) {
const scriptEl = document.createElement("script");
if (script.type) {
scriptEl.setAttribute("type", script.type);
Expand All @@ -83,7 +102,11 @@ function run(transformFn, script) {
/**
* Load script from the provided url and pass the content to the callback.
*/
function load(url, successCallback, errorCallback) {
function load(
url: string,
successCallback: (content: string) => void,
errorCallback: () => void,
) {
const xhr = new XMLHttpRequest();

// async, however scripts will be executed in the order they are in the
Expand All @@ -110,7 +133,10 @@ function load(url, successCallback, errorCallback) {
* the string is empty, returns an empty array. If the string is not defined,
* returns null.
*/
function getPluginsOrPresetsFromScript(script, attributeName) {
function getPluginsOrPresetsFromScript(
script: HTMLScriptElement,
attributeName: string,
) {
const rawValue = script.getAttribute(attributeName);
if (rawValue === "") {
// Empty string means to not load ANY presets or plugins
Expand All @@ -129,8 +155,11 @@ function getPluginsOrPresetsFromScript(script, attributeName) {
* inline script, or by using XHR. Transforms are applied if needed. The scripts
* are executed in the order they are found on the page.
*/
function loadScripts(transformFn, scripts) {
const result = [];
function loadScripts(
transformFn: typeof transform,
scripts: HTMLScriptElement[],
) {
const result: CompilationResult[] = [];
const count = scripts.length;

function check() {
Expand Down Expand Up @@ -196,7 +225,10 @@ function loadScripts(transformFn, scripts) {
* Run script tags with type="text/jsx".
* @param {Array} scriptTags specify script tags to run, run all in the <head> if not given
*/
export function runScripts(transformFn, scripts) {
export function runScripts(
transformFn: typeof transform,
scripts?: HTMLCollectionOf<HTMLScriptElement>,
) {
headEl = document.getElementsByTagName("head")[0];
if (!scripts) {
scripts = document.getElementsByTagName("script");
Expand Down

0 comments on commit 9789a13

Please sign in to comment.