Hi all,
I found some interesting Webpack features so I'd like to share them.
Excluding Code
==============
Sometimes it is useful to behave a bit different in a development build and in the
production build. For example you might add some extra debugging in development mode
or you might use some development library which does not make sense in production.
For example the patternfly-react-seed project[1] which is a template project
for the PatternFly library uses the "axe" accessibility testing engine [2]. Of
course, reporting the potential accessibility issues only makes sense for developers
in the development builds.
You can do that with code like:
```
if (process.env.NODE_ENV !== "production") {
const axe = require("@axe-core/react");
axe(React, ReactDOM, 1000);
}
```
That looks pretty straightforward isn't it?
But it is actually quite tricky because 1) you cannot access the environment from
browser Javascript, 2) even if that worked it's running on a completely different
machine.
So how it works actually??
The trick is that Webpack replaces (!) the "process.env.NODE_ENV" coode in the source
code with the current value when processing it. So what the browser actually sees in
the development mode is:
```
if ("development" !== "production") {
const axe = require("@axe-core/react");
axe(React, ReactDOM, 1000);
}
```
And that condition is always true so that code always runs.
In the production mode it would be:
```
if ("production" !== "production") {
import { foo } from "foo";
foo.bar();
}
```
So that would never run.
But the production builds usually use extra minification and optimization step. The
minifier is quite clever and for example it removes the always false conditions from
the code completely.
So the final minified production code is reduced to:
```
```
Yes, nothing! :-)
By default it works only for the "NODE_ENV" variable but you can add support for any
other environment variable using the Webpack EnvironmentPlugin, see [3].
Replacing Values
================
This is similar to the previous case, but instead of replacing an environment
variables you can replace any value at the compile time.
For example you want to somewhere display the project version or the last git commit
hash or the build date or... (Um, the build date is actually a bad idea, that would
break reproducible package builds in OBS.)
Weback has DefinePlugin for that, see the documentation [4].
If you want to replace a string then it must be quoted because the value is replaced
literally. A common trick is to use JSON.stringify(string). On the other hand that
allows the replacement to be any expression, even some code to execute.
The ESlint step is called *before* these string replacements so it sees the original
code. And that means it would complain about undefined variables. The workaround is
to define it as a known global in the .eslintrc.json configuration file [5].
HTH, Ladislav
[1] https://github.com/patternfly/patternfly-react-seed
[2] https://github.com/dequelabs/axe-core
[3] https://webpack.js.org/plugins/environment-plugin/
[4] https://webpack.js.org/plugins/define-plugin/
[5] https://eslint.org/docs/latest/use/configure/language-options#specifying-gl…
--
Ladislav Slezák
YaST Developer
SUSE LINUX, s.r.o.
Corso IIa
Křižíkova 148/34
18600 Praha 8
Maximum column width seems needed to address.
On /every/ return to partition list screen after editing a partition, the column
heading widths are reset to defaults instead of applying those selected before the
first edit/add/delete. When an nvme type name is stupid lengthy, it can push the
Label column so far right that it is inadequately visible, and make the Mount
Point column completely invisible.
In this case, the Enc column appears to be centered on the XVideo=1440x900,108
screen, the problem exacerbated to start with by md devices making the Device
column unusually wide, with the Type column extending to within 5.5 characters of
the scrollbar, the 5.5 being all there is to see of the Label column. NVME name:
pci 0x1987 Phison Electronics Corporation-Phison Electronics PS5013 E13 NVMe
Controller.
Also, the format column has enough width to fit the string Format, yet only an F
appears there. The encrypt column is even wider, but only shows Enc.
https://paste.opensuse.org/pastes/094de981b806 (mislabeled) actual before
https://paste.opensuse.org/pastes/115e64f68ea4 (mislabeled) actual after
NICE TO HAVE:
In partitioner summary screen there is loads of whitespace. It would be nice to
see the changes to partitioning list items by mount method instead of or in
addition to device name, and sorted by disk location
--
Evolution as taught in public schools is, like religion,
based on faith, not based on science.
Team OS/2 ** Reg. Linux User #211409 ** a11y rocks!
Felix Miata
Hi all,
We have released a new version of D-Installer which, among other
things, includes:
* Many UI fixes and improvements, including a hamburger menu.
* Validation and error reporting of the software proposal.
* Browsing and downloading of YaST2 logs.
* Use of our a dedicated bus apart from the system one.
You can find the full announcement including all the changes in our
blog:
https://yast.opensuse.org/blog/2023-02-16/announcing-d-installer-0-7
Regards,
Imo
--
Imobach González Sosa
SUSE Linux LLC
Hi all!
I am pleased to announce that Hot Module Replacement[1] has now
available in D-Installer[2]. Thus, working on the web UI should be a
bit more productive now, saving you a few clicks to get it up-to-date
after writing changes to a file.
Just use `npm run server` instead of `npm run watch`.
Hope you find it useful!
Regards.
[1] https://webpack.js.org/concepts/hot-module-replacement/
[2] https://github.com/yast/d-installer/pull/419
--
David Díaz
YaST Team at SUSE LINUX GmbH
IRC: dgdavid
Hello!
This Hack Week I rewrote my experimental y2log viewer from a plain
Javascript and CSS to React and PatternFly. The original implementation
was ugly (a single JS file with bunch of random functions directly
manipulating DOM) and was difficult to maintain.
And I also wanted to learn React more because of the D-Installer :-)
What I learned:
- React is a nice framework which helps to split your project into small reusable
components. The start was quite difficult for me as the concept is completely
different, it uses own JSX syntax, etc... But in the end I like React programming!
- PatternFly is a complex set of basic components with good documentation
and a lot of examples. I suggest to start a new project using their template
repository https://github.com/patternfly/patternfly-react-seed
If you want to try the new version just go to:
https://lslezak.github.io/ylogviewer2/
There are some example logs to see how it works,
see the links at
https://github.com/lslezak/ylogviewer2#examples
Just press the "Load URL" button after opening a link.
I even opened a PR for the D-Installer to improve displaying the y2log
using the components from this Hack Week project:
https://github.com/yast/d-installer/pull/417
Enjoy!
--
Ladislav Slezák
YaST Developer
SUSE LINUX, s.r.o.
Corso IIa
Křižíkova 148/34
18600 Praha 8
Hi all,
As a Hack Week project, Josef and I started to work on a Rust-based
command line interface[1] for D-Installer. My primary purpose was to
determine whether it is a good language for building this tool.
Moreover, I wanted to put my (limited) knowledge of the language into
practice.
TL;DR; the experience was really positive. Although it is far from
finished, we managed to build a minimal CLI that allows setting/getting
configuration values (using YAML and JSON as output formats). You can
find more details in the Running section[2] of the README.
Now, I will comment on some aspects that I found interesting. I hope
you enjoy the reading :-)
# The main obstacle
Funny enough, the main "problem" we found was unrelated to Rust. It
was, instead, the gap between our new CLI design (+ the auto-
installation specification) and the D-Bus API. To fill the gap, we
decided to keep an in-memory representation of D-Installer's settings
(see the Settings and related structs[3]) and implement a separate
mechanism to read/write those settings (see the Store struct[4]).
# Procedural macros
We found out that to set or get those configuration values, we needed
to determine the name of the method/function to call at runtime. That's
trivial with Ruby, but not with Rust without writing one line per each
possible function. So we implemented a proc-macro[5] that generates the
code for us. Beware that these macros are different to C/C++ ones and,
among other things, they are written in Rust and give you access to the
AST.
# Abstraction level
Rust cannot offer the same abstraction level as Ruby, period. But it
has an expressive type system and powerful tools for meta-programming
if needed. So when writing this CLI, I felt quite comfortable with the
level of abstraction.
# Error messages are helpful
Most of the time, compiler error messages make sense. Apart from an
explanation, it usually gives you some hints to solve the issues.
However, if the error implies lifetimes, generics and so on, it can be
hard to understand what is happening behind the scenes.
# Extensive documentation
Apart from "the book"[6], the standard library documentation is
rather complete. However, it can be intimidating if you do not know the
basis.
# Closing thoughts
As said before, the experience was really positive and I enjoyed a lot
working on this project. There were a few things that we wanted to try,
like calling Rust code from Ruby or using the async support, but we ran
out of time.
My main question now is: should we use this as the base for our D-
Installer CLI or should we go back to our Ruby-based implementation?
Regards,
Imo
[1] https://hackweek.opensuse.org/22/projects/rewrite-the-d-installer
[2] https://github.com/imobachgs/dinstaller-rs#running
[3]
https://github.com/imobachgs/dinstaller-rs/blob/update-readme/dinstaller-li…
[4]
https://github.com/imobachgs/dinstaller-rs/blob/update-readme/dinstaller-li…
[5]
https://github.com/imobachgs/dinstaller-rs/blob/update-readme/dinstaller-de…
[6] https://doc.rust-lang.org/book/
[7] https://www.rust-lang.org/tools
--
Imobach González Sosa
SUSE Linux LLC