Skip to content

Commit

Permalink
refactor(tools): enable TypeScript as default (#8521)
Browse files Browse the repository at this point in the history
With this update, TypeScript is now enabled by default for the 'tools' package, along with cleanup for the configuration options.

BREAKING CHANGE: JavaScript projects may not function properly with the tools package.

Related to: #8461
  • Loading branch information
nnaydenow authored Mar 27, 2024
1 parent e9cb499 commit 83ee0cc
Show file tree
Hide file tree
Showing 19 changed files with 42 additions and 161 deletions.
6 changes: 3 additions & 3 deletions packages/base/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const viteConfig = `-c "${require.resolve("@ui5/webcomponents-tools/components-p
const scripts = {
clean: "rimraf src/generated && rimraf dist && rimraf .port",
lint: `eslint .`,
generate: "cross-env UI5_TS=true nps clean integrate copy generateAssetParameters generateVersionInfo generateStyles generateTemplates",
prepare: "cross-env UI5_TS=true nps clean integrate copy generateAssetParameters generateVersionInfo generateStyles generateTemplates typescript integrate.no-remaining-require",
generate: "nps clean integrate copy generateAssetParameters generateVersionInfo generateStyles generateTemplates",
prepare: "nps clean integrate copy generateAssetParameters generateVersionInfo generateStyles generateTemplates typescript integrate.no-remaining-require",
typescript: "tsc -b",
integrate: {
default: "nps integrate.copy-used-modules integrate.amd-to-es6 integrate.third-party",
Expand All @@ -40,7 +40,7 @@ const scripts = {
generateAssetParameters: `node "${assetParametersScript}"`,
generateVersionInfo: `node "${versionScript}"`,
generateStyles: `node "${stylesScript}"`,
generateTemplates: `mkdirp src/generated/templates && cross-env UI5_BASE=true UI5_TS=true node "${LIB}/hbs2ui5/index.js" -d test/elements -o src/generated/templates`,
generateTemplates: `mkdirp src/generated/templates && cross-env UI5_BASE=true node "${LIB}/hbs2ui5/index.js" -d test/elements -o src/generated/templates`,
generateAPI: {
default: "nps generateAPI.generateCEM generateAPI.validateCEM",
generateCEM: `cem analyze --config "${LIB}/cem/custom-elements-manifest.config.mjs" --dev`,
Expand Down
1 change: 0 additions & 1 deletion packages/create-package/template/package-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const getScripts = require("@ui5/webcomponents-tools/components-package/nps.js")

const options = {
port: 8080,
typescript: true,
};

const scripts = getScripts(options);
Expand Down
1 change: 0 additions & 1 deletion packages/fiori/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const options = {
portStep: 2,
dev: true,
fioriPackage: true,
typescript: true,
noWatchTS: true,
illustrationsData: [
{
Expand Down
1 change: 0 additions & 1 deletion packages/icons-business-suite/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const getScripts = require("@ui5/webcomponents-tools/icons-collection/nps.js");
const options = {
collectionName: "SAP-icons-business-suite",
versions: ["v1", "v2"],
typescript: true,
};

const scripts = getScripts(options);
Expand Down
1 change: 0 additions & 1 deletion packages/main/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const getScripts = require("@ui5/webcomponents-tools/components-package/nps.js")
const options = {
port: 8080,
portStep: 2,
typescript: true,
noWatchTS: true,
dev: true,
};
Expand Down
4 changes: 2 additions & 2 deletions packages/theming/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const LIB = path.join(__dirname, `../tools/lib/`);
module.exports = {
scripts: {
clean: "rimraf dist && rimraf src/generated",
generate: `cross-env UI5_TS=true nps build.postcss build.jsonImports`,
generate: "nps build.postcss build.jsonImports",
build: {
default: `cross-env UI5_TS=true nps clean build.src build.postcss build.jsonImports build.typescript generateReport`,
default: "nps clean build.src build.postcss build.jsonImports build.typescript generateReport",
src: `copy-and-watch "src/**/*.{json}" dist/`,
typescript: "tsc",
postcss: `node "${LIB}/css-processors/css-processor-themes.mjs"`,
Expand Down
27 changes: 11 additions & 16 deletions packages/tools/components-package/nps.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,17 @@ const getScripts = (options) => {
// The script creates the "src/generated/js-imports/Illustration.js" file that registers loaders (dynamic JS imports) for each illustration
const createIllustrationsLoadersScript = illustrationsData.map(illustrations => `node ${LIB}/generate-js-imports/illustrations.js ${illustrations.destinationPath} ${illustrations.dynamicImports.outputFile} ${illustrations.set} ${illustrations.collection} ${illustrations.dynamicImports.location} ${illustrations.dynamicImports.filterOut.join(" ")}`).join(" && ");

const tsOption = options.typescript;
const tsCommandOld = tsOption ? "tsc" : "";
let tsWatchCommandStandalone = tsOption ? "tsc --watch" : "";
let tsWatchCommandStandalone = "tsc --watch";
// this command is only used for standalone projects. monorepo projects get their watch from vite, so opt-out here
if (options.noWatchTS) {
tsWatchCommandStandalone = "";
}
const tsCrossEnv = tsOption ? "cross-env UI5_TS=true" : "";

if (tsOption) {
try {
require("typescript");
} catch(e) {
console.error(`TypeScript is not found. Try to install it by running \`npm install --save-dev typescript\` if you are using npm or by running \`yarn add --dev typescript\` if you are using yarn.`);
process.exit(e.code);
}
try {
require("typescript");
} catch(e) {
console.error(`TypeScript is not found. Try to install it by running \`npm install --save-dev typescript\` if you are using npm or by running \`yarn add --dev typescript\` if you are using yarn.`);
process.exit(e.code);
}

let viteConfig;
Expand Down Expand Up @@ -56,19 +51,19 @@ const getScripts = (options) => {
lint: `eslint . ${eslintConfig}`,
lintfix: `eslint . ${eslintConfig} --fix`,
generate: {
default: `${tsCrossEnv} nps prepare.all`,
default: "nps prepare.all",
all: 'concurrently "nps build.templates" "nps build.i18n" "nps prepare.styleRelated" "nps copy" "nps build.illustrations"',
styleRelated: "nps build.styles build.jsonImports build.jsImports",
},
prepare: {
default: `${tsCrossEnv} nps clean prepare.all copy prepare.typescript generateAPI`,
default: "nps clean prepare.all copy prepare.typescript generateAPI",
all: 'concurrently "nps build.templates" "nps build.i18n" "nps prepare.styleRelated" "nps build.illustrations"',
styleRelated: "nps build.styles build.jsonImports build.jsImports",
typescript: tsCommandOld,
typescript: "tsc",
},
build: {
default: "nps prepare lint build.bundle", // build.bundle2
templates: `mkdirp src/generated/templates && ${tsCrossEnv} node "${LIB}/hbs2ui5/index.js" -d src/ -o src/generated/templates`,
templates: `mkdirp src/generated/templates && node "${LIB}/hbs2ui5/index.js" -d src/ -o src/generated/templates`,
styles: {
default: `concurrently "nps build.styles.themes" "nps build.styles.components" "nps build.styles.componentStyles"`,
themes: `node "${LIB}/css-processors/css-processor-themes.mjs"`,
Expand Down Expand Up @@ -100,7 +95,7 @@ const getScripts = (options) => {
props: `node "${LIB}/copy-and-watch/index.js" --silent "src/**/*.properties" dist/`,
},
watch: {
default: `${tsCrossEnv} concurrently "nps watch.templates" "nps watch.typescript" "nps watch.api" "nps watch.src" "nps watch.styles" "nps watch.i18n" "nps watch.props"`,
default: `concurrently "nps watch.templates" "nps watch.typescript" "nps watch.api" "nps watch.src" "nps watch.styles" "nps watch.i18n" "nps watch.props"`,
devServer: 'concurrently "nps watch.default" "nps watch.bundle"',
src: 'nps "copy.src --watch --safe --skip-initial-copy"',
typescript: tsWatchCommandStandalone,
Expand Down
8 changes: 3 additions & 5 deletions packages/tools/icons-collection/nps.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,14 @@ const copyIconAssetsCommand = (options) => {
const getScripts = (options) => {
const createJSImportsCmd = createIconImportsCommand(options);
const copyAssetsCmd = copyIconAssetsCommand(options);
const tsCommand = options.typescript ? "tsc --build" : "";
const tsCrossEnv = options.typescript ? "cross-env UI5_TS=true" : "";

const scripts = {
clean: "rimraf dist && rimraf src/generated",
copy: copyAssetsCmd,
generate: `${tsCrossEnv} nps clean copy build.i18n build.icons build.jsonImports copyjson`,
generate: "nps clean copy build.i18n build.icons build.jsonImports copyjson",
copyjson: "copy-and-watch \"src/generated/**/*.json\" dist/generated/",
build: {
default: `${tsCrossEnv} nps clean copy build.i18n typescript build.icons build.jsonImports`,
default: "nps clean copy build.i18n typescript build.icons build.jsonImports",
i18n: {
default: "nps build.i18n.defaultsjs build.i18n.json",
defaultsjs: `mkdirp dist/generated/i18n && node "${LIB}/i18n/defaults.js" src/i18n src/generated/i18n`,
Expand All @@ -62,7 +60,7 @@ const getScripts = (options) => {
},
icons: createJSImportsCmd,
},
typescript: tsCommand,
typescript: "tsc --build",
};

return scripts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import chokidar from "chokidar";
import scopeVariables from "./scope-variables.mjs";
import { writeFileIfChanged, getFileContent } from "./shared.mjs";

const tsMode = process.env.UI5_TS === "true";
const extension = tsMode ? ".css.ts" : ".css.js";

const packageJSON = JSON.parse(fs.readFileSync("./package.json"))
const inputFilesGlob = "src/themes/*.css";
const restArgs = process.argv.slice(2);
Expand All @@ -27,8 +24,8 @@ let customPlugin = {
writeFile(f.path, newText);

// JS/TS
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", extension);
const jsContent = getFileContent(tsMode, jsPath, packageJSON.name, "\`" + newText + "\`", true);
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", ".css.ts");
const jsContent = getFileContent(jsPath, packageJSON.name, "\`" + newText + "\`", true);
writeFileIfChanged(jsPath, jsContent);
});
})
Expand Down
7 changes: 2 additions & 5 deletions packages/tools/lib/css-processors/css-processor-themes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import combineDuplicatedSelectors from "../postcss-combine-duplicated-selectors/
import { writeFileIfChanged, stripThemingBaseContent, getFileContent } from "./shared.mjs";
import scopeVariables from "./scope-variables.mjs";

const tsMode = process.env.UI5_TS === "true";
const extension = tsMode ? ".css.ts" : ".css.js";

const packageJSON = JSON.parse(fs.readFileSync("./package.json"))

let inputFiles = await globby("src/**/parameters-bundle.css");
Expand Down Expand Up @@ -50,8 +47,8 @@ let scopingPlugin = {
writeFileIfChanged(jsonPath, JSON.stringify({_: data}));

// JS/TS
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", extension);
const jsContent = getFileContent(tsMode, jsPath, packageJSON.name, "\`" + newText + "\`");
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", ".css.ts");
const jsContent = getFileContent(jsPath, packageJSON.name, "\`" + newText + "\`");
writeFileIfChanged(jsPath, jsContent);
});
})
Expand Down
16 changes: 1 addition & 15 deletions packages/tools/lib/css-processors/shared.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,7 @@ registerThemePropertiesLoader("${packageName}", "${DEFAULT_THEME}", async () =>
`;
};

const getFileContent = (tsMode, targetFile, packageName, css, includeDefaultTheme) => {
if (tsMode) {
return getTSContent(targetFile, packageName, css, includeDefaultTheme);
}

return getJSContent(targetFile, packageName, css, includeDefaultTheme);
}

const getTSContent = (targetFile, packageName, css, includeDefaultTheme) => {
const getFileContent = (targetFile, packageName, css, includeDefaultTheme) => {
const typeImport = "import type { StyleData } from \"@ui5/webcomponents-base/dist/types.js\";"
const defaultTheme = includeDefaultTheme ? getDefaultThemeCode(packageName) : "";

Expand All @@ -67,10 +59,4 @@ export default styleData;
`;
}

const getJSContent = (targetFile, packageName, css, includeDefaultTheme) => {
const defaultTheme = includeDefaultTheme ? getDefaultThemeCode(packageName) : "";

return `${defaultTheme}export default {packageName:"${packageName}",fileName:"${targetFile.substr(targetFile.lastIndexOf("themes"))}",content:${css}}`
}

export { writeFileIfChanged, stripThemingBaseContent, getFileContent}
41 changes: 3 additions & 38 deletions packages/tools/lib/generate-json-imports/i18n.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
const fs = require("fs").promises;
const path = require('path');

const isTypeScript = process.env.UI5_TS;
const ext = isTypeScript ? 'ts' : 'js';

const generate = async () => {

const packageName = JSON.parse(await fs.readFile("package.json")).name;

const inputFolder = path.normalize(process.argv[2]);
const outputFile = path.normalize(`${process.argv[3]}/i18n-static.${ext}`);
const outputFileDynamic = path.normalize(`${process.argv[3]}/i18n.${ext}`);
const outputFileDynamic = path.normalize(`${process.argv[3]}/i18n.ts`);

// All languages present in the file system
const files = await fs.readdir(inputFolder);
Expand All @@ -19,46 +15,16 @@ const generate = async () => {
return matches ? matches[1] : undefined;
}).filter(key => !!key);

let contentStatic, contentDynamic;
let contentDynamic;

// No i18n - just import dependencies, if any
if (languages.length === 0) {
contentStatic = "";
contentDynamic = "";
// There is i18n - generate the full file
} else {
// Keys for the array
const languagesKeysString = languages.map(key => `"${key}": _${key},`).join("\n\t");
const languagesKeysStringArray = languages.map(key => `"${key}",`).join("\n\t");

// Actual imports for json assets
const assetsImportsString = languages.map(key => `import _${key} from "../assets/i18n/messagebundle_${key}.json";`).join("\n");

// static imports
contentStatic = `// @ts-nocheck
import { registerI18nLoader } from "@ui5/webcomponents-base/dist/asset-registries/i18n.js";
${assetsImportsString}
const bundleMap = {
${languagesKeysString}
};
const fetchMessageBundle = async (localeId) => {
if (typeof bundleMap[localeId] === "object") {
// inlined from build
throw new Error("[i18n] Inlined JSON not supported with static imports of assets. Use dynamic imports of assets or configure JSON imports as URLs")
}
return (await fetch(bundleMap[localeId])).json()
}
const localeIds = [${languagesKeysStringArray}];
localeIds.forEach(localeId => {
registerI18nLoader("${packageName}", localeId, fetchMessageBundle);
});
`;

// Actual imports for json assets
const dynamicImportsString = languages.map(key => ` case "${key}": return (await import(/* webpackChunkName: "${packageName.replace("@", "").replace("/", "-")}-messagebundle-${key}" */ "../assets/i18n/messagebundle_${key}.json")).default;`).join("\n");

Expand Down Expand Up @@ -91,9 +57,8 @@ import { registerI18nLoader } from "@ui5/webcomponents-base/dist/asset-registrie

}

await fs.mkdir(path.dirname(outputFile), { recursive: true });
await fs.mkdir(path.dirname(outputFileDynamic), { recursive: true });
return Promise.all([
fs.writeFile(outputFile, contentStatic),
fs.writeFile(outputFileDynamic, contentDynamic),
]);
}
Expand Down
34 changes: 2 additions & 32 deletions packages/tools/lib/generate-json-imports/themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ const fs = require("fs").promises;
const path = require('path');
const assets = require("../../assets-meta.js");

const isTypeScript = process.env.UI5_TS;
const ext = isTypeScript ? 'ts' : 'js';

const generate = async () => {
const inputFolder = path.normalize(process.argv[2]);
const outputFile = path.normalize(`${process.argv[3]}/Themes-static.${ext}`);
const outputFileDynamic = path.normalize(`${process.argv[3]}/Themes.${ext}`);
const outputFileDynamic = path.normalize(`${process.argv[3]}/Themes.ts`);

// All supported optional themes
const allThemes = assets.themes.all;
Expand All @@ -22,34 +18,9 @@ const generate = async () => {

const packageName = JSON.parse(await fs.readFile("package.json")).name;

const importLines = themesOnFileSystem.map(theme => `import ${theme} from "../assets/themes/${theme}/parameters-bundle.css.json";`).join("\n");
const themeUrlsByName = "{\n" + themesOnFileSystem.join(",\n") + "\n}";
const availableThemesArray = `[${themesOnFileSystem.map(theme => `"${theme}"`).join(", ")}]`;
const dynamicImportLines = themesOnFileSystem.map(theme => `\t\tcase "${theme}": return (await import(/* webpackChunkName: "${packageName.replace("@", "").replace("/", "-")}-${theme.replace("_", "-")}-parameters-bundle" */"../assets/themes/${theme}/parameters-bundle.css.json")).default;`).join("\n");


// static imports file content
const contentStatic = `// @ts-nocheck
import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
${importLines}
const themeUrlsByName = ${themeUrlsByName};
const isInlined = obj => typeof (obj) === "object";
const loadThemeProperties = async (themeName) => {
if (typeof themeUrlsByName[themeName] === "object") {
// inlined from build
throw new Error("[themes] Inlined JSON not supported with static imports of assets. Use dynamic imports of assets or configure JSON imports as URLs");
}
return (await fetch(themeUrlsByName[themeName])).json();
};
${availableThemesArray}
.forEach(themeName => registerThemePropertiesLoader("${packageName}", themeName, loadThemeProperties));
`;


// dynamic imports file content
const contentDynamic = `// @ts-nocheck
import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
Expand All @@ -73,9 +44,8 @@ ${availableThemesArray}
.forEach(themeName => registerThemePropertiesLoader("${packageName}", themeName, loadAndCheck));
`;

await fs.mkdir(path.dirname(outputFile), { recursive: true });
await fs.mkdir(path.dirname(outputFileDynamic), { recursive: true });
return Promise.all([
fs.writeFile(outputFile, contentStatic),
fs.writeFile(outputFileDynamic, contentDynamic)
]);
};
Expand Down
4 changes: 1 addition & 3 deletions packages/tools/lib/hbs2lit/src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ const hbs2lit = async (file, componentName) => {

sPreprocessed = removeWhiteSpaces(sPreprocessed);

const blockSignature = process.env.UI5_TS ? `this: ${componentName}` : ""

// icons hack
if (sPreprocessed.startsWith("<g ") || sPreprocessed.startsWith("<g>")) {
return `
function block0 (${blockSignature}) {
function block0 (this: ${componentName}) {
return svg\`${sPreprocessed}\`
}`;
}
Expand Down
Loading

0 comments on commit 83ee0cc

Please sign in to comment.