From 9a4b02becb21ce91b5b00bd9eaeb8a2de1f9405e Mon Sep 17 00:00:00 2001 From: Iku-turso Date: Thu, 27 Apr 2023 15:02:25 +0300 Subject: [PATCH] chore: Consolidate infrastructure of webpack to ts to make it scriptable Co-authored-by: Janne Savolainen Signed-off-by: Iku-turso Signed-off-by: Janne Savolainen --- package-lock.json | 21 ++++++- packages/infrastructure/webpack/index.js | 5 -- packages/infrastructure/webpack/index.ts | 3 + packages/infrastructure/webpack/package.json | 16 ++++- ...p => get-multi-export-config.test.ts.snap} | 2 +- ...est.js => get-multi-export-config.test.ts} | 39 +++--------- ...t-config.js => get-multi-export-config.ts} | 60 +++++++++++------- ...{get-node-config.js => get-node-config.ts} | 29 +++++---- ...eact-config.js => get-react-config-for.ts} | 14 +++-- .../infrastructure/webpack/src/node-config.js | 7 --- .../infrastructure/webpack/src/node-config.ts | 7 +++ ...me.test.js => get-dependency-name.test.ts} | 0 ...endency-name.js => get-dependency-name.ts} | 4 +- .../make-peer-dependencies-external.js | 29 --------- .../make-peer-dependencies-external.ts | 26 ++++++++ ...protect-from-importing-non-dependencies.js | 58 ----------------- ...protect-from-importing-non-dependencies.ts | 63 +++++++++++++++++++ .../to-module-matcher-reg-exp.js | 3 - ...t.js => to-module-matcher-reg-exp.test.ts} | 8 +-- .../to-module-matcher-reg-exp.ts | 1 + .../webpack/src/react-config.js | 7 --- .../webpack/src/react-config.ts | 7 +++ packages/infrastructure/webpack/tsconfig.json | 4 ++ .../infrastructure/webpack/webpack.config.ts | 7 +++ 24 files changed, 230 insertions(+), 190 deletions(-) delete mode 100644 packages/infrastructure/webpack/index.js create mode 100644 packages/infrastructure/webpack/index.ts rename packages/infrastructure/webpack/src/__snapshots__/{get-multi-export-config.test.js.snap => get-multi-export-config.test.ts.snap} (98%) rename packages/infrastructure/webpack/src/{get-multi-export-config.test.js => get-multi-export-config.test.ts} (87%) rename packages/infrastructure/webpack/src/{get-multi-export-config.js => get-multi-export-config.ts} (74%) rename packages/infrastructure/webpack/src/{get-node-config.js => get-node-config.ts} (61%) rename packages/infrastructure/webpack/src/{get-react-config.js => get-react-config-for.ts} (83%) delete mode 100644 packages/infrastructure/webpack/src/node-config.js create mode 100644 packages/infrastructure/webpack/src/node-config.ts rename packages/infrastructure/webpack/src/plugins/get-dependency-name/{get-dependency-name.test.js => get-dependency-name.test.ts} (100%) rename packages/infrastructure/webpack/src/plugins/get-dependency-name/{get-dependency-name.js => get-dependency-name.ts} (57%) delete mode 100644 packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js create mode 100644 packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.ts delete mode 100644 packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.js create mode 100644 packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.ts delete mode 100644 packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.js rename packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/{to-module-matcher-reg-exp.test.js => to-module-matcher-reg-exp.test.ts} (88%) create mode 100644 packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.ts delete mode 100644 packages/infrastructure/webpack/src/react-config.js create mode 100644 packages/infrastructure/webpack/src/react-config.ts create mode 100644 packages/infrastructure/webpack/tsconfig.json create mode 100644 packages/infrastructure/webpack/webpack.config.ts diff --git a/package-lock.json b/package-lock.json index 4f11a37b3f..8b0d8a33a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36585,6 +36585,7 @@ "@types/webpack-env": "^1.18.0", "css-loader": "^6.7.2", "fork-ts-checker-webpack-plugin": "^7.3.0", + "fs-extra": "^9.0.1", "mini-css-extract-plugin": "^2.7.3", "sass": "^1.62.1", "sass-loader": "^13.2.0", @@ -36593,6 +36594,18 @@ "ts-loader": "^9.4.1", "webpack": "^5.81.0", "webpack-cli": "^4.10.0" + }, + "devDependencies": { + "@async-fn/jest": "^1.6.4", + "@k8slens/test-utils": "^1.0.0-alpha.1", + "@k8slens/typescript": "^6.5.0-alpha.2", + "ts-node": "^10.9.1", + "webpack-node-externals": "^3.0.0" + }, + "peerDependencies": { + "@ogre-tools/fp": "^15.6", + "@ogre-tools/injectable": "^15.6.1", + "lodash": "^4.17.21" } }, "packages/infrastructure/webpack/node_modules/sass-loader": { @@ -41520,17 +41533,23 @@ "@k8slens/webpack": { "version": "file:packages/infrastructure/webpack", "requires": { + "@async-fn/jest": "^1.6.4", + "@k8slens/test-utils": "^1.0.0-alpha.1", + "@k8slens/typescript": "^6.5.0-alpha.2", "@types/webpack-env": "^1.18.0", "css-loader": "^6.7.2", "fork-ts-checker-webpack-plugin": "^7.3.0", + "fs-extra": "^9.0.1", "mini-css-extract-plugin": "^2.7.3", "sass": "^1.62.1", "sass-loader": "^13.2.0", "style-loader": "^3.3.1", "tailwindcss": "^3.3.2", "ts-loader": "^9.4.1", + "ts-node": "^10.9.1", "webpack": "^5.81.0", - "webpack-cli": "^4.10.0" + "webpack-cli": "^4.10.0", + "webpack-node-externals": "^3.0.0" }, "dependencies": { "sass-loader": { diff --git a/packages/infrastructure/webpack/index.js b/packages/infrastructure/webpack/index.js deleted file mode 100644 index 978c6b1526..0000000000 --- a/packages/infrastructure/webpack/index.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - configForNode: require("./src/node-config"), - configForReact: require("./src/react-config"), - getMultiExportConfig: require("./src/get-multi-export-config"), -}; diff --git a/packages/infrastructure/webpack/index.ts b/packages/infrastructure/webpack/index.ts new file mode 100644 index 0000000000..c7dffc231e --- /dev/null +++ b/packages/infrastructure/webpack/index.ts @@ -0,0 +1,3 @@ +export { configForNode } from "./src/node-config"; +export { configForReact } from "./src/react-config"; +export { getMultiExportConfig } from "./src/get-multi-export-config"; diff --git a/packages/infrastructure/webpack/package.json b/packages/infrastructure/webpack/package.json index 157f5aa3a3..016ffd3b56 100644 --- a/packages/infrastructure/webpack/package.json +++ b/packages/infrastructure/webpack/package.json @@ -12,7 +12,7 @@ "type": "git", "url": "git+https://github.com/lensapp/lens.git" }, - "main": "index.js", + "main": "dist/index.js", "author": { "name": "OpenLens Authors", "email": "info@k8slens.dev" @@ -20,12 +20,14 @@ "license": "MIT", "homepage": "https://github.com/lensapp/lens", "scripts": { + "build": "webpack", "test:unit": "jest --coverage --runInBand" }, "dependencies": { "@types/webpack-env": "^1.18.0", "css-loader": "^6.7.2", "fork-ts-checker-webpack-plugin": "^7.3.0", + "fs-extra": "^9.0.1", "mini-css-extract-plugin": "^2.7.3", "sass": "^1.62.1", "sass-loader": "^13.2.0", @@ -34,5 +36,17 @@ "ts-loader": "^9.4.1", "webpack": "^5.81.0", "webpack-cli": "^4.10.0" + }, + "peerDependencies": { + "@ogre-tools/fp": "^15.6", + "@ogre-tools/injectable": "^15.6.1", + "lodash": "^4.17.21" + }, + "devDependencies": { + "@async-fn/jest": "^1.6.4", + "@k8slens/test-utils": "^1.0.0-alpha.1", + "@k8slens/typescript": "^6.5.0-alpha.2", + "ts-node": "^10.9.1", + "webpack-node-externals": "^3.0.0" } } diff --git a/packages/infrastructure/webpack/src/__snapshots__/get-multi-export-config.test.js.snap b/packages/infrastructure/webpack/src/__snapshots__/get-multi-export-config.test.ts.snap similarity index 98% rename from packages/infrastructure/webpack/src/__snapshots__/get-multi-export-config.test.js.snap rename to packages/infrastructure/webpack/src/__snapshots__/get-multi-export-config.test.ts.snap index b65f45748e..4a4b0373c1 100644 --- a/packages/infrastructure/webpack/src/__snapshots__/get-multi-export-config.test.js.snap +++ b/packages/infrastructure/webpack/src/__snapshots__/get-multi-export-config.test.ts.snap @@ -123,7 +123,7 @@ exports[`get-multi-export-config given maximal package.json, when creating confi { test: /\\.s?css$/, use: [ - { some: 'miniCssExtractPluginLoader' }, + 'miniCssExtractPluginLoader', { loader: 'css-loader', options: { diff --git a/packages/infrastructure/webpack/src/get-multi-export-config.test.js b/packages/infrastructure/webpack/src/get-multi-export-config.test.ts similarity index 87% rename from packages/infrastructure/webpack/src/get-multi-export-config.test.js rename to packages/infrastructure/webpack/src/get-multi-export-config.test.ts index 48e457e9d1..5ddf5587a7 100644 --- a/packages/infrastructure/webpack/src/get-multi-export-config.test.js +++ b/packages/infrastructure/webpack/src/get-multi-export-config.test.ts @@ -1,14 +1,15 @@ import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"; -import getMultiExportConfig from "./get-multi-export-config"; +import { getMultiExportConfig } from "./get-multi-export-config"; import path from "path"; import { inspect } from "util"; -const getReactConfigFor = require("./get-react-config"); +import { getReactConfigFor } from "./get-react-config-for"; +import type { Configuration } from "webpack"; const resolvePathFake = path.posix.resolve; describe("get-multi-export-config", () => { - let configs; - let maximalPackageJson; + let configs: Configuration[]; + let maximalPackageJson: any; beforeEach(() => { maximalPackageJson = { @@ -61,7 +62,7 @@ describe("get-multi-export-config", () => { workingDirectory: "/some-working-directory", getReactConfig: getReactConfigFor({ - miniCssExtractPluginLoader: { some: "miniCssExtractPluginLoader" }, + miniCssExtractPluginLoader: "miniCssExtractPluginLoader", }), }); }); @@ -93,10 +94,10 @@ describe("get-multi-export-config", () => { }, ].forEach((scenario) => { describe(scenario.name, () => { - let config; + let config: Configuration; beforeEach(() => { - config = configs.find(({ name }) => name === scenario.entrypoint); + config = configs.find(({ name }) => name === scenario.entrypoint)!; }); it("has correct entrypoint", () => { @@ -112,7 +113,7 @@ describe("get-multi-export-config", () => { it("has correct declaration directory", () => { expect( - config.plugins.find( + config.plugins!.find( ({ constructor }) => constructor === ForkTsCheckerPlugin ) ).toHaveProperty( @@ -129,9 +130,7 @@ describe("get-multi-export-config", () => { expect(() => { getMultiExportConfig(maximalPackageJson, { - getNodeConfig: () => nodeConfigStub, getReactConfig: () => reactConfigStub, - joinPath: resolvePathFake, }); }).toThrow( 'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:' @@ -143,9 +142,7 @@ describe("get-multi-export-config", () => { expect(() => { getMultiExportConfig(maximalPackageJson, { - getNodeConfig: () => nodeConfigStub, getReactConfig: () => reactConfigStub, - joinPath: resolvePathFake, }); }).toThrow( 'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:' @@ -157,9 +154,7 @@ describe("get-multi-export-config", () => { expect(() => { getMultiExportConfig(maximalPackageJson, { - getNodeConfig: () => nodeConfigStub, getReactConfig: () => reactConfigStub, - joinPath: resolvePathFake, }); }).toThrow( 'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:' @@ -171,9 +166,7 @@ describe("get-multi-export-config", () => { expect(() => { getMultiExportConfig(maximalPackageJson, { - getNodeConfig: () => nodeConfigStub, getReactConfig: () => reactConfigStub, - joinPath: resolvePathFake, }); }).toThrow( 'Tried to get multi export config for package "some-name" but configuration is missing.' @@ -185,9 +178,7 @@ describe("get-multi-export-config", () => { expect(() => { getMultiExportConfig(maximalPackageJson, { - getNodeConfig: () => nodeConfigStub, getReactConfig: () => reactConfigStub, - joinPath: resolvePathFake, }); }).toThrow( 'Tried to get multi export config for package "some-name" but build types "some-invalid" were not any of "node", "react".' @@ -200,9 +191,7 @@ describe("get-multi-export-config", () => { expect(() => { getMultiExportConfig(maximalPackageJson, { - getNodeConfig: () => nodeConfigStub, getReactConfig: () => reactConfigStub, - joinPath: resolvePathFake, }); }).toThrow( 'Tried to get multi export config for package "some-name" but entrypoint was missing for "./some-entrypoint".' @@ -210,14 +199,6 @@ describe("get-multi-export-config", () => { }); }); -const nodeConfigStub = { - stub: "node", - output: { - some: "value", - path: "/some-build-directory", - }, -}; - const reactConfigStub = { stub: "react", @@ -225,4 +206,4 @@ const reactConfigStub = { some: "other-value", path: "/some-build-directory", }, -}; +} as unknown as Configuration; diff --git a/packages/infrastructure/webpack/src/get-multi-export-config.js b/packages/infrastructure/webpack/src/get-multi-export-config.ts similarity index 74% rename from packages/infrastructure/webpack/src/get-multi-export-config.js rename to packages/infrastructure/webpack/src/get-multi-export-config.ts index b4612ebad5..61443b5f49 100644 --- a/packages/infrastructure/webpack/src/get-multi-export-config.js +++ b/packages/infrastructure/webpack/src/get-multi-export-config.ts @@ -1,28 +1,37 @@ -const getNodeConfig = require("./get-node-config"); -const getReactConfigFor = require("./get-react-config"); -const path = require("path"); -const { - map, +import { + filter, + fromPairs, isEqual, keys, - fromPairs, - toPairs, - reject, - values, + map, nth, - filter, -} = require("lodash/fp"); -const { pipeline } = require("@ogre-tools/fp"); + reject, + toPairs, + values, +} from "lodash/fp"; -module.exports = ( - packageJson, +import { pipeline } from "@ogre-tools/fp"; +import path from "path"; +import { getReactConfigFor } from "./get-react-config-for"; +import { getNodeConfig } from "./get-node-config"; - dependencies = { +type Dependencies = { + resolvePath: typeof path.resolve; + workingDirectory: string; + getReactConfig: ReturnType; +}; + +export const getMultiExportConfig = ( + packageJson: any, + _dependencies: Partial +) => { + const dependencies: Dependencies = { resolvePath: path.resolve, workingDirectory: process.cwd(), - getReactConfig: getReactConfigFor() - } -) => { + getReactConfig: getReactConfigFor(), + ..._dependencies, + }; + if (!packageJson.lensMultiExportConfig) { throw new Error( `Tried to get multi export config for package "${packageJson.name}" but configuration is missing.` @@ -90,7 +99,7 @@ module.exports = ( ); }; -const toExpectedExport = (externalImportPath) => { +const toExpectedExport = (externalImportPath: string) => { const posixJoinForPackageJson = path.posix.join; const entrypointPath = `./${posixJoinForPackageJson( @@ -116,10 +125,13 @@ const toExpectedExport = (externalImportPath) => { }; const toExportSpecificWebpackConfigFor = - (dependencies) => - ([externalImportPath, { buildType, entrypoint }]) => { - const outputDirectory = dependencies.resolvePath( - dependencies.workingDirectory, + (dependencies: Dependencies) => + ([externalImportPath, { buildType, entrypoint }]: [ + string, + { buildType: string; entrypoint: string } + ]) => { + const outputDirectory = dependencies.resolvePath!( + dependencies.workingDirectory!, "dist", externalImportPath ); @@ -129,7 +141,7 @@ const toExportSpecificWebpackConfigFor = entrypointFilePath: entrypoint, outputDirectory, }) - : dependencies.getReactConfig({ + : dependencies.getReactConfig!({ entrypointFilePath: entrypoint, outputDirectory, }); diff --git a/packages/infrastructure/webpack/src/get-node-config.js b/packages/infrastructure/webpack/src/get-node-config.ts similarity index 61% rename from packages/infrastructure/webpack/src/get-node-config.js rename to packages/infrastructure/webpack/src/get-node-config.ts index 7daf2d9f1f..adcfe7b5b2 100644 --- a/packages/infrastructure/webpack/src/get-node-config.js +++ b/packages/infrastructure/webpack/src/get-node-config.ts @@ -1,12 +1,17 @@ -const ForkTsCheckerPlugin = require("fork-ts-checker-webpack-plugin"); -const { MakePeerDependenciesExternalPlugin } = require("./plugins/make-peer-dependencies-external"); -const { ProtectFromImportingNonDependencies } = require("./plugins/protect-from-importing-non-dependencies"); +import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"; +import type { Configuration } from "webpack"; +import { MakePeerDependenciesExternalPlugin } from "./plugins/make-peer-dependencies-external"; +import { ProtectFromImportingNonDependencies } from "./plugins/protect-from-importing-non-dependencies"; -/** - * - * @returns {import("webpack").Configuration} - */ -module.exports = ({ entrypointFilePath, outputDirectory }) => ({ +export type Paths = { + entrypointFilePath: string; + outputDirectory: string; +}; + +export const getNodeConfig = ({ + entrypointFilePath, + outputDirectory, +}: Paths): Configuration => ({ name: entrypointFilePath, entry: { index: entrypointFilePath }, target: "node", @@ -45,13 +50,13 @@ module.exports = ({ entrypointFilePath, outputDirectory }) => ({ path: outputDirectory, filename: (pathData) => - pathData.chunk.name === "index" + pathData.chunk?.name === "index" ? "index.js" - : `${pathData.chunk.name}/index.js`, + : `${pathData.chunk?.name}/index.js`, library: { - type: "commonjs2" - } + type: "commonjs2", + }, }, externalsPresets: { node: true }, diff --git a/packages/infrastructure/webpack/src/get-react-config.js b/packages/infrastructure/webpack/src/get-react-config-for.ts similarity index 83% rename from packages/infrastructure/webpack/src/get-react-config.js rename to packages/infrastructure/webpack/src/get-react-config-for.ts index b8be931329..945d5e4b91 100644 --- a/packages/infrastructure/webpack/src/get-react-config.js +++ b/packages/infrastructure/webpack/src/get-react-config-for.ts @@ -1,18 +1,20 @@ -const getNodeConfig = require("./get-node-config"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +import { getNodeConfig, Paths } from "./get-node-config"; +import MiniCssExtractPlugin from "mini-css-extract-plugin"; +import type { Configuration } from "webpack"; -module.exports = +export const getReactConfigFor = ({ miniCssExtractPluginLoader = MiniCssExtractPlugin.loader } = {}) => - ({ entrypointFilePath, outputDirectory }) => { + ({ entrypointFilePath, outputDirectory }: Paths): Configuration => { const nodeConfig = getNodeConfig({ entrypointFilePath, outputDirectory, }); + return { ...nodeConfig, plugins: [ - ...nodeConfig.plugins, + ...nodeConfig.plugins!, new MiniCssExtractPlugin({ filename: "[name].css", @@ -23,7 +25,7 @@ module.exports = ...nodeConfig.module, rules: [ - ...nodeConfig.module.rules, + ...nodeConfig.module!.rules!, { test: /\.s?css$/, diff --git a/packages/infrastructure/webpack/src/node-config.js b/packages/infrastructure/webpack/src/node-config.js deleted file mode 100644 index 97ade8cd37..0000000000 --- a/packages/infrastructure/webpack/src/node-config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require("path"); -const getNodeConfig = require("./get-node-config"); - -module.exports = getNodeConfig({ - entrypointFilePath: "./index.ts", - outputDirectory: path.resolve(process.cwd(), "dist"), -}); diff --git a/packages/infrastructure/webpack/src/node-config.ts b/packages/infrastructure/webpack/src/node-config.ts new file mode 100644 index 0000000000..2252cc4925 --- /dev/null +++ b/packages/infrastructure/webpack/src/node-config.ts @@ -0,0 +1,7 @@ +import path from "path"; +import { getNodeConfig } from "./get-node-config"; + +export const configForNode = getNodeConfig({ + entrypointFilePath: "./index.ts", + outputDirectory: path.resolve(process.cwd(), "dist"), +}); diff --git a/packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.test.js b/packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.test.ts similarity index 100% rename from packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.test.js rename to packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.test.ts diff --git a/packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.js b/packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.ts similarity index 57% rename from packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.js rename to packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.ts index 520d0c14c6..649ee8db74 100644 --- a/packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.js +++ b/packages/infrastructure/webpack/src/plugins/get-dependency-name/get-dependency-name.ts @@ -1,9 +1,7 @@ -const getDependencyName = (requireString) => { +export const getDependencyName = (requireString: string) => { const [a, b] = requireString.split("/"); const scoped = a.startsWith("@"); return scoped ? `${a}/${b}` : a; }; - -module.exports = { getDependencyName }; diff --git a/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js b/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js deleted file mode 100644 index 4193e50d23..0000000000 --- a/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js +++ /dev/null @@ -1,29 +0,0 @@ -const ExternalModuleFactoryPlugin = require("webpack/lib/ExternalModuleFactoryPlugin"); -const path = require("path"); - -const { - toModuleMatcherRegExp, -} = require("./to-module-matcher-reg-exp/to-module-matcher-reg-exp"); - -class MakePeerDependenciesExternalPlugin { - apply(compiler) { - compiler.hooks.compile.tap("compile", (params) => { - const peerDependencies = getPeerDependencies(); - - new ExternalModuleFactoryPlugin( - compiler.options.output.library.type, - peerDependencies.map(toModuleMatcherRegExp) - ).apply(params.normalModuleFactory); - }); - } -} - -const getPeerDependencies = () => { - const pathToPackageJson = path.resolve(process.cwd(), "package.json"); - - const packageJson = require(pathToPackageJson); - - return Object.keys(packageJson.peerDependencies || {}); -}; - -module.exports = { MakePeerDependenciesExternalPlugin }; diff --git a/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.ts b/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.ts new file mode 100644 index 0000000000..9ad7b5f5b1 --- /dev/null +++ b/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.ts @@ -0,0 +1,26 @@ +// @ts-ignore +import ExternalModuleFactoryPlugin from "webpack/lib/ExternalModuleFactoryPlugin"; +import path from "path"; +import { toModuleMatcherRegExp } from "./to-module-matcher-reg-exp/to-module-matcher-reg-exp"; +import { readJsonSync } from "fs-extra"; + +export class MakePeerDependenciesExternalPlugin { + apply(compiler: any) { + compiler.hooks.compile.tap("compile", (params: any) => { + const peerDependencies = getPeerDependencies(); + + new ExternalModuleFactoryPlugin( + compiler.options.output.library.type, + peerDependencies.map(toModuleMatcherRegExp) + ).apply(params.normalModuleFactory); + }); + } +} + +const getPeerDependencies = () => { + const pathToPackageJson = path.resolve(process.cwd(), "package.json"); + + const packageJson = readJsonSync(pathToPackageJson); + + return Object.keys(packageJson.peerDependencies || {}); +}; diff --git a/packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.js b/packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.js deleted file mode 100644 index 47331b9c76..0000000000 --- a/packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.js +++ /dev/null @@ -1,58 +0,0 @@ -const path = require("path"); -const { getDependencyName } = require("./get-dependency-name/get-dependency-name"); - -const pathToPackageJson = path.resolve(process.cwd(), "package.json"); - -class ProtectFromImportingNonDependencies { - apply(compiler) { - const dependencies = getDependenciesAndPeerDependencies(); - - const nodeModulesToBeResolved = new Set(); - - compiler.hooks.normalModuleFactory.tap("irrelevant", (normalModuleFactory) => { - normalModuleFactory.hooks.resolve.tap("irrelevant", (toBeResolved) => { - - const isSassDependency = toBeResolved.request.endsWith(".scss"); - const isLocalDependency = toBeResolved.request.startsWith("."); - const isDependencyOfDependency = - toBeResolved.context.includes("node_modules"); - - const dependencyName = getDependencyName(toBeResolved.request); - - const dependencyWeAreInterested = - !isSassDependency && !isLocalDependency && !isDependencyOfDependency && dependencyName; - - if (dependencyWeAreInterested) { - nodeModulesToBeResolved.add(dependencyName); - } - }); - } - ); - - compiler.hooks.afterCompile.tap("compile", () => { - const notSpecifiedDependencies = [...nodeModulesToBeResolved].filter( - (x) => !dependencies.includes(x) - ); - - if (notSpecifiedDependencies.length) { - throw new Error( - `Tried to import dependencies that are not specified in the package.json "${pathToPackageJson}". Add "${notSpecifiedDependencies.join( - '", "' - )}" to dependencies or peerDependencies.` - ); - } - }); - } -} -const getDependenciesAndPeerDependencies = () => { - const packageJson = require(pathToPackageJson); - - const dependencies = Object.keys(packageJson.dependencies || {}); - const peerDependencies = Object.keys(packageJson.peerDependencies || {}); - - return [...dependencies, ...peerDependencies]; -}; - -module.exports = { - ProtectFromImportingNonDependencies, -}; diff --git a/packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.ts b/packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.ts new file mode 100644 index 0000000000..4ea1b4cd56 --- /dev/null +++ b/packages/infrastructure/webpack/src/plugins/protect-from-importing-non-dependencies.ts @@ -0,0 +1,63 @@ +import path from "path"; +import { getDependencyName } from "./get-dependency-name/get-dependency-name"; +import { readJsonSync } from "fs-extra"; + +const pathToPackageJson = path.resolve(process.cwd(), "package.json"); + +export class ProtectFromImportingNonDependencies { + apply(compiler: any) { + const dependencies = getDependenciesAndPeerDependencies(); + + const nodeModulesToBeResolved = new Set(); + + compiler.hooks.normalModuleFactory.tap( + "irrelevant", + (normalModuleFactory: any) => { + normalModuleFactory.hooks.resolve.tap( + "irrelevant", + (toBeResolved: any) => { + const isSassDependency = toBeResolved.request.endsWith(".scss"); + const isLocalDependency = toBeResolved.request.startsWith("."); + const isDependencyOfDependency = + toBeResolved.context.includes("node_modules"); + + const dependencyName = getDependencyName(toBeResolved.request); + + const dependencyWeAreInterested = + !isSassDependency && + !isLocalDependency && + !isDependencyOfDependency && + dependencyName; + + if (dependencyWeAreInterested) { + nodeModulesToBeResolved.add(dependencyName); + } + } + ); + } + ); + + compiler.hooks.afterCompile.tap("compile", () => { + const notSpecifiedDependencies = [...nodeModulesToBeResolved].filter( + (x: any) => !dependencies.includes(x) + ); + + if (notSpecifiedDependencies.length) { + throw new Error( + `Tried to import dependencies that are not specified in the package.json "${pathToPackageJson}". Add "${notSpecifiedDependencies.join( + '", "' + )}" to dependencies or peerDependencies.` + ); + } + }); + } +} + +const getDependenciesAndPeerDependencies = () => { + const packageJson = readJsonSync(pathToPackageJson); + + const dependencies = Object.keys(packageJson.dependencies || {}); + const peerDependencies = Object.keys(packageJson.peerDependencies || {}); + + return [...dependencies, ...peerDependencies]; +}; diff --git a/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.js b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.js deleted file mode 100644 index 37e2c411c1..0000000000 --- a/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.js +++ /dev/null @@ -1,3 +0,0 @@ -const toModuleMatcherRegExp = x => new RegExp(`^${x}(/.*)*$`); - -module.exports = { toModuleMatcherRegExp }; diff --git a/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.js b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.ts similarity index 88% rename from packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.js rename to packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.ts index 6a48a4905d..4c0620541a 100644 --- a/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.js +++ b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.ts @@ -1,7 +1,7 @@ import { toModuleMatcherRegExp } from "./to-module-matcher-reg-exp"; describe('to-module-matcher-reg-exp', () => { - let regExp; + let regExp: RegExp; beforeEach(() => { regExp = toModuleMatcherRegExp("some-package"); @@ -10,7 +10,7 @@ describe('to-module-matcher-reg-exp', () => { it('given exactly matching package, matches', () => { const targetString = 'some-package'; - const [match] = targetString.match(regExp); + const [match] = targetString.match(regExp)!; expect(match).toBeTruthy() }); @@ -18,7 +18,7 @@ describe('to-module-matcher-reg-exp', () => { it('given matching package with entrypoint, matches', () => { const targetString = 'some-package/some-entrypoint'; - const [match] = targetString.match(regExp); + const [match] = targetString.match(regExp)!; expect(match).toBeTruthy() }); @@ -26,7 +26,7 @@ describe('to-module-matcher-reg-exp', () => { it('given matching package with directory, matches', () => { const targetString = 'some-package/some-directory/some-other-directory'; - const [match] = targetString.match(regExp); + const [match] = targetString.match(regExp)!; expect(match).toBeTruthy() }); diff --git a/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.ts b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.ts new file mode 100644 index 0000000000..4fffcc9971 --- /dev/null +++ b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.ts @@ -0,0 +1 @@ +export const toModuleMatcherRegExp = (x: string) => new RegExp(`^${x}(/.*)*$`); diff --git a/packages/infrastructure/webpack/src/react-config.js b/packages/infrastructure/webpack/src/react-config.js deleted file mode 100644 index 201a3c9a6b..0000000000 --- a/packages/infrastructure/webpack/src/react-config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require("path"); -const getReactConfig = require("./get-react-config"); - -module.exports = getReactConfig()({ - entrypointFilePath: "./index.ts", - outputDirectory: path.resolve(process.cwd(), "dist"), -}); diff --git a/packages/infrastructure/webpack/src/react-config.ts b/packages/infrastructure/webpack/src/react-config.ts new file mode 100644 index 0000000000..090db90704 --- /dev/null +++ b/packages/infrastructure/webpack/src/react-config.ts @@ -0,0 +1,7 @@ +import path from "path"; +import { getReactConfigFor } from "./get-react-config-for"; + +export const configForReact = getReactConfigFor()({ + entrypointFilePath: "./index.ts", + outputDirectory: path.resolve(process.cwd(), "dist"), +}); diff --git a/packages/infrastructure/webpack/tsconfig.json b/packages/infrastructure/webpack/tsconfig.json new file mode 100644 index 0000000000..9e140d79da --- /dev/null +++ b/packages/infrastructure/webpack/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@k8slens/typescript/config/base.json", + "include": ["**/*.ts", "**/*.tsx"], +} diff --git a/packages/infrastructure/webpack/webpack.config.ts b/packages/infrastructure/webpack/webpack.config.ts new file mode 100644 index 0000000000..5a803e4643 --- /dev/null +++ b/packages/infrastructure/webpack/webpack.config.ts @@ -0,0 +1,7 @@ +import { configForNode } from "./src/node-config"; +import nodeExternals from "webpack-node-externals"; + +export default { + ...configForNode, + externals: [nodeExternals({ modulesFromFile: true })], +};