# How to use
Tooling requirements
The basic use requirements:
* [NodeJS version 22+](https://nodejs.org/)
* NPM
> There appear to be dependency mapping issues with `Yarn` v1.x.x lock files, `Typescript` and `webpack`, and specific dependencies
> using ES modules. If you do decide to use [Yarn](https://yarnpkg.com) use the latest version.
Set up a project
`weldable` makes assumptions on project structure in order to be up and moving. Many of these assumptions can be
overridden, or ignored, to fit your own preferences.
Assumptions `weldable` presets...
- `src` project directory, `Your project -> src -> your work`
- `index.(js|mjs|cjs|jsx|ts|mts|cts|tsx)` application prefix and possible extensions located in `src`, `Your project -> src -> index.(js|mjs|cjs|jsx|ts|mts|cts|tsx)`
- `dist` directory for webpack bundle output, `Your project -> dist`
- `localhost` host name
- `port` default of `3000`
> To alter these presets see [`dotenv`](#dotenv-use) use.
#### Basic setup
> All setup directions are based on a MacOS experience. If Linux, or Windows, is used and
you feel the directions could be updated please open a pull request to update documentation.
**For those with experience**, to get up and running quickly...
1. Confirm you installed the correct version of [NodeJS](https://nodejs.org)
1. Confirm you added `weldable` as a `dependency` to your project
1. Make sure you have a `src` directory with at least an `index.(js|ts)`
1. Create NPM scripts that reference the `weldable` CLI
```
"scripts": {
"build": "weldable",
"start": "weldable -e development"
},
```
1. Run the NPM scripts and that's it, customize away!
**And for those with less experience**, directions for all...
1. Confirm you installed the correct version of [NodeJS](https://nodejs.org/). The current minimum NodeJS version is noted on the main [README.md](./README.md)
1. Create a new directory, open your terminal and change directories into it
```
$ cd ./[new_directory]
```
1. Create your `package.json` file. You can use the terminal to initialize the project, you'll be asked questions (there are defaults, just hit enter or fill them out)...
```
$ npm init
```
1. After creating `package.json`. Add `weldable` as a `devDependency` via the terminal
```
$ npm i weldable --save-dev
```
1. Next, add a `src` directory to your new directory, like `new_directory -> src`
1. Next, add an `index.js` file to `src`, like `new_directory -> src -> index.js`
1. Add the following contents to `index.js`
```
const body = document.querySelector('BODY');
const div = document.createElement('div');
div.innerText = `hello world`;
body.appendChild(div);
```
1. To get everything running, we need to add some NPM scripts inside the `package.json` `scripts` section
```
"scripts": {
"build": "weldable",
"start": "weldable -e development"
},
```
1. Next, in the terminal, lets run the development mode.
```
$ npm start
```
> If everything is working correctly you should see messaging telling you where files are running.
>
> If everything did NOT work, you may receive messaging from `weldable`, or `webpack`, explaining what the issue is.
> If you receive no error messaging a standard practice is to reconfirm you have the correct tooling installed and walk
> back through the previous steps.
1. Finally, in the terminal, we'll create our bundle
```
$ npm run build
```
> If everything is working correctly you should see messaging telling you basic bundle stats and a successful completion message.
> You can access your bundle under the `dist` directory.
>
> If things are NOT working, `weldable` and `webpack` should provide messaging to help you
> debug why your bundle isn't being compiled
#### Set up a JS framework, like React
At its most basic `weldable` does not work out of the box with frameworks, like React, unless a loader we've included happens to support
said framework, such as `ts-loader` and `React`.
What that means is you may have to modify and use your own webpack configuration loader.
**Set up a React project with `ts-loader`**
1. Confirm you installed the correct version of [NodeJS](https://nodejs.org)
1. Confirm you added [`weldable`](https://www.npmjs.com/package/weldable) as a `dependency` to your project
1. Confirm you added [`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) as `dependencies` for your project
1. Create a basic `tsconfig.json` in the root of your project directory with the following content. After everything is working modify as needed.
```
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"jsx": "react",
"module": "esnext",
"moduleResolution": "node"
}
}
```
1. Make sure you have a `src` directory with at least an `index.tsx`, and the following content.
```
import React from 'react';
import { createRoot } from 'react-dom/client';
const body = document.querySelector('BODY');
const div = document.createElement('div');
body?.appendChild(div);
const App = () => <>hello world>;
const root = createRoot(div);
root.render();
```
1. Create NPM scripts that reference the `weldable` CLI
```
"scripts": {
"build": "weldable -l ts",
"start": "weldable -e development -l ts"
}
```
1. Run the NPM scripts and that's it. You should see `hello world`, when you run `$ npm start`, displayed in a browser window.
> If the browser failed to open you can find the content at http://localhost:3000/
**Set up a React project with `babel-loader`**
1. Confirm you installed the correct version of [NodeJS](https://nodejs.org)
1. Confirm you added [`weldable`](https://www.npmjs.com/package/weldable) as a `dependency` to your project
1. Confirm you added [`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) as `dependencies` for your project
1. Create a basic `babel.config.js` file with the following content
```
module.exports = {};
```
1. Create a basic `webpack.config.js` in the root of your project directory with the following content. After everything working modify as needed.
```
const { babelLoaderResolve, babelPresetEnvResolve, babelPresetReactResolve } = require('weldable/lib/packages');
module.exports = ({ SRC_DIR } = {}) => ({
module: {
rules: [
{
test: /\.(jsx|js)?$/,
include: [SRC_DIR],
use: [
{
loader: babelLoaderResolve,
options: {
presets: [babelPresetEnvResolve, babelPresetReactResolve]
}
}
]
}
]
}
});
```
1. Make sure you have a `src` directory with at least an `index.js`, and the following content.
```
import React from 'react';
import { createRoot } from 'react-dom/client';
const body = document.querySelector('BODY');
const div = document.createElement('div');
body?.appendChild(div);
const App = () => <>hello world>;
const root = createRoot(div);
root.render();
```
1. Create NPM scripts that reference the `weldable` CLI
```
"scripts": {
"build": "weldable -x ./webpack.config.js",
"start": "weldable -e development -x ./webpack.config.js"
}
```
1. Run the NPM scripts and that's it. You should see `hello world`, when you run `$ npm start`, displayed in a browser window.
> If the browser failed to open you can find the content at http://localhost:3000/
dotenv use
`weldable` makes use of dotenv parameters for aspects of webpack configuration overrides.
> Instead of dotenv files you can choose to export parameters via the terminal
#### dotenv via terminal
Using the terminal to handle dotenv parameters
Set a parameter
```shell
export YOUR_DOTENV_PARAM="lorem ipsum"; echo $YOUR_DOTENV_PARAM
```
Unset a parameter
```shell
unset YOUR_DOTENV_PARAM; echo $YOUR_DOTENV_PARAM
```
#### dotenv via files
dotenv files are structured to cascade, similar to stylesheets. Each additional dotenv file builds settings from a root `.env` file.
```
.env = base dotenv file settings
.env.local = local settings overrides that enhance the base .env settings
.env -> .env.development = development settings that enhances the base .env settings
.env -> .env.development.local = local run development settings that enhances the base .env and .env.development settings
.env -> .env.production = build modifications associated with all environments
.env -> .env.production.local = local run build modifications that enhance the base .env and .env.production settings
```
In certain instances it is encouraged that you `.gitignore` all dotenv files since they can contain application settings.
For this framework, however, we encourage application settings being applied to `.env*.local` files and adding 2 entries
to your project's `.gitignore`
```
!.env
.env*.local
```
This allows you to have both local settings that are NOT checked in, and settings that are.
**Available dotenv parameters**
`weldable` makes use of exposed dotenv parameters to handle webpack configuration settings...
| dotenv parameter | definition | default value |
|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| RELATIVE_DIRNAME (*read only*) | A dynamically build populated string reference for the root context path | |
| APP_INDEX_PREFIX | A static string for the webpack application entry file `[APP_INDEX_PREFIX].[ext]` | index |
| DIST_DIR | A static string for the webpack build output directory | ./dist |
| HOST | A static string for the webpack dev server host | localhost |
| HTML_INDEX_DIR | A static string referencing what directory your `index.html` file is located. If there is no `index.html`, webpack is nice, it'll create one for you. | ./src |
| NODE_ENV | | |
| PORT | A static number for the webpack dev server port | 3000 |
| OPEN_PATH | A static string for the webpack dev server browser open path | |
| PUBLIC_PATH | A static string for the webpack output base expected path of your application. **Tip: This parameter can cause `webpack` to reference an incorrect path, specifically for static assets and your bundle output, resulting in `404`s and hair-pulling during development, see [`webpack` docs for more info](https://webpack.js.org/configuration/output/#outputpublicpath)** | / |
| PUBLIC_URL | A static string alias for PUBLIC_PATH | / |
| SRC_DIR | A static string for application source directory | ./src |
| STATIC_DIR | A static string associated with the directory containing static build assets. We've generally used this directory for files included directly in `index.html`, and resources included with XHR. **Warning: importing, or requiring, assets from this directory to within the `SRC_DIR` WILL cause webpack to attempt bundling the asset along with copying it!** | |
| UI_NAME | A static string title for `index.html`. `index.html` being a file you, or webpack, creates within the STATIC_DIR | |
> Technically all dotenv parameters are strings. When consuming them it is important to cast them accordingly.
CLI use
Basic CLI functionality can also be viewed under a simple terminal command
```shell
$ weldable -h
```
#### Options
| CLI OPTION | DESCRIPTION | TYPE | CHOICES | DEFAULT |
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------|---------------------------------------------------------------------------------|--------------|
| -e, --env | Use a default configuration type if NODE_ENV is not set to the available choices of "development" and "production" | string | development, production | production |
| -l, --loader | Preprocess loader, use the classic JS (babel-loader), TS (ts-loader), or "none" to use webpack defaults, or a different loader. | string | js, ts, none | js |
| -s, --stats | Stats output level for NodeJS API | string | errors-only, errors-warnings, minimal, none, normal, verbose, detailed, summary | normal |
| --standalone | Standalone webpack configuration. Output weldable webpack config functions and update package.json so you can do whatever you want. | boolean | | |
| --statsFile | Output JSON webpack bundle stats for use with "webpack-bundle-analyzer". Use the default or enter a relative path and filename | string | | ./stats.json |
| --tsconfig | Generate a base tsconfig from one of the available NPM @tsconfig/[base]. An existing tsconfig.json will override this option, see "tsconfig-opt". This option can be run without running webpack. | string | create-react-app, node20, node22, node24, react-native, recommended, strictest | |
| --tsconfig-opt | Regenerate or merge a tsconfig. Useful if a tsconfig already exists. Requires the use of "tsconfig" option | string | merge, regen | regen |
| -x, --extend | Extend, or override, the default configs with your own relative path webpack configs using webpack merge. Configuration can be a callback that returns a webpack config object, available dotenv parameters are returned as the callback parameter. | string \| Array\ | | |
| -h, --help | | boolean | | |
| -v, --version | | boolean | | |
#### Use the CLI with NPM scripts
CLI usage can be placed under NPM scripts
A basic development start, and production build, using your own scripts
```js
"scripts": {
"start": "weldable -e development",
"build": "weldable"
}
```
A development start, and production build, using your own webpack configurations merged with the defaults.
```js
"scripts": {
"start": "weldable -e development -x ./webpack.yourCustomBuild.js -x ./webpack.developmentBuild.js",
"build": "weldable -x ./webpack.yourCustomBuild.js -x ./webpack.productionBuild.js"
}
```
#### Use weldable to generate a webpack configuration
You can output the `weldable` webpack and support configuration files, plus the associated NPM packages and scripts into an existing
or new project. These resources are current to any modifications made to `weldable` itself.
> You'll need to have `weldable` installed, locally, globally or use `npx`.
> Similar to `Create React Apps` ability of generating and "ejecting", but without the doom and gloom. You can always go back to `weldable`.
To get the output...
- Run the `--standalone` option.
```
$ cd [into a directory to generate the configuration in]
$ npx weldable --standalone
```
- And that's it. You should now have a basic webpack configuration setup. If this is a new project you should be able to immediately use the new NPM scripts like `$ npm run standalone:start`.
> Files that are created, or modified, generally vary when the `--loader` option is used, for example: `$ npx weldable --standalone --loader=ts`
Changes include...
- A `webpack.config.js` file is created
- A modified, or basic, `package.json` is created
- 2 NPM scripts should be added, both are prefixed with `standalone:`
- `standalone:build`
- `standalone:start`
- multiple developer dependencies should be added
- A basic `hello world` `./src/index.[js|ts]` file is created, if none exists
- Additional configuration may also be generated. Console output should provide a listing of all skipped, modified, and added files.
After everything is generated feel free to move and modify the files as needed since you'll no longer need `weldable`.
Lib use
The `lib` aspect of `weldable` is exported as CommonJS and is intended to be run as part of your build process without the need to install many additional packages.
Two primary things are exposed through `weldable`...
- packages, such as `webpack-merge`
- and `weldable` "helper" functions
Example use within build files...
```
const { dotenv } = require('weldable');
const dotenvFunc = dotenv.[FUNC];
```
#### Exposed packages
See our [package.json](./package.json) `dependencies` for exposed packages.
You can also use the `weldable` namespace, or you can always call the package directly...
```
const packages = require('weldable/lib/packages');
const aPackage = packages.[PACKAGE_NAME];
```
**Heads up**
- Packages is kept separated from `weldable` functions due to ES module loading. Certain packages do but others don't provide modules which can cause issues with tooling, such as `Jest`.
- Every package has 2 exported aspects, the `required` package and a `require.resolve`
- We do not provide package use documentation. For package use review associated package.
- All packages retain their respective license. It is your responsibility to use said packages accordingly.
> The `weldable` lib bundles a [`txt` resource](./lib/packagesLicenses.txt) containing available license materials.
| PACKAGES | EXPOSED NAME |
|---------------------------------|-----------------------------------------------------------------|
| @babel/core | babelCore, babelCoreResolve |
| @babel/plugin-transform-runtime | babelPluginTransformRuntime, babelPluginTransformRuntimeResolve |
| @babel/preset-env | babelPresetEnv, babelPresetEnvResolve |
| @babel/preset-react | babelPresetReact, babelPresetReactResolve |
| @tsconfig/create-react-app | N/A |
| @tsconfig/node20 | N/A |
| @tsconfig/node22 | N/A |
| @tsconfig/node24 | N/A |
| @tsconfig/react-native | N/A |
| @tsconfig/recommended | N/A |
| @tsconfig/strictest | N/A |
| babel-loader | babelLoader, babelLoaderResolve |
| copy-webpack-plugin | CopyWebpackPlugin, CopyWebpackPluginResolve |
| css-loader | cssLoader, cssLoaderResolve |
| css-minimizer-webpack-plugin | CssMinimizerWebpackPlugin, CssMinimizerWebpackPluginResolve |
| dotenv | dotenv, dotenvResolve |
| dotenv-expand | dotenvExpand, dotenvExpandResolve |
| dotenv-webpack | dotenvWebpack, dotenvWebpackResolve |
| eslint-webpack-plugin | EslintWebpackPlugin, EslintWebpackPluginResolve |
| html-replace-webpack-plugin | htmlReplaceWebpackPlugin, htmlReplaceWebpackPluginResolve |
| html-webpack-plugin | HtmlWebpackPlugin, HtmlWebpackPluginResolve |
| less | less, lessResolve |
| less-loader | lessLoader, lessLoaderResolve |
| mini-css-extract-plugin | MiniCssExtractPlugin, MiniCssExtractPluginResolve |
| mini-svg-data-uri | miniSvgDataUri, miniSvgDataUriResolve |
| rimraf | rimraf, rimrafResolve |
| sass | sass, sassResolve |
| sass-loader | sassLoader, sassLoaderResolve |
| style-loader | styleLoader, styleLoaderResolve |
| terser-webpack-plugin | TerserWebpackPlugin, TerserWebpackPluginResolve |
| ts-loader | tsLoader, tsLoaderResolve |
| tsconfig-paths-webpack-plugin | tsconfigPathsWebpackPlugin, tsconfigPathsWebpackPluginResolve |
| tslib | tslib, tslibResolve |
| typescript | typescript, typescriptResolve |
| webpack | webpack, webpackResolve |
| webpack-bundle-analyzer | webpackBundleAnalyzer, webpackBundleAnalyzerResolve |
| webpack-cli | WebpackCli, WebpackCliResolve |
| webpack-dev-server | WebpackDevServer, WebpackDevServerResolve |
| webpack-merge | webpackMerge, webpackMergeResolve |
An example webpack config rules loader using the provided `require.resolve`...
```
const { cssLoaderResolve, MiniCssExtractPlugin, sassLoaderResolve } = require('weldable/lib/packages');
module.exports = ({ SRC_DIR } = {}) => ({
module: {
rules: [
{
test: /\.(sa|sc)ss$/i,
use: [MiniCssExtractPlugin.loader, cssLoaderResolve, sassLoaderResolve]
}
]
}
});
```
#### Exposed weldable functions
`weldable` exposes limited helper functions
You can access the functions like so...
```
const { dotenv } = require('weldable');
const dotenvFunc = dotenv.[FUNC];
```
| HELPER | EXPOSED NAME | DESCRIPTION |
|------------------------------------------------------------------------------------------------------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [dotenv](./src/README.md#module_dotenv) | dotenv | An object group of helper functions designed to consume dotenv files. Useful for implementing your own dotenv parameters used during testing, or for a standalone webpack build |
| [dotenv.setupDotenvFilesForEnv](./src/README.md#module_dotenv..setupDotenvFilesForEnv) | dotenv.setupDotenvFilesForEnv | A function for use with non-webpack configurations. Access local and specific dotenv file parameters. Failed or missing parameters return an empty string. |
| [dotenv.setupWebpackDotenvFilesForEnv](./src/README.md#module_dotenv..setupWebpackDotenvFilesForEnv) | dotenv.setupWebpackDotenvFilesForEnv | A function for use with webpack configurations. Set multiple webpack dotenv file parameters during configuration and build. |
**Examples**
Example usage with Jest, `setupTests.js`. This will allow the use of `.env.test` and `.env.test.local` files.
```
/**
* Set dotenv params for use during testing.
*/
setupDotenvFilesForEnv({ env: 'test' });
```
Example usage with a webpack build configuration. The associated dotenv files would be
- `.env`
- `.env.local`
- `.env.loremIpsum`
- `.env.loremIpsum.local`
```
const { dotenv } = require('weldable');
const { setupDotenvFilesForEnv, setupWebpackDotenvFilesForEnv } = dotenv;
process.env.NODE_ENV='development';
const {
RELATIVE_DIRNAME,
DIST_DIR
HOST
NODE_ENV
PORT
OPEN_PATH
PUBLIC_PATH
PUBLIC_URL
SRC_DIR
STATIC_DIR
} = setupDotenvFilesForEnv({
env: 'loremIpsum',
relativePath: process.cwd()
});
const webpackProduction = {
...
plugins: [
...setupWebpackDotenvFilesForEnv({
directory: RELATIVE_DIRNAME,
env: NODE_ENV
}),
...
};
```
> `setupDotenvFilesForEnv` falls back to creating a NODE_ENV parameter if one is not already set. It is
> recommended if you decide to use webpack and a non-standard env beyond `development` or `production` you
> also export a NODE_ENV=development or NODE_ENV=production to avoid issues.