Introduction to npm, npx, NodeJS and React

This page introduces npm, webpack, jest and NodeJS to a Lino developer who wants to help improving the React front end. Lino’s React front end is made using these tools.

The tools

  • React is a “library for web and native user interfaces”.

  • Node.js is a cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.

  • npm is a software package manager originally developed for JavaScript packages to be run with Node.js, but also used for other programming languages. It is an interface to the npm repository. It allows JavaScript developers to share packages quickly and easily. It is also a build tool. npx is the Node package runner.

  • webpack is a static module bundler for modern JavaScript applications.

  • electron is “an all-in-one tool for packaging and distributing Electron applications. It combines many single-purpose packages to create a full build pipeline that works out of the box, complete with code signing, installers, and artifact publishing.”

  • Babel is a JavaScript compiler.

  • TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.

  • Jest is a JavaScript testing framework.

External resources

Introductions to npm:

Introductions to Webpack:

Introductions to React and JSX:

Creating your own packages

npm packages must contain at least a file named package.json, which must exist in their top-level directory. This file can be generated by npm init and later edited manually. But there is a tool that creates a whole package with a working react app, including a package.json:

$ npx create-react-app myapp

It is an npm package, but it isn’t

The React front end for Lino repository is an npm package because it has a package.json file, but we don’t publish it on the npm repository. That’s not needed because everything needed to run a Lino site with the React front end is made available as Django static files inside the Python package (published on PyPI as lino-react). The whole source code is published on GitLab. You need npm and node only for developing Lino’s React front end, not for using it.

React framework

Lino’s React front end is built on top of React framework. We write React compatible code and webpack as a bundler knows how to bundle codes in the node_modules/ dir and our own application code into a single source. The minified (by webpack) components of the main[.hash].js file is not understandable, yet it contains code from node_modules/react/* and our own application code. And essentially Lino’s React front end is a React application.

https://react.dev/learn/start-a-new-react-project

Lino React files reference

package.json

Any project that uses Node.js needs to have a package.json file.

The package.json of an npm project lists the packages it depends on, contains information about its unique source control and specific metadata like the project’s name, description, and author.

The npm package description for lino_react.

The package.json for lino_react mainly defines a few “scripts” (i.e. commands):

"scripts": {
    "debug": "NODE_OPTIONS='--max-old-space-size=8192' webpack --mode none ",
    "watch": "NODE_OPTIONS='--max-old-space-size=8192' webpack --watch",
    "dev": "NODE_OPTIONS='--max-old-space-size=8192' webpack --mode development",
    "build": "NODE_OPTIONS='--max-old-space-size=8192' webpack --mode production",
    "test": "jest",
    "ntest": "jest --runTestsByPath",
    "mm": "node lino_react/translations/i18n-scan.js"
},

The commands debug, dev and build create the main.js file. They are very similar, their only difference is the –mode option, which tells webpack to use its built-in optimizations accordingly.

test & ntest commands are used for testing the javascript functionality. See usage example.

The mm command is used to extract translatable strings from the static source file made from the dev command.

webpack is a tool that bundles all the “assets” into a set of deployable files (.js, .css etc). We use it to bundle the react app into the minified main.js file.

webpack.config.js

Our configuration file for webpack to efficiently bundle the React app into a minified javascript source file.

react/main.js

A generated file is in lino_react/react/static

It contains a lot of generated and compressed JS code.

It is quite big and therefore causes webpack to issue a warning:

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
  main.js (1.24 MiB)
jest-puppeteer.config.js

Contains configuration options for jest-puppeteer test runtime.

forge.config.js

Contains configuration options for electronforge.

package-lock.json

Contains a complete description of the npm packages installed and are referenced from the node_modules/ directory.

node_modules/

This is the directory where all the external npm packages such as React are put by npm itself.

Troubleshoot issues with Node.js and npm

How to see which version you have:

$ npm -v
10.8.2
$ node -v
v20.17.0

Some issues might be caused by version conflicts caused by earlier installation attempts on your machine. Here is how to restart from scratch:

$ go react
$ rm -rf node_modules
$ rm package-lock.json
$ npm install

Not sure when this is useful:

$ npm cache clean --force

Seems that it’s important to do the following setting:

npm config set legacy-peer-deps true

(I had issues with dependencies, found this discussion on SO and after setting it my issues were gone)

Site data

site data

The state attribute of the App() object (defined in App.jsx) has a key site_data.

JS code can say e.g. if (this.state.site_data.use_push_api) ....