Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package for sharing webpack configurations for upcoming Features #7199

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ docs/extensions/api
site/
lerna-debug.log
coverage
dist
node_modules
180 changes: 78 additions & 102 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions packages/bump-version-for-cron/.gitignore

This file was deleted.

2 changes: 0 additions & 2 deletions packages/core/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
static/build/
build/webpack/
binaries/
dist/
node_modules/
2 changes: 0 additions & 2 deletions packages/ensure-binaries/.gitignore

This file was deleted.

2 changes: 0 additions & 2 deletions packages/extension-api/.gitignore

This file was deleted.

2 changes: 0 additions & 2 deletions packages/generate-tray-icons/.gitignore

This file was deleted.

76 changes: 76 additions & 0 deletions packages/infrastructure/webpack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# @k8slens/webpack

This package contains webpack configurations for Lens packages.

## Install

```
$ npm install @k8slens/webpack
```

## Features

### Configurations

### Node package
This configuration should be used when creating package that will be executed within **Node** environment.

**webpack.config.js**
```javascript
module.exports = require("@k8slens/webpack").configForNode;
```
### React package
This configuration should be used when creating package tha will be executed within **Browser** environment.

**webpack.config.js**
```javascript
module.exports = require("@k8slens/webpack").configForReact;
```

### Multi export package

This configuration should be used when package contains **multiple entrypoint** e.g. for different environments. You need to add `lensMultiExportConfig` to `package.json` with configuration. Note that also `exports` property needs to be set, but the correct values are generated from `lensMultiExportConfig` when using `lens-build` -script.

**webpack.config.js**
```javascript
const packageJson = require("./package.json");

module.exports = require("@k8slens/webpack").getMultiExportConfig(packageJson);
```

**package.json**
```json
{
"lensMultiExportConfig": {
"./main": {
"buildType": "node",
"entrypoint": "./src/main/index.ts"
},
"./renderer": {
"buildType": "react",
"entrypoint": "./src/renderer/index.ts"
}
},

"exports": {
"./main": {
"types": "./dist/main/index.d.ts",
"require": "./dist/main/index.js",
"import": "./dist/main/index.js",
"default": "./dist/main/index.js"
},
"./renderer": {
"types": "./dist/renderer/index.d.ts",
"require": "./dist/renderer/index.js",
"import": "./dist/renderer/index.js",
"default": "./dist/renderer/index.js"
}
}
}
```

## Scripts

1. `lens-build` which builds the packages
2. `lens-remove-build` which removes the build directory from packages. It's useful for cleaning up.

2 changes: 2 additions & 0 deletions packages/infrastructure/webpack/bin/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set -e
webpack $@
1 change: 1 addition & 0 deletions packages/infrastructure/webpack/bin/remove-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rm -rfv build
5 changes: 5 additions & 0 deletions packages/infrastructure/webpack/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
configForNode: require("./src/node-config"),
configForReact: require("./src/react-config"),
getMultiExportConfig: require("./src/get-multi-export-config"),
};
8 changes: 8 additions & 0 deletions packages/infrastructure/webpack/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { configForNode } =
require("@k8slens/jest").monorepoPackageConfig(__dirname);

module.exports = {
...configForNode,

collectCoverageFrom: [...configForNode.collectCoverageFrom],
};
36 changes: 36 additions & 0 deletions packages/infrastructure/webpack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "@k8slens/webpack",
"private": false,
"version": "0.0.1",
"description": "Webpack configurations and scripts for Lens packages.",
"type": "commonjs",
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
},
"main": "index.js",
"author": {
"name": "OpenLens Authors",
"email": "info@k8slens.dev"
},
"license": "MIT",
"homepage": "https://github.com/lensapp/lens",
"bin": {
"lens-build": "bin/build.sh",
"lens-remove-build": "bin/remove-build.sh"
},
"scripts": {
"test:unit": "lens-test"
},
"dependencies": {
"@types/webpack-env": "^1.18.0",
"css-loader": "^6.7.2",
"mini-css-extract-plugin": "^2.7.0",
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.4.1",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-node-externals": "^3.0.0"
}
}
120 changes: 120 additions & 0 deletions packages/infrastructure/webpack/src/get-multi-export-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const nodeConfig = require("./node-config");
const reactConfig = require("./react-config");
const path = require("path");
const {
map,
isEqual,
keys,
fromPairs,
toPairs,
reject,
values,
nth,
filter,
} = require("lodash/fp");
const { pipeline } = require("@ogre-tools/fp");

module.exports = (packageJson, dependencies = { nodeConfig, reactConfig }) => {
if (!packageJson.lensMultiExportConfig) {
throw new Error(
`Tried to get multi export config for package "${packageJson.name}" but configuration is missing.`
);
}

const validBuildTypes = ["node", "react"];

const invalidBuildTypes = pipeline(
packageJson.lensMultiExportConfig,
values,
map((config) => config.buildType),
reject((buildType) => validBuildTypes.includes(buildType))
);

if (invalidBuildTypes.length > 0) {
throw new Error(
`Tried to get multi export config for package "${
packageJson.name
}" but build types "${invalidBuildTypes.join(
'", "'
)}" were not any of "${validBuildTypes.join('", "')}".`
);
}

const exportsWithMissingEntrypoint = pipeline(
packageJson.lensMultiExportConfig,
toPairs,
filter(([, config]) => !config.entrypoint),
map(nth(0))
);

if (exportsWithMissingEntrypoint.length > 0) {
throw new Error(
`Tried to get multi export config for package "${
packageJson.name
}" but entrypoint was missing for "${exportsWithMissingEntrypoint.join(
'", "'
)}".`
);
}

const expectedExports = pipeline(
packageJson.lensMultiExportConfig,
keys,
map(toExpectedExport),
fromPairs
);

if (!isEqual(expectedExports, packageJson.exports)) {
throw new Error(
`Tried to get multi export config but exports of package.json for "${
packageJson.name
}" did not match exactly:\n\n${JSON.stringify(expectedExports, null, 2)}`
);
}

return pipeline(
packageJson.lensMultiExportConfig,
toPairs,
map(toExportSpecificWebpackConfigFor(dependencies))
);
};

const toExpectedExport = (externalImportPath) => {
const entrypointPath = `./${path.join(
"./dist",
externalImportPath,
"index.js"
)}`;

return [
externalImportPath,
{
types: `./${path.join("./dist", externalImportPath, "index.d.ts")}`,

default: entrypointPath,
import: entrypointPath,
require: entrypointPath,
},
];
};

const toExportSpecificWebpackConfigFor =
(dependencies) =>
([externalImportPath, { buildType, entrypoint }]) => {
const baseConfig =
buildType === "node" ? dependencies.nodeConfig : dependencies.reactConfig;

return {
...baseConfig,
name: entrypoint,

entry: {
index: entrypoint,
},

output: {
...baseConfig.output,
path: path.join(baseConfig.output.path, externalImportPath),
},
};
};