From 35965505e74de80dcaaa6cec5e1508fdb26da6a6 Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Thu, 13 Apr 2023 10:43:01 +0300 Subject: [PATCH] feat: Allow dependencies to be bundled After this, only peerDependencies are externals. Co-authored-by: Mikko Aspiala Signed-off-by: Janne Savolainen --- package-lock.json | 4 +- packages/infrastructure/webpack/package.json | 3 +- .../webpack/src/get-node-config.js | 17 +----- .../make-peer-dependencies-external.js | 29 ++++++++++ .../to-module-matcher-reg-exp.js | 3 + .../to-module-matcher-reg-exp.test.js | 57 +++++++++++++++++++ 6 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js create mode 100644 packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.js create mode 100644 packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.js diff --git a/package-lock.json b/package-lock.json index 26f20b1333..4c4462a78e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37282,6 +37282,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", + "dev": true, "engines": { "node": ">=6" } @@ -42278,8 +42279,7 @@ "tailwindcss": "^3.3.1", "ts-loader": "^9.4.1", "webpack": "^5.77.0", - "webpack-cli": "^4.10.0", - "webpack-node-externals": "^3.0.0" + "webpack-cli": "^4.10.0" } }, "packages/infrastructure/webpack/node_modules/@types/estree": { diff --git a/packages/infrastructure/webpack/package.json b/packages/infrastructure/webpack/package.json index 960d49b216..1caee08983 100644 --- a/packages/infrastructure/webpack/package.json +++ b/packages/infrastructure/webpack/package.json @@ -33,7 +33,6 @@ "tailwindcss": "^3.3.1", "ts-loader": "^9.4.1", "webpack": "^5.77.0", - "webpack-cli": "^4.10.0", - "webpack-node-externals": "^3.0.0" + "webpack-cli": "^4.10.0" } } diff --git a/packages/infrastructure/webpack/src/get-node-config.js b/packages/infrastructure/webpack/src/get-node-config.js index 828201af04..f8876fc904 100644 --- a/packages/infrastructure/webpack/src/get-node-config.js +++ b/packages/infrastructure/webpack/src/get-node-config.js @@ -1,4 +1,5 @@ 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"); module.exports = ({ entrypointFilePath, outputDirectory }) => ({ @@ -17,6 +18,7 @@ module.exports = ({ entrypointFilePath, outputDirectory }) => ({ }, plugins: [ + new MakePeerDependenciesExternalPlugin(), new ProtectFromImportingNonDependencies(), new ForkTsCheckerPlugin({ @@ -46,21 +48,6 @@ module.exports = ({ entrypointFilePath, outputDirectory }) => ({ libraryTarget: "commonjs2", }, - externals: [ - nodeExternals({ modulesFromFile: true }), - - nodeExternals({ - modulesDir: path.resolve( - __dirname, - "..", - "..", - "..", - "..", - "node_modules" - ), - }), - ], - externalsPresets: { node: true }, node: { diff --git a/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js b/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js new file mode 100644 index 0000000000..4193e50d23 --- /dev/null +++ b/packages/infrastructure/webpack/src/plugins/make-peer-dependencies-external.js @@ -0,0 +1,29 @@ +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/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 new file mode 100644 index 0000000000..37e2c411c1 --- /dev/null +++ b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.js @@ -0,0 +1,3 @@ +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.js new file mode 100644 index 0000000000..6a48a4905d --- /dev/null +++ b/packages/infrastructure/webpack/src/plugins/to-module-matcher-reg-exp/to-module-matcher-reg-exp.test.js @@ -0,0 +1,57 @@ +import { toModuleMatcherRegExp } from "./to-module-matcher-reg-exp"; + +describe('to-module-matcher-reg-exp', () => { + let regExp; + + beforeEach(() => { + regExp = toModuleMatcherRegExp("some-package"); + }); + + it('given exactly matching package, matches', () => { + const targetString = 'some-package'; + + const [match] = targetString.match(regExp); + + expect(match).toBeTruthy() + }); + + it('given matching package with entrypoint, matches', () => { + const targetString = 'some-package/some-entrypoint'; + + const [match] = targetString.match(regExp); + + expect(match).toBeTruthy() + }); + + it('given matching package with directory, matches', () => { + const targetString = 'some-package/some-directory/some-other-directory'; + + const [match] = targetString.match(regExp); + + expect(match).toBeTruthy() + }); + + it('given package that starts with same name but is still different, does not match', () => { + const targetString = 'some-package-but-still-different'; + + const actual = targetString.match(regExp); + + expect(actual).toBeNull() + }); + + it('given package that starts with something else, does not match', () => { + const targetString = 'different-some-package'; + + const actual = targetString.match(regExp); + + expect(actual).toBeNull() + }); + + it('given irrelevant package, does not match', () => { + const targetString = 'some-other-package'; + + const actual = targetString.match(regExp); + + expect(actual).toBeNull() + }); +});