What's new in version 3

WinnetouJs has shifted its primary focus toward exceptional speed and top-notch performance. By meticulously removing all unnecessary features, the framework now produces extremely lightweight bundles, significantly reducing their size. Additionally, the compilation process has become astonishingly fast, ensuring developers experience rapid, efficient builds and smoother workflows.

Main changes

Now, constructos and WinnetouJs functions are tree-shakable which means that you only will compile to final bundle what you really use.

WinnetouJs Modules

Winnetou was divided in modules in order to user can import only what is important for project. Modules are:

  • colorThemes
  • router
  • select
  • style
  • translations

To use modules, import methods like:

import { Router } from "winnetoujs/modules/router";

ESBuild Engine

We have replaced Webpack in order to use esbuild.

Sass

We have discontinued the embedded compilation of sass. But we encourage you to keep use sass in winnetou projects. The best way to do it is:

    "sass:app:dev": "sass --style expanded --watch --embed-sources sass/app.scss:../../Public/reports/dist/css/app.css --load-path='./_constructos'",
    "sass:login:dev": "sass --embed-sources --watch --style expanded sass/login.scss:../../Public/reports/dist/css/login.css  --load-path='./_constructos'",
    "sass:app:prod": "sass sass/app.scss:../../Public/reports/dist/css/app.css --style compressed --no-source-map --quiet  --load-path='./_constructos'",
    "sass:login:prod": "sass sass/login.scss:../../Public/reports/dist/css/login.css --style compressed --no-source-map --quiet  --load-path='./_constructos'"

Note the use of --load-path attribute. It ensure that watch files will recompile your css even you edit scss inside constructos folders:

@use "./test.scss";
@use "app/mainFrame/mainFrame";

In ./_constructos/app/mainFrame folder create a _mainFrame.scss file. When import it to entry scss file, just use app/mainFrame/mainFrame statement.

In this way you can keep your scss file around wcto.html constructos files, increase readability and navigation.

VDOM

VDOM is completely removed from WinnetouJs.

Color Themes

Now must be called on app startup

WStyle Philosophy

It's not a WinnetouJs feature, it's a javascript methodology.

import { wstyle } from "winnetoujs/modules/style";
export const leftMenu = wstyle({
  width: "100%",
  height: "50px",
  color: "white",
  "border-radius": "5px",
  display: "flex",
  "align-items": "center",
  "justify-content": "center",
  cursor: "pointer",
  "font-size": "16px",
  "text-transform": "uppercase",
});

And then put the style in style class of constructo:

import { leftMenu } from "./styles";
new $leftMenu({
  onclick: "",
  style: leftMenu,
  text: strings.endpoints,
}).create(this.output);

Be careful, Winnetou Styles can increase the final bundle size, use wisely.

Typescript

Now WinnetouJS works with typescript.

Translations

Now the original language file must be a js/ts file and not a json one. This ensure that use can use Go To Reference between strings and code, without the need to use extensions.

import { W } from "winnetoujs";
export default W.strings = {
  title: "Hello Strings!",
  buttonText: "Change Lang",
  buttonText2: "Original Lang",
};

In this new way user can use f12 to go directly to
string and apply changes and wbr has one less
calculation to do. And reverse f12 works as well.

Now updateTranslations has a new calling method (note that translationPublicPath is declared directly within the method, not in win.config.json):

import { updateTranslations } from "winnetoujs/modules/translations";
import strings from "./en-us";

updateTranslations({
  stringsClass: strings,
  translationsPublicPath: "/reports/translations",
}).then(() => {
  startApp();
});

async function startApp() {
  console.log(strings.title);
}

Inside /translationsFiles folder, put the json translations files as usual. Do not put original language json file in translationsPublicPath in
order to clear localStorage and load strings from
winnetou.js it self. It's more efficient.

Icons

Do not digest icons anymore. Icons libraries has their own integration methods which is most of the time the fasted way and also makes the final winnetou bundle lighter.

We recommend you to use lucide npm package.

import { createElement, Menu } from "lucide";
const menuIcon = createElement(Menu).outerHTML;
// ...
new $menuItem({
  text: strings.home,
  icon: menuIcon,
  chevron: "",
}).create(output);

Plugins

Now must provide compiled constructos js files because wbr doesn't search node_modules anymore.

Constructos

WinnetouJs now uses folder paradigm, which provides a better readability for large projects. It mean that wbr will transpile constructos directly in the folder where placed wcto.html file.

Now constructos must be initialized with new token and contains a $ token to identify it.

async function startApp() {
  new $div({ content: "test" }).create("#app");
}

Constructos props

Now winnetoujs has more prop options

{{?display(set visibility of constructo):"flex"|"none"}}

{{text?:string}}

Use : to create types for props.

Use () to write prop description.

Use ? to set prop as optional.

Files Naming

WinnetouJs now use wcto to identify their own files. It mean that constructor must have wcto.html extension and output files will have wcto.js extension. It allows you to configure excludes patterns in your code editor easily.

In Visual Studio Code use search.exclude to not show transpile constructos files in search bar:

"search.exclude": {
    "**/node_modules": true,
    "**/bower_components": true,
    "**/*.code-search": true,
    "**/*.wcto.js": true
}

Router

This is a new router paradigm, that allow user to use go to reference:

import { Router } from "winnetoujs/modules/router";
import { Settings } from "../constructos/settings/settings";

class MyRouter_ {
  constructor() {
    this.createRoutes();
  }
  /** @private */
  routes = {};

  methods = {
    settings: {
      go: () => Router.navigate("/settings"),
      set: () => {
        this.routes["/settings"] = () => {
          new Settings("right-win-base").render();
        };
      },
    },
  };

  /** @private */
  createRoutes() {
    Object.keys(this.methods).forEach(key => {
      this.methods[key].set();
    });
    Router.createRoutes(this.routes);
  }
}

export const MyRouter = new MyRouter_();

WBR

WBR hasn't transpile method anymore. It'll always compile bundle because esbuild is ultra fast.
Args has this settings:

program
  .name("wbr")
  .description("Winnetou Bundle Runtime (WBR) - Version 3")
  .version("3.0.0")
  .option("-w, --watch", "Watch mode")
  .option("-b,--bundleRelease", "Compile project")
  .option("-p, --production", "Production mode")
  .option("-v, --verbose", "Verbose output")
  .parse();

win.config.json

WinnetouJs setting file is extremely simpler.

{
  "apps": ["./src/ts/app.ts"],
  "outputDir": "./dist/js",
  "constructosSourceFolder": "./src/constructos"
}

Sass integration

We recommend you to use sass. Create this scripts in your package.json:


"scripts": {
    "wbr:prod": "node wbr -b -p",
    "wbr:dev": "node wbr -b -v --watch",
    "sass:app:dev": "sass --style expanded --watch --embed-sources sass/app.scss:../../Public/reports/dist/css/app.css",
    "sass:login:dev": "sass --embed-sources --watch --style expanded sass/login.scss:../../Public/reports/dist/css/login.css",
    "sass:app:prod": "sass sass/app.scss:../../Public/reports/dist/css/app.css --style compressed --no-source-map --quiet",
    "sass:login:prod": "sass sass/login.scss:../../Public/reports/dist/css/login.css --style compressed --no-source-map --quiet"
},

Script type="module"

Esbuild output use esm module imports, so you need to use type="module" when add script tag.

Clear output bundles

Clear output is discontinued, if you need a clean compilation, first delete dist folder

NPX Template

We have created a npx template to create winnetou projects easily.

npx create-winnetou-app my-awesome-app
cd my-awesome-app
npm install
npm run serve

Then open http://localhost:3123 to see your app.