Skip to content

Commit

Permalink
refactor: expand js extensions for webpack (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcabrera committed Jun 12, 2024
1 parent 9b7d52d commit c36c5a4
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 14 deletions.
112 changes: 109 additions & 3 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ overridden, or ignored, to fit your own preferences.

Assumptions `weldable` presets...
- `src` project directory, `Your project -> src -> your work`
- `index.(js|jsx|ts|tsx)` application prefix and possible extensions located in `src`, `Your project -> src -> index.(js|jsx|ts|tsx)`
- `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.
#### Setup
#### 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|jsx|ts|tsx)`
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": {
Expand Down Expand Up @@ -93,6 +93,112 @@ you feel the directions could be updated please open a pull request to update do
> 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.

**Setup 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"
}
}
```

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(<App />);
```
1. Create NPM scripts that reference the `weldable` CLI
```
"scripts": {
"build": "weldable",
"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/

**Setup a React project with `bable-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(<App />);
```
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/
</details>

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The goal of `weldable` is to make it easier to install `webpack` build packages
`weldable` is intended...

- To be quickly used for basic webpack development and production builds.
- To purposefully not include webpack configurations for JS frameworks beyond basic JS and exposing basic related NPM loader packages.
- To purposefully not include webpack configurations for linting and styling aspects beyond basic webpack capabilities.
- To be designed with the expectation that you can expand on the `weldable` base using the CLI extend option. `-x ./webpack.exampleConfig.js`.
- To be used as a single build resource with exposed webpack plugins/addons. And without the need to reinstall available webpack packages (or at least the ones `weldable` uses).
Expand Down
3 changes: 2 additions & 1 deletion __fixtures__/src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import './index.css';
import { hello } from './woot';

(() => {
const body = document.querySelector('BODY');
const div = document.createElement('div');
div.innerText = `${process.env.MOCK_JS_VALUE} hello world`;
div.innerText = `${process.env.MOCK_JS_VALUE} ${hello()}`;
body.appendChild(div);
})();
3 changes: 3 additions & 0 deletions __fixtures__/src/woot.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const hello = () => 'Hello World!';

export { hello as default, hello };
1 change: 1 addition & 0 deletions cspell.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"language": "en",
"words": [
"babel",
"chunkfixture",
"codecov",
"cmds",
Expand Down
16 changes: 16 additions & 0 deletions src/__tests__/__snapshots__/wp.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,14 @@ exports[`webpack should create a webpack config with language: language configur
"include": [
"./__fixtures__/src"
],
"resolve": {
"extensions": [
".jsx",
".js",
".mjs",
".cjs"
]
},
"use": [
{
"loader": "babel-loader"
Expand Down Expand Up @@ -608,6 +616,14 @@ exports[`webpack should create a webpack config with language: language configur
"include": [
"./__fixtures__/src"
],
"resolve": {
"extensions": [
".jsx",
".js",
".mjs",
".cjs"
]
},
"use": [
{
"loader": "babel-loader"
Expand Down
24 changes: 20 additions & 4 deletions src/__tests__/__snapshots__/wpConfigs.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -592,16 +592,16 @@ exports[`webpackConfigs should return a development configuration object: develo
exports[`webpackConfigs should return a preprocessLoader configuration object: language dev, prod hashes 1`] = `
[
{
"devHash": "622840d4852c749c1df5e7325bca73a1",
"devHash": "94105185f5f28d4ba07282938bd4d43a",
"isEqual": true,
"loader": "js",
"prodHash": "622840d4852c749c1df5e7325bca73a1",
"prodHash": "94105185f5f28d4ba07282938bd4d43a",
},
{
"devHash": "7149a7a85fe5bc99f81782452e2c0ced",
"devHash": "3905735acd7ce27ca46d4aaad2d6aa1d",
"isEqual": true,
"loader": "ts",
"prodHash": "7149a7a85fe5bc99f81782452e2c0ced",
"prodHash": "3905735acd7ce27ca46d4aaad2d6aa1d",
},
{
"devHash": "49e595be76828acf4f2a3617fea9a378",
Expand All @@ -621,6 +621,14 @@ exports[`webpackConfigs should return a preprocessLoader configuration object: p
"include": [
"./__fixtures__/src"
],
"resolve": {
"extensions": [
".jsx",
".js",
".mjs",
".cjs"
]
},
"use": [
{
"loader": "babel-loader"
Expand Down Expand Up @@ -649,6 +657,14 @@ exports[`webpackConfigs should return a preprocessLoader configuration object: p
"include": [
"./__fixtures__/src"
],
"resolve": {
"extensions": [
"tsx",
".ts",
".jsx",
".js"
]
},
"use": [
{
"loader": "ts-loader"
Expand Down
26 changes: 20 additions & 6 deletions src/wpConfigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,30 @@ const preprocessLoader = ({ _BUILD_SRC_DIR: SRC_DIR = '' } = OPTIONS.dotenv || {
case 'js':
return [
{
test: /\.(jsx|js)?$/,
test: /\.(jsx|[cm]?js)?$/,
include: [SRC_DIR],
resolve: {
extensions: ['.jsx', '.js', '.cjs', '.mjs']
},
use: [
{
loader: babelLoaderResolve
loader: babelLoaderResolve,
options: {
presets: ['@babel/preset-env']
}
}
]
}
];
case 'ts':
return [
{
test: /\.(tsx|ts|js)?$/,
test: /\.(jsx|tsx|[cm]?ts|[cm]?js)?$/,
include: [SRC_DIR],
resolve: {
// Dependent on tsconfig resolutions may, or may not, be necessary
extensions: ['.tsx', '.ts', '.mts', '.cts', '.jsx', '.js', '.mjs', '.cjs']
},
use: [
{
loader: tsLoaderResolve
Expand Down Expand Up @@ -97,15 +107,19 @@ const common = (
try {
const entryFilesSet = new Set([
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.js`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.mjs`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.cjs`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.jsx`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.${loader}`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.${loader}x`)
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.ts`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.mts`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.cts`),
path.join(SRC_DIR, `${APP_INDEX_PREFIX}.tsx`)
]);
entryFiles = Array.from(entryFilesSet).filter(file => fs.existsSync(file));

if (!entryFiles.length) {
consoleMessage.warn(
`webpack app entry file error: Missing entry/app file. Expected ${APP_INDEX_PREFIX}.(${loader}|x)`
`webpack app entry file error: Missing entry/app file. Expected an index file! ${APP_INDEX_PREFIX}.(${loader}x|[cm]?${loader})`
);
}
} catch (e) {
Expand Down

0 comments on commit c36c5a4

Please sign in to comment.