Boiled down: packages, npm, webpack, babel, task runner
Tags: javascript, webdev, beginners, learning
Published: 2024-05-07 13:34:07

## Packages

JavaScript packages are pieces of code that has been made available to be used by more than one person or group. If you needed a password-hashing program, you may be able to leverage a package called [bcrypt](https://www.npmjs.com/package/bcrypt), instead of creating it from scratch yourself. This helps you save time and stops people from reinventing the wheel all the time.

## npm

[npm](https://docs.npmjs.com/about-npm) is a software registry and package manager. You can use npm to discover packages and to install them in your project.

npm consists of three distinct components:

- the website: used to discover packages and to manage profiles
- the CLI: developers can interact with npm through the CLI tool
- the registry: a large public database of JavaScript software and the meta-information surrounding it

### Why use npm? 

Package managers help automate tedious tasks such as navigating to package websites to download and move packages into your projects. 

Imagine you have a project you want to share with others, but it has many large packages that can slow down the data transfer process. With npm, you can specify your packages or "dependencies" in a configuration file (called `package.json`) and share that file instead. Using `package.json`, others will know exactly which packages and which version your project uses.

## webpack

Most programming languages provide a way to import code from one file to another, but JavaScript is not inherently able to do so. For security reasons, browsers cannot go into the server's file system to search for modules to use, therefore, we need to load the entire module file into a variable that'll be shared globally.

That looks like this (moment.js being the package):
```
<script src="node_modules/moment/min/moment.min.js"></script>
<script src="index.js"></script>
```

Instead, we can use webpack (also an npm package), a JavaScript module bundler. Popularized by React, webpack allows you to use the `require` syntax from node.js to import modules.

Running the following command installs webpack and the webpack CLI:
```
$ npm install webpack webpack-cli --save-dev
```
`--save-dev` saves your packages as a development environment dependency, which will be reflected in the `package.json` file.

Now, running the following command turns your `require` statements into legitimate JavaScript code that will have pulled the content from the required file(s):
```
$ ./node_modules/.bin/webpack index.js --mode=development
```

It will create a single output file `dist/main.js` which is what we use in our HTML file instead of `index.js`:
```
<script src="dist/main.js"></script>
```

Every time we make a change to `index.js`, we will need to run the webpack command, but this time, webpack has saved our "entry file" (`index.js`) and our "mode" in the file `webpack.config.js`. So, now we run:
```
$ ./node_modules/.bin/webpack
```

Bundling saves us time in not having to load external scripts via global variables, using `require` in JavaScript instead of adding `<script>` tags in HTML, and better performance.

## babel

Babel is a transpiler which converts modern JavaScript into a backwards compatible version for old environments (browsers, platforms, legacy code bases).

We can use the ES2015 `import` statement instead of `require` for loading modules, which is the more common way today. Most modern browsers support ES2015, so it's hard to tell if babel helped, but if you had some ancient browser, you'd be able to find our code has been transpiled.

## task runner

Using npm's built-in scripting capabilities, we can write some npm scripts to make using webpack easier. We can do so by editing `package.json`:

```
"script": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "build": "webpack --progress --mode=production",
  "watch": "webpack --progress --watch"
}
```

Running `npm run build` will run webpack while showing percent progress (--progress), and minimizing the code for production (--mode=production).

Running `npm run watch` will automatically re-run webpack each time any JavaScript file changes.

npm knows the location of each npm module path, which is why we don't specify the full path for webpack: `./node_modules/.bin/webpack`.

We can get another tool that provides a simple web server for live reloading:
```
$ npm install webpack-dev-server --save-dev
```

Then add an npm script to `package.json`:
```
"serve": "webpack-dev-server --open"
```

Now, you can run `npm run serve` to automatically open `index.html` that will rebuild its own bundled JavaScript and refresh the browser automatically.

## Conclusion

There are a lot of tools being used here to make web development simpler, but arguably these tools are also overwhelming to use initially.

Many popular frameworks leverage these tools to make the development process less painful by creating everything mentioned here for you. For example, React's create-react-app or Vues' vue-cli will set up all this stuff for you.