From f039f7b8f69b3c8b9564714890b2fe2d4cd8a22d Mon Sep 17 00:00:00 2001 From: cha0s Date: Thu, 30 Nov 2023 21:41:42 -0600 Subject: [PATCH] feat: webpack 5 --- CHANGELOG.md | 74 ++++++ TODO.md | 4 + lerna.json | 2 +- package.json | 39 +-- packages/core/CHANGELOG.md | 57 +++++ packages/core/build/.eslintrc.js | 4 - packages/core/build/.neutrinorc.js | 74 ------ packages/core/build/dox/concepts/build.md | 22 +- packages/core/build/dox/concepts/hooks.md | 2 +- packages/core/build/dox/hooks.js | 79 +++--- packages/core/build/eslint.config.js | 3 + packages/core/build/webpack.config.js | 9 +- packages/core/package.json | 49 ++-- packages/core/src/bootstrap/autoentry.js | 50 ---- packages/core/src/bootstrap/fleck.js | 74 ------ .../core/src/bootstrap/fleck.neutrinorc.js | 35 --- packages/core/src/index.js | 8 - packages/core/src/{bootstrap => }/require.js | 0 .../core/src/server/build/.eslint.defaults.js | 50 ---- .../core/src/server/build/babel.config.js | 8 +- .../src/server/build/default.eslint.config.js | 92 +++++++ .../build/{eslintrc.js => eslint.config.js} | 24 +- .../src/server/build/fleck.webpack.config.js | 135 +++++++++++ .../src/server/build/fleckspack.config.js | 95 ++++++++ .../core/src/server/build/webpack.config.js | 84 ------- packages/core/src/server/commands.js | 38 +-- packages/core/src/server/flecks.js | 51 ++-- packages/core/src/server/index.js | 77 +++--- packages/core/src/server/webpack.js | 163 +++++++++++++ packages/core/test/one/index.js | 4 +- packages/core/test/two/index.js | 4 +- packages/create-app/CHANGELOG.md | 38 +++ packages/create-app/build/fleck.neutrinorc.js | 51 ---- .../create-app/build/fleck.webpack.config.js | 17 ++ packages/create-app/package.json | 6 +- .../template/package.json.noconflict | 6 +- packages/create-fleck/CHANGELOG.md | 38 +++ .../create-fleck/build/fleck.neutrinorc.js | 51 ---- .../build/fleck.webpack.config.js | 17 ++ packages/create-fleck/package.json | 8 +- .../template/package.json.noconflict | 4 +- packages/db/CHANGELOG.md | 38 +++ packages/db/package.json | 6 +- packages/db/src/connection.js | 4 +- packages/docker/CHANGELOG.md | 38 +++ packages/docker/package.json | 6 +- packages/docker/src/start-container.js | 4 +- packages/dox/CHANGELOG.md | 43 ++++ packages/dox/package.json | 6 +- packages/dox/src/generate.js | 29 ++- packages/dox/src/parser.js | 6 +- packages/electron/CHANGELOG.md | 49 ++++ packages/electron/package.json | 15 +- packages/electron/src/server/index.js | 37 +-- packages/fleck/CHANGELOG.md | 44 ++++ packages/fleck/package.json | 8 +- .../src/server/build/fleck.neutrinorc.js | 42 ---- .../src/server/build/fleck.webpack.config.js | 7 + packages/fleck/src/server/commands.js | 8 +- packages/fleck/src/server/index.js | 6 +- packages/governor/CHANGELOG.md | 38 +++ packages/governor/package.json | 8 +- packages/react/CHANGELOG.md | 45 ++++ packages/react/build/.eslint.defaults.js | 5 - packages/react/package.json | 22 +- packages/react/src/server.js | 20 +- packages/react/src/ssr.js | 12 +- packages/redis/CHANGELOG.md | 38 +++ packages/redis/package.json | 6 +- packages/redux/CHANGELOG.md | 43 ++++ packages/redux/build/.eslint.defaults.js | 5 - packages/redux/package.json | 6 +- packages/repl/CHANGELOG.md | 38 +++ packages/repl/package.json | 6 +- packages/repl/src/repl.js | 4 +- packages/server/CHANGELOG.md | 44 ++++ packages/server/package.json | 18 +- packages/server/src/index.js | 5 +- packages/server/src/runtime.js | 4 +- packages/server/src/server/build/runtime.js | 146 +++++------ .../src/server/build/server.neutrinorc.js | 102 -------- .../src/server/build/server.webpack.config.js | 58 +++++ packages/server/src/server/build/start.js | 25 +- packages/socket/CHANGELOG.md | 38 +++ packages/socket/build/.eslint.defaults.js | 5 - packages/socket/package.json | 8 +- packages/socket/src/index.js | 2 +- packages/socket/src/packet/index.js | 2 +- packages/socket/src/server/create-intercom.js | 4 +- packages/user/CHANGELOG.md | 39 +++ packages/user/package.json | 10 +- packages/user/src/packets/logout.js | 4 +- packages/web/CHANGELOG.md | 45 ++++ packages/web/build/.eslint.defaults.js | 5 - packages/web/build/fleck.neutrinorc.js | 46 ---- packages/web/build/fleck.webpack.config.js | 34 +++ packages/web/package.json | 42 ++-- packages/web/src/runtime.js | 4 +- packages/web/src/server/augment-build.js | 129 ++++++---- packages/web/src/server/build/dev-server.js | 27 --- packages/web/src/server/build/runtime.js | 226 +++++++++--------- packages/web/src/server/build/template.ejs | 9 +- .../web/src/server/build/wait-for-manifest.js | 4 +- .../src/server/build/web-vendor.neutrinorc.js | 79 ------ .../server/build/web-vendor.webpack.config.js | 56 +++++ .../web/src/server/build/web.neutrinorc.js | 201 ---------------- .../src/server/build/web.webpack.config.js | 190 +++++++++++++++ packages/web/src/server/http.js | 20 +- packages/web/src/server/index.js | 39 ++- 109 files changed, 2355 insertions(+), 1653 deletions(-) delete mode 100644 packages/core/build/.eslintrc.js delete mode 100644 packages/core/build/.neutrinorc.js create mode 100644 packages/core/build/eslint.config.js delete mode 100644 packages/core/src/bootstrap/autoentry.js delete mode 100644 packages/core/src/bootstrap/fleck.js delete mode 100644 packages/core/src/bootstrap/fleck.neutrinorc.js rename packages/core/src/{bootstrap => }/require.js (100%) delete mode 100644 packages/core/src/server/build/.eslint.defaults.js create mode 100644 packages/core/src/server/build/default.eslint.config.js rename packages/core/src/server/build/{eslintrc.js => eslint.config.js} (65%) create mode 100644 packages/core/src/server/build/fleck.webpack.config.js create mode 100644 packages/core/src/server/build/fleckspack.config.js delete mode 100644 packages/core/src/server/build/webpack.config.js create mode 100644 packages/core/src/server/webpack.js delete mode 100644 packages/create-app/build/fleck.neutrinorc.js create mode 100644 packages/create-app/build/fleck.webpack.config.js delete mode 100644 packages/create-fleck/build/fleck.neutrinorc.js create mode 100644 packages/create-fleck/build/fleck.webpack.config.js create mode 100644 packages/electron/CHANGELOG.md delete mode 100644 packages/fleck/src/server/build/fleck.neutrinorc.js create mode 100644 packages/fleck/src/server/build/fleck.webpack.config.js delete mode 100644 packages/react/build/.eslint.defaults.js delete mode 100644 packages/redux/build/.eslint.defaults.js delete mode 100644 packages/server/src/server/build/server.neutrinorc.js create mode 100644 packages/server/src/server/build/server.webpack.config.js delete mode 100644 packages/socket/build/.eslint.defaults.js delete mode 100644 packages/web/build/.eslint.defaults.js delete mode 100644 packages/web/build/fleck.neutrinorc.js create mode 100644 packages/web/build/fleck.webpack.config.js delete mode 100644 packages/web/src/server/build/dev-server.js delete mode 100644 packages/web/src/server/build/web-vendor.neutrinorc.js create mode 100644 packages/web/src/server/build/web-vendor.webpack.config.js delete mode 100644 packages/web/src/server/build/web.neutrinorc.js create mode 100644 packages/web/src/server/build/web.webpack.config.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ead41cb..5a37b70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,80 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/monorepo + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + + +### Bug Fixes + +* dox ([2d7c2f9](https://github.com/cha0s/flecks/commit/2d7c2f93dc673e12ce02263d54a2f8b309ed29fe)) + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* async for parity ([780fa43](https://github.com/cha0s/flecks/commit/780fa433e156fbc7adad0f97aaebd3c821f40dee)) +* avoid FOUC on dev ([18e2bb9](https://github.com/cha0s/flecks/commit/18e2bb9446b2ead51800f2dd2d094cbe8c6282f8)) +* babel devs always breaking things ([cc8a35a](https://github.com/cha0s/flecks/commit/cc8a35a4b25ee730feb8cb1c978d3f29238e1f64)) +* coerce the number ([820e390](https://github.com/cha0s/flecks/commit/820e390744d9a16a145db72c2ea7a433d2273d57)) +* complex aliasing ([4ba2b51](https://github.com/cha0s/flecks/commit/4ba2b5113657f4426d8e976fe9a77d797378475a)) +* conditional electron inclusion ([a959722](https://github.com/cha0s/flecks/commit/a9597225ca250fd9acee28c3feb284a979ee3111)) +* core neutrino config ([7feac4a](https://github.com/cha0s/flecks/commit/7feac4a87b711ec9e48fa5b41be6d52b251a4e61)) +* default source-map-support install ([ed2aa6a](https://github.com/cha0s/flecks/commit/ed2aa6a3c1354d7dfc4290e431c50779b8be2437)) +* doc ([9a5fb07](https://github.com/cha0s/flecks/commit/9a5fb07d81fea6b5bb915ef2efe5973c186392aa)) +* fake context ([3976078](https://github.com/cha0s/flecks/commit/3976078bebdf426bd2fa027f8d4e553149a14d02)) +* hook dox ([aa78144](https://github.com/cha0s/flecks/commit/aa7814462801a9fef2324b8b5be231f288f23179)) +* mocha error propagation ([1f11aac](https://github.com/cha0s/flecks/commit/1f11aac027e0699b821c2bc9f31bdfe3fd61a2d0)) +* paths got broken somehow ([c7bbc48](https://github.com/cha0s/flecks/commit/c7bbc48d3a4c4db2b57c1002b73f4baac0b80172)) +* test fails -> nonzero process code ([1f01189](https://github.com/cha0s/flecks/commit/1f0118914393d8b16913aad25eef81aaadac4e68)) +* tests ([a982224](https://github.com/cha0s/flecks/commit/a98222495ebffa555db426e480e5f453148c240a)) + + +### Features + +* "wtf, you can't just take @babel/register, give it an actual API, and make it work simultaneously across multiple roots" ([82e22c3](https://github.com/cha0s/flecks/commit/82e22c3eef69f13b6b8645667d3362d49d3b3e6b)) +* add electron for dox ([3e5a90d](https://github.com/cha0s/flecks/commit/3e5a90db648662a49bb7988df401a416ada153a2)) +* awesomerific module resolution ([60c844d](https://github.com/cha0s/flecks/commit/60c844d58b294df0d9cf0be741266fdd8dd53a33)) +* crazy hax to make our ESLint experience dope ([467f0c9](https://github.com/cha0s/flecks/commit/467f0c9ad30521f841665a7b939ad4d9b7c8b53c)) +* electron ([67723d1](https://github.com/cha0s/flecks/commit/67723d1d356af94a1bbbc38c734722d4409ba057)) +* electron with start-server-webpack-plugin ([1ade829](https://github.com/cha0s/flecks/commit/1ade8294a1d825cfa4361daa245c50ff05f6fa79)) +* **electron:** devtools ([10d59e1](https://github.com/cha0s/flecks/commit/10d59e16edc6e8828c019fa728f19546a4c55042)) +* html template specifier ([5791c7a](https://github.com/cha0s/flecks/commit/5791c7a89433f16c1efea045a00ab488975c6dab)) +* per-entry styles ([d43316a](https://github.com/cha0s/flecks/commit/d43316a43635ea19338a6a1ce917f9b2d308c977)) +* **react:** configure in web's absence ([754646d](https://github.com/cha0s/flecks/commit/754646d4a1df63de44f91e5a3184ebd9c75afd95)) +* reopen closed ([11c61b3](https://github.com/cha0s/flecks/commit/11c61b3d7284cd8403660e71c314aba276244d8b)) +* ServerFlecks::register(BuildConfig|Resolver) ([013f980](https://github.com/cha0s/flecks/commit/013f980f583277e2e48e74e53ff148f12ebb345a)) +* support mjs ([7935597](https://github.com/cha0s/flecks/commit/79355977830a3778ef2414ece4d2812bc2e7ea0c)) +* UserRequired ([9b5f6f4](https://github.com/cha0s/flecks/commit/9b5f6f4818afaec76ee941c8d2c4795912234ee8)) +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) diff --git a/TODO.md b/TODO.md index f03c90e..2efb25d 100644 --- a/TODO.md +++ b/TODO.md @@ -32,4 +32,8 @@ # Next +# Webpack 5 +fixup no-param-reassign +warningsFilter deprecated +refactor stats diff --git a/lerna.json b/lerna.json index fbd50b2..a886e6f 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,5 @@ "packages": [ "packages/*" ], - "version": "1.4.1" + "version": "2.0.3" } diff --git a/package.json b/package.json index fd51e1d..cb6af16 100644 --- a/package.json +++ b/package.json @@ -5,31 +5,34 @@ "url": "https://github.com/cha0s/flecks.git" }, "scripts": { + "bfp": "for i in $(npx lerna exec pwd); do cd $i; bfp || break; done; cd ../..", "build": "lerna run build", + "clean": "for i in $(npx lerna exec pwd); do cd $i; rm -rf yarn.lock node_modules; yarn; done; cd ../..", "dox": "FLECKS_ENV_FLECKS_DOX_SERVER_filenameRewriters=\"{\\\"^@flecks/(.*):([0-9]+):([0-9]+)\\\": \\\"@flecks/\\$1:\\$2:\\$3\\\"}\" yarn flecks dox", "lint": "lerna run lint", "publish": "lerna publish --conventional-commits --contents=dist --registry https://registry.npmjs.org", + "refresh": "npm run clean && npm run bfp", "test": "lerna run test --no-bail -- --silent" }, "dependencies": {}, "devDependencies": { - "@flecks/core": "^1.4.1", - "@flecks/create-app": "^1.4.1", - "@flecks/create-fleck": "^1.4.1", - "@flecks/db": "^1.4.1", - "@flecks/docker": "^1.4.1", - "@flecks/dox": "^1.4.1", - "@flecks/electron": "^1.4.1", - "@flecks/fleck": "^1.4.1", - "@flecks/governor": "^1.4.1", - "@flecks/react": "^1.4.1", - "@flecks/redis": "^1.4.1", - "@flecks/redux": "^1.4.1", - "@flecks/repl": "^1.4.1", - "@flecks/server": "^1.4.1", - "@flecks/socket": "^1.4.1", - "@flecks/user": "^1.4.1", - "@flecks/web": "^1.4.1", - "lerna": "^3.22.1" + "@flecks/core": "*", + "@flecks/create-app": "*", + "@flecks/create-fleck": "*", + "@flecks/db": "*", + "@flecks/docker": "*", + "@flecks/dox": "*", + "@flecks/electron": "*", + "@flecks/fleck": "*", + "@flecks/governor": "*", + "@flecks/react": "*", + "@flecks/redis": "*", + "@flecks/redux": "*", + "@flecks/repl": "*", + "@flecks/server": "*", + "@flecks/socket": "*", + "@flecks/user": "*", + "@flecks/web": "*", + "lerna": "^7.4.2" } } diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 1c17f26..b410d3f 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -3,6 +3,63 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/core + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + + +### Bug Fixes + +* dox ([2d7c2f9](https://github.com/cha0s/flecks/commit/2d7c2f93dc673e12ce02263d54a2f8b309ed29fe)) + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* babel devs always breaking things ([cc8a35a](https://github.com/cha0s/flecks/commit/cc8a35a4b25ee730feb8cb1c978d3f29238e1f64)) +* coerce the number ([820e390](https://github.com/cha0s/flecks/commit/820e390744d9a16a145db72c2ea7a433d2273d57)) +* complex aliasing ([4ba2b51](https://github.com/cha0s/flecks/commit/4ba2b5113657f4426d8e976fe9a77d797378475a)) +* core neutrino config ([7feac4a](https://github.com/cha0s/flecks/commit/7feac4a87b711ec9e48fa5b41be6d52b251a4e61)) +* default source-map-support install ([ed2aa6a](https://github.com/cha0s/flecks/commit/ed2aa6a3c1354d7dfc4290e431c50779b8be2437)) +* fake context ([3976078](https://github.com/cha0s/flecks/commit/3976078bebdf426bd2fa027f8d4e553149a14d02)) +* tests ([a982224](https://github.com/cha0s/flecks/commit/a98222495ebffa555db426e480e5f453148c240a)) + + +### Features + +* "wtf, you can't just take @babel/register, give it an actual API, and make it work simultaneously across multiple roots" ([82e22c3](https://github.com/cha0s/flecks/commit/82e22c3eef69f13b6b8645667d3362d49d3b3e6b)) +* awesomerific module resolution ([60c844d](https://github.com/cha0s/flecks/commit/60c844d58b294df0d9cf0be741266fdd8dd53a33)) +* crazy hax to make our ESLint experience dope ([467f0c9](https://github.com/cha0s/flecks/commit/467f0c9ad30521f841665a7b939ad4d9b7c8b53c)) +* ServerFlecks::register(BuildConfig|Resolver) ([013f980](https://github.com/cha0s/flecks/commit/013f980f583277e2e48e74e53ff148f12ebb345a)) +* support mjs ([7935597](https://github.com/cha0s/flecks/commit/79355977830a3778ef2414ece4d2812bc2e7ea0c)) +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/core diff --git a/packages/core/build/.eslintrc.js b/packages/core/build/.eslintrc.js deleted file mode 100644 index ea05650..0000000 --- a/packages/core/build/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -const neutrino = require('neutrino'); - -// eslint-disable-next-line import/no-dynamic-require -module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).eslintrc(); diff --git a/packages/core/build/.neutrinorc.js b/packages/core/build/.neutrinorc.js deleted file mode 100644 index eb7167d..0000000 --- a/packages/core/build/.neutrinorc.js +++ /dev/null @@ -1,74 +0,0 @@ -const {chmod} = require('fs'); -const {join} = require('path'); - -const airbnb = require('@neutrinojs/airbnb'); -const banner = require('@neutrinojs/banner'); -const copy = require('@neutrinojs/copy'); -const glob = require('glob'); - -const fleck = require('../src/bootstrap/fleck'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -const config = require('../src/bootstrap/fleck.neutrinorc'); - -// Dotfiles. -config.use.push(({config}) => { - ['eslintrc'].forEach((filename) => { - config - .entry(`server/build/.${filename}`) - .clear() - .add(`./src/server/build/${filename}`); - }) -}); - -// Tests. -config.use.push(({config}) => { - // Test entrypoint. - const testPaths = glob.sync(join(FLECKS_CORE_ROOT, 'test/*.js')); - testPaths.push(...glob.sync(join(FLECKS_CORE_ROOT, `test/platforms/server/*.js`))); - if (testPaths.length > 0) { - const testEntry = config.entry('test').clear(); - testPaths.forEach((path) => testEntry.add(path)); - } -}); - -// Fleck build configuration. -config.use.unshift(fleck()); - -// AirBnb linting. -config.use.unshift( - airbnb({ - eslint: { - baseConfig: require('../src/server/build/.eslint.defaults'), - }, - }), -); - -// Include a shebang and set the executable bit.. -config.use.push(banner({ - banner: '#!/usr/bin/env node', - include: /^cli\.js$/, - pluginId: 'shebang', - raw: true, -})) -config.use.push(({config}) => { - config - .plugin('executable') - .use(class Executable { - - apply(compiler) { - compiler.hooks.afterEmit.tapAsync( - 'Executable', - (compilation, callback) => { - chmod(join(__dirname, '..', 'dist', 'cli.js'), 0o755, callback); - }, - ) - } - - }); -}); - -module.exports = config; diff --git a/packages/core/build/dox/concepts/build.md b/packages/core/build/dox/concepts/build.md index 2f852f4..26ae3bf 100644 --- a/packages/core/build/dox/concepts/build.md +++ b/packages/core/build/dox/concepts/build.md @@ -71,28 +71,28 @@ Have fun! The flecks server provides an interface (`flecks.buildConfig()`) for gathering configuration files from the `build` directory. The resolution order is determined by a few variables: -- `filename` specifies the name of the configuration file, e.g. `server.neutrinorc.js`. +- `filename` specifies the name of the configuration file, e.g. `server.webpack.config.js`. -- `general` specifies a general variation of the given configuration. The general form of `server.neutrinorc.js` is `.neutrinorc.js`. +- `general` specifies a general variation of the given configuration. The general form of `server.webpack.config.js` is `webpack.config.js`. - `root` specifies an alternative location to search. Defaults to `FLECKS_CORE_ROOT`. -- `fleck` specifies the fleck owning the configuration. `@flecks/server` owns `server.neutrinorc.js`. +- `fleck` specifies the fleck owning the configuration. `@flecks/server` owns `server.webpack.config.js`. Given these considerations, and supposing we had the above variables set like: ```javascript -const filename = 'server.neutrinorc.js'; -const general = '.neutrinorc.js'; +const filename = 'server.webpack.config.js'; +const general = 'webpack.config.js'; const root = '/foo/bar/baz'; const fleck = '@flecks/server'; ``` Flecks will then search the following paths top-down until it finds the build configuration: -- `/foo/bar/baz/build/server.neutrinorc.js` -- `/foo/bar/baz/build/.neutrinorc.js` -- `${FLECKS_CORE_ROOT}/build/server.neutrinorc.js` -- `${FLECKS_CORE_ROOT}/build/.neutrinorc.js` -- `@flecks/server/build/server.neutrinorc.js` -- `@flecks/server/build/.neutrinorc.js` +- `/foo/bar/baz/build/server.webpack.config.js` +- `/foo/bar/baz/build/webpack.config.js` +- `${FLECKS_CORE_ROOT}/build/server.webpack.config.js` +- `${FLECKS_CORE_ROOT}/build/webpack.config.js` +- `@flecks/server/build/server.webpack.config.js` +- `@flecks/server/build/webpack.config.js` diff --git a/packages/core/build/dox/concepts/hooks.md b/packages/core/build/dox/concepts/hooks.md index 4bbe26f..fa4bd2e 100755 --- a/packages/core/build/dox/concepts/hooks.md +++ b/packages/core/build/dox/concepts/hooks.md @@ -161,7 +161,7 @@ export const hooks = { If you think about the example above, you might realize that it will become a lot of typing to keep adding new models over time. Provider hooks exist to reduce this maintenance burden for you. -Webpack provides an API called [require.context](https://v4.webpack.js.org/guides/dependency-management/#requirecontext), and the flecks provider is optimized to work with this API. +Webpack provides an API called [require.context](https://webpack.js.org/guides/dependency-management/#requirecontext), and the flecks provider is optimized to work with this API. Supposing our fleck is structured like so: diff --git a/packages/core/build/dox/hooks.js b/packages/core/build/dox/hooks.js index edd1ad6..361dbff 100644 --- a/packages/core/build/dox/hooks.js +++ b/packages/core/build/dox/hooks.js @@ -1,32 +1,40 @@ export const hooks = { /** - * Hook into neutrino configuration. + * Hook into webpack configuration. * @param {string} target The build target; e.g. `server`. - * @param {Object} config The neutrino configuration. + * @param {Object} config The webpack configuration. + * @param {Object} env The webpack environment. + * @param {Object} argv The webpack commandline arguments. + * @see {@link https://webpack.js.org/configuration/configuration-types/#exporting-a-function} */ - '@flecks/core.build': (target, config) => { + '@flecks/core.build': (target, config, env, argv) => { if ('something' === target) { - config[target].use.push(someNeutrinoMiddleware); + if ('production' === argv.mode) { + config.plugins.push(new SomePlugin()); + } } }, /** - * Alter build configurations after they have been hooked. - * @param {Object} configs The neutrino configurations. - */ + * Alter build configurations after they have been hooked. + * @param {Object} configs The webpack configurations keyed by target. + * @param {Object} env The webpack environment. + * @param {Object} argv The webpack commandline arguments. + * @see {@link https://webpack.js.org/configuration/configuration-types/#exporting-a-function} + */ '@flecks/core.build.alter': (configs) => { - // Maybe we want to do something if a config exists..? - if (configs.something) { + // Maybe we want to do something if a target exists..? + if (configs.someTarget) { // Do something... - // And then maybe we want to remove it from the build configuration..? - delete configs.something; + // And then maybe we want to remove it from the build configuration..? That's ok! + delete configs.someTarget; } }, /** - * Register build configuration. - */ + * Register build configuration. + */ '@flecks/core.build.config': () => [ /** * If you document your config files like this, documentation will be automatically @@ -40,8 +48,8 @@ export const hooks = { ], /** - * Define CLI commands. - */ + * Define CLI commands. + */ '@flecks/core.commands': (program) => ({ // So this could be invoked like: // npx flecks something -t --blow-up blah @@ -61,8 +69,8 @@ export const hooks = { }), /** - * Define configuration. - */ + * Define configuration. + */ '@flecks/core.config': () => ({ whatever: 'configuration', your: 1337, @@ -74,45 +82,34 @@ export const hooks = { }), /** - * Invoked when a fleck is HMR'd - * @param {string} path The path of the fleck - * @param {Module} updatedFleck The updated fleck module. - */ - '@flecks/core.hmr': (path, updatedFleck) => { + * Invoked when a fleck is HMR'd + * @param {string} path The path of the fleck + * @param {Module} updatedFleck The updated fleck module. + */ + '@flecks/core.hmr': (path, updatedFleck) => { if ('my-fleck' === path) { updatedFleck.doSomething(); } }, /** - * Invoked when a gathered class is HMR'd. - * @param {constructor} Class The class. - * @param {string} hook The gather hook; e.g. `@flecks/db/server.models`. - */ + * Invoked when a gathered class is HMR'd. + * @param {constructor} Class The class. + * @param {string} hook The gather hook; e.g. `@flecks/db/server.models`. + */ '@flecks/core.hmr.gathered': (Class, hook) => { // Do something with Class... }, /** - * Invoked when the application is starting. Use for order-independent initialization tasks. - */ + * Invoked when the application is starting. Use for order-independent initialization tasks. + */ '@flecks/core.starting': (flecks) => { flecks.set('$my-fleck/value', initializeMyValue()); }, /** - * Define neutrino build targets. - */ + * Define build targets. + */ '@flecks/core.targets': () => ['sometarget'], - - /** - * Hook into webpack configuration. - * @param {string} target The build target; e.g. `server`. - * @param {Object} config The neutrino configuration. - */ - '@flecks/core.webpack': (target, config) => { - if ('something' === target) { - config.stats = 'verbose'; - } - }, }; diff --git a/packages/core/build/eslint.config.js b/packages/core/build/eslint.config.js new file mode 100644 index 0000000..7d44f73 --- /dev/null +++ b/packages/core/build/eslint.config.js @@ -0,0 +1,3 @@ +const defaultConfigFn = require('../src/server/build/default.eslint.config'); + +module.exports = defaultConfigFn(); diff --git a/packages/core/build/webpack.config.js b/packages/core/build/webpack.config.js index 31b6f38..b5cd9c4 100644 --- a/packages/core/build/webpack.config.js +++ b/packages/core/build/webpack.config.js @@ -1,3 +1,8 @@ -const neutrino = require('neutrino'); +const configFn = require('../src/server/build/fleck.webpack.config'); +const {executable} = require('../src/server/webpack'); -module.exports = neutrino(require('./.neutrinorc')).webpack(); +module.exports = (env, argv) => { + const config = configFn(env, argv); + config.plugins.push(...executable()); + return config; +}; diff --git a/packages/core/package.json b/packages/core/package.json index ba37f15..d35a63e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "author": "cha0s", "license": "MIT", @@ -18,7 +18,7 @@ "scripts": { "build": "NODE_PATH=./node_modules webpack --config ./build/webpack.config.js --mode production", "clean": "rm -rf dist node_modules yarn.lock && yarn", - "lint": "NODE_PATH=./node_modules eslint --config ./build/.eslintrc.js --format codeframe --ext mjs,js .", + "lint": "NODE_PATH=./node_modules eslint --config ./build/eslint.config.js .", "postversion": "cp package.json dist", "test": "npm run build && mocha -t 10000 --colors ./dist/test.js" }, @@ -30,14 +30,16 @@ "index.js.map", "server.js", "server.js.map", - "server/build/.eslint.defaults.js", - "server/build/.eslint.defaults.js.map", - "server/build/.eslintrc.js", - "server/build/.eslintrc.js.map", "server/build/babel.config.js", "server/build/babel.config.js.map", - "server/build/webpack.config.js", - "server/build/webpack.config.js.map", + "server/build/default.eslint.config.js", + "server/build/default.eslint.config.js.map", + "server/build/eslint.config.js", + "server/build/eslint.config.js.map", + "server/build/fleck.webpack.config.js", + "server/build/fleck.webpack.config.js.map", + "server/build/fleckspack.config.js", + "server/build/fleckspack.config.js.map", "src", "start.js", "start.js.map", @@ -47,42 +49,51 @@ ], "dependencies": { "@babel/core": "^7.12.10", + "@babel/eslint-parser": "^7.23.3", + "@babel/eslint-plugin": "^7.22.10", "@babel/plugin-proposal-optional-chaining": "^7.12.16", "@babel/plugin-transform-regenerator": "^7.16.7", "@babel/preset-env": "^7.12.11", "@babel/register": "7.13.0", - "@neutrinojs/airbnb": "^9.4.0", - "@neutrinojs/banner": "^9.4.0", - "@neutrinojs/clean": "^9.5.0", - "@neutrinojs/compile-loader": "^9.5.0", - "@neutrinojs/copy": "^9.4.0", + "babel-loader": "^9.1.3", "babel-merge": "^3.0.0", "babel-plugin-prepend": "^1.0.2", "chai": "4.2.0", "chai-as-promised": "7.1.1", "commander": "^8.3.0", + "copy-webpack-plugin": "^11.0.0", "debug": "4.3.1", "enhanced-resolve": "^5.9.2", "eslint": "^7.0.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-airbnb-base": "^15.0.0", "eslint-import-resolver-webpack": "0.13.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-jsx-a11y": "^6.8.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-webpack-plugin": "^4.0.1", + "glob": "^7.2.0", + "globals": "^13.23.0", "js-yaml": "4.1.0", "jsonparse": "^1.3.1", "lodash.flatten": "^4.4.0", "lodash.get": "^4.4.2", - "lodash.intersection": "^4.4.0", + "lodash.intersectionby": "4.7.0", "lodash.set": "^4.3.2", "lodash.without": "^4.4.0", - "neutrino": "^9.4.0", + "path-browserify": "^1.0.1", "pirates": "^4.0.5", + "process": "^0.11.10", "rimraf": "^3.0.2", + "source-map-loader": "4.0.1", "source-map-support": "0.5.19", "supports-color": "9.2.1", - "webpack": "^4", - "webpack-cli": "^3", - "webpack-node-externals": "2.5.2" + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-node-externals": "^3.0.0" }, "devDependencies": { - "glob": "^7.2.0", "mocha": "^8.3.2" } } diff --git a/packages/core/src/bootstrap/autoentry.js b/packages/core/src/bootstrap/autoentry.js deleted file mode 100644 index 8e6a533..0000000 --- a/packages/core/src/bootstrap/autoentry.js +++ /dev/null @@ -1,50 +0,0 @@ -const { - basename, - dirname, - extname, - join, -} = require('path'); - -const R = require('./require'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -const resolveValidModulePath = (source) => (path) => { - // Does the file resolve as source? - try { - R.resolve(`${source}/${path}`); - return true; - } - catch (error) { - const ext = extname(path); - // Try the implicit [path]/index[.ext] variation. - try { - R.resolve(`${source}/${dirname(path)}/${basename(path, ext)}/index${ext}`); - return true; - } - catch (error) { - return false; - } - } -}; - -module.exports = () => ({config, options}) => { - const {packageJson: {name, files = []}, source} = options; - // index is not taken for granted. - config.entryPoints.delete('index'); - // Alias this package. - config.resolve.alias - .set(name, join(FLECKS_CORE_ROOT, 'src')); - // Calculate entry points from `files`. - files - .filter(resolveValidModulePath(source)) - .forEach((file) => { - const trimmed = join(dirname(file), basename(file, extname(file))); - config - .entry(trimmed) - .clear() - .add(`./src/${trimmed}`); - }); -}; diff --git a/packages/core/src/bootstrap/fleck.js b/packages/core/src/bootstrap/fleck.js deleted file mode 100644 index e67a45b..0000000 --- a/packages/core/src/bootstrap/fleck.js +++ /dev/null @@ -1,74 +0,0 @@ -const clean = require('@neutrinojs/clean'); -const compileLoader = require('@neutrinojs/compile-loader'); -const babelMerge = require('babel-merge'); -const nodeExternals = require('webpack-node-externals'); - -const R = require('./require'); - -module.exports = ({ - babel = {}, - targets = { - esmodules: true, - node: 'current', - }, -} = {}) => (neutrino) => { - const {config, options} = neutrino; - const {name} = options.packageJson; - neutrino.use( - compileLoader({ - include: [options.source, options.tests], - babel: babelMerge( - { - plugins: [R.resolve('@babel/plugin-syntax-dynamic-import')], - presets: [ - [ - R.resolve('@babel/preset-env'), - { - shippedProposals: true, - targets, - }, - ], - ], - }, - babel, - ), - }), - ); - neutrino.use(clean({cleanStaleWebpackAssets: false})); - /* eslint-disable indent */ - config - .context(options.root) - .devtool('source-map') - .externals(nodeExternals({importType: 'umd'})) - .target('node') - .resolve - .extensions - .merge([ - '.wasm', - ...options.extensions.map((ext) => `.${ext}`), - '.json', - ]) - .end() - .end() - .stats({ - children: false, - colors: true, - entrypoints: false, - modules: false, - }) - .optimization - .splitChunks(false) - .runtimeChunk(false) - .end() - .output - .filename('[name].js') - .library(name) - .libraryTarget('umd') - .path(options.output) - .umdNamedDefine(true) - .end() - .node - .set('__dirname', false) - .set('__filename', false); - /* eslint-enable indent */ -}; diff --git a/packages/core/src/bootstrap/fleck.neutrinorc.js b/packages/core/src/bootstrap/fleck.neutrinorc.js deleted file mode 100644 index 535d0c1..0000000 --- a/packages/core/src/bootstrap/fleck.neutrinorc.js +++ /dev/null @@ -1,35 +0,0 @@ -const copy = require('@neutrinojs/copy'); - -const autoentry = require('./autoentry'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -module.exports = { - options: { - output: 'dist', - root: FLECKS_CORE_ROOT, - }, - use: [ - copy({ - copyUnmodified: true, - patterns: [ - { - from: '.', - to: '.', - globOptions: { - dot: true, - ignore: [ - 'dist', - 'node_modules', - ], - gitignore: true, - }, - }, - ], - pluginId: '@flecks/core.copy', - }), - autoentry(), - ], -}; diff --git a/packages/core/src/index.js b/packages/core/src/index.js index 36843b2..e1d8f51 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -15,12 +15,4 @@ export const hooks = { */ id: 'flecks', }), - '@flecks/core.build': (target, config) => { - config.use.push(({config}) => { - config.module - .rule('mjs$') - .test(/.mjs$/) - .type('javascript/auto'); - }); - }, }; diff --git a/packages/core/src/bootstrap/require.js b/packages/core/src/require.js similarity index 100% rename from packages/core/src/bootstrap/require.js rename to packages/core/src/require.js diff --git a/packages/core/src/server/build/.eslint.defaults.js b/packages/core/src/server/build/.eslint.defaults.js deleted file mode 100644 index d6b5166..0000000 --- a/packages/core/src/server/build/.eslint.defaults.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = { - env: { - browser: true, - // @todo chase - es2021: true, - node: true, - mocha: true, - }, - globals: { - __non_webpack_require__: true, - window: true, - }, - ignorePatterns: [ - '**/dist/**', - 'build/dox/hooks.js', - ], - overrides: [ - { - files: [ - 'test/**/*.js', - ], - rules: { - 'babel/no-unused-expressions': 'off', - 'brace-style': 'off', - 'class-methods-use-this': 'off', - 'import/no-extraneous-dependencies': 'off', - 'import/no-unresolved': 'off', - 'max-classes-per-file': 'off', - 'no-new': 'off', - 'padded-blocks': 'off', - }, - }, - ], - rules: { - 'babel/object-curly-spacing': 'off', - 'brace-style': ['error', 'stroustrup'], - 'import/prefer-default-export': 'off', - 'jsx-a11y/control-has-associated-label': ['error', {assert: 'either'}], - 'jsx-a11y/label-has-associated-control': ['error', {assert: 'either'}], - 'no-plusplus': 'off', - 'no-shadow': 'off', - 'padded-blocks': ['error', {classes: 'always'}], - yoda: 'off', - }, - settings: { - 'import/resolver': { - node: {}, - }, - }, -}; diff --git a/packages/core/src/server/build/babel.config.js b/packages/core/src/server/build/babel.config.js index f452721..3dd60c8 100644 --- a/packages/core/src/server/build/babel.config.js +++ b/packages/core/src/server/build/babel.config.js @@ -10,10 +10,10 @@ module.exports = (api) => { setSpreadProperties: true, }, plugins: [ - '@babel/plugin-proposal-class-properties', - '@babel/plugin-proposal-logical-assignment-operators', - '@babel/plugin-proposal-nullish-coalescing-operator', - '@babel/plugin-proposal-optional-chaining', + '@babel/plugin-syntax-class-properties', + '@babel/plugin-syntax-logical-assignment-operators', + '@babel/plugin-syntax-nullish-coalescing-operator', + '@babel/plugin-syntax-optional-chaining', ], presets: [ [ diff --git a/packages/core/src/server/build/default.eslint.config.js b/packages/core/src/server/build/default.eslint.config.js new file mode 100644 index 0000000..b2fa7a4 --- /dev/null +++ b/packages/core/src/server/build/default.eslint.config.js @@ -0,0 +1,92 @@ +const babelmerge = require('babel-merge'); +const globals = require('globals'); + +const R = require('../../require'); + +module.exports = (flecks) => { + const merging = [ + { + plugins: [R.resolve('@babel/plugin-syntax-dynamic-import')], + presets: [ + [ + R.resolve('@babel/preset-env'), + { + shippedProposals: true, + targets: { + esmodules: true, + node: 'current', + }, + }, + ], + ], + }, + ]; + if (flecks) { + merging.push({configFile: flecks.buildConfig('babel.config.js')}); + const rcBabel = flecks.babel(); + merging.push(...rcBabel.map(([, babel]) => babel)); + } + const babelConfig = babelmerge.all(merging); + return { + extends: [ + R.resolve('eslint-config-airbnb'), + R.resolve('eslint-config-airbnb/hooks'), + ], + globals: { + ...globals.browser, + ...globals.es2021, + ...globals.mocha, + ...globals.node, + __non_webpack_require__: true, + }, + ignorePatterns: [ + '**/dist/**', + 'build/dox/hooks.js', + ], + overrides: [ + { + files: [ + 'test/**/*.js', + ], + rules: { + 'brace-style': 'off', + 'class-methods-use-this': 'off', + 'import/no-extraneous-dependencies': 'off', + 'import/no-unresolved': 'off', + 'max-classes-per-file': 'off', + 'no-new': 'off', + 'no-unused-expressions': 'off', + 'padded-blocks': 'off', + }, + }, + ], + parser: R.resolve('@babel/eslint-parser'), + parserOptions: { + requireConfigFile: false, + babelOptions: babelConfig, + }, + plugins: ['@babel'], + rules: { + 'brace-style': ['error', 'stroustrup'], + // Bug: https://github.com/import-js/eslint-plugin-import/issues/2181 + 'import/no-import-module-exports': 'off', + 'import/prefer-default-export': 'off', + 'jsx-a11y/control-has-associated-label': ['error', {assert: 'either'}], + 'jsx-a11y/label-has-associated-control': ['error', {assert: 'either'}], + 'no-param-reassign': ['error', {props: false}], + 'no-plusplus': 'off', + 'no-shadow': 'off', + 'object-curly-spacing': 'off', + 'padded-blocks': ['error', {classes: 'always'}], + yoda: 'off', + }, + settings: { + 'import/resolver': { + node: {}, + }, + react: { + version: '18', + }, + }, + }; +}; diff --git a/packages/core/src/server/build/eslintrc.js b/packages/core/src/server/build/eslint.config.js similarity index 65% rename from packages/core/src/server/build/eslintrc.js rename to packages/core/src/server/build/eslint.config.js index 3a73bdc..a246b8f 100644 --- a/packages/core/src/server/build/eslintrc.js +++ b/packages/core/src/server/build/eslint.config.js @@ -7,14 +7,10 @@ const { } = require('fs'); const {join} = require('path'); -const neutrino = require('neutrino'); - -const R = require('../../bootstrap/require'); const D = require('../../debug'); -const {targetNeutrino, targetNeutrinos} = require('../commands'); const {default: Flecks} = require('../flecks'); -const debug = D('@flecks/core/.eslintrc.js'); +const debug = D('@flecks/core/server/build/eslint.config.js'); const { FLECKS_CORE_BUILD_TARGET = 'fleck', @@ -28,14 +24,8 @@ if (FLECKS_CORE_SYNC_FOR_ESLINT) { debug('bootstrapping flecks...'); const flecks = Flecks.bootstrap(); debug('bootstrapped'); - const neutrinos = targetNeutrinos(flecks); - const config = neutrinos[targetNeutrino(FLECKS_CORE_BUILD_TARGET)] - ? await R(neutrinos[targetNeutrino(FLECKS_CORE_BUILD_TARGET)])(flecks) - // eslint-disable-next-line global-require - : require('../../../build/.neutrinorc'); - flecks.invokeFlat('@flecks/core.build', FLECKS_CORE_BUILD_TARGET, config); - const eslintConfig = neutrino(config).eslintrc(); - const webpackConfig = neutrino(config).webpack(); + const eslintConfig = flecks.buildConfig('eslint.config.js', FLECKS_CORE_BUILD_TARGET); + const webpackConfig = flecks.buildConfig('webpack.config.js', FLECKS_CORE_BUILD_TARGET); eslintConfig.settings['import/resolver'].webpack = { config: { resolve: webpackConfig.resolve, @@ -45,10 +35,10 @@ if (FLECKS_CORE_SYNC_FOR_ESLINT) { })(); } else { - const cacheDirectory = join(FLECKS_CORE_ROOT, 'node_modules', '.cache', 'flecks'); + const cacheDirectory = join(FLECKS_CORE_ROOT, 'node_modules', '.cache', '@flecks', 'core'); try { - statSync(join(cacheDirectory, 'eslintrc.json')); - module.exports = JSON.parse(readFileSync(join(cacheDirectory, 'eslintrc.json')).toString()); + statSync(join(cacheDirectory, 'eslint.config.json')); + module.exports = JSON.parse(readFileSync(join(cacheDirectory, 'eslint.config.json')).toString()); } catch (error) { // Just silly. By synchronously spawning... ourselves, the spawned copy can use async. @@ -64,7 +54,7 @@ else { try { statSync(join(FLECKS_CORE_ROOT, 'node_modules')); mkdirSync(cacheDirectory, {recursive: true}); - writeFileSync(join(cacheDirectory, 'eslintrc.json'), json); + writeFileSync(join(cacheDirectory, 'eslint.config.json'), json); } // eslint-disable-next-line no-empty catch (error) {} diff --git a/packages/core/src/server/build/fleck.webpack.config.js b/packages/core/src/server/build/fleck.webpack.config.js new file mode 100644 index 0000000..2872f80 --- /dev/null +++ b/packages/core/src/server/build/fleck.webpack.config.js @@ -0,0 +1,135 @@ +const { + basename, + dirname, + extname, + join, +} = require('path'); + +const CopyPlugin = require('copy-webpack-plugin'); +const glob = require('glob'); +const ESLintPlugin = require('eslint-webpack-plugin'); + +const R = require('../../require'); +const {defaultConfig, externals} = require('../webpack'); +const eslintConfigFn = require('./default.eslint.config'); + +const { + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; + +const source = join(FLECKS_CORE_ROOT, 'src'); +const tests = join(FLECKS_CORE_ROOT, 'test'); + +const resolveValidModulePath = (source) => (path) => { + // Does the file resolve as source? + try { + R.resolve(`${source}/${path}`); + } + catch (error) { + const ext = extname(path); + // Try the implicit [path]/index[.ext] variation. + try { + R.resolve(`${source}/${dirname(path)}/${basename(path, ext)}/index${ext}`); + } + catch (error) { + return false; + } + } + return true; +}; + +module.exports = (env, argv, flecks) => { + const {name, files = []} = R(join(FLECKS_CORE_ROOT, 'package.json')); + const config = defaultConfig(flecks, { + externals: externals({importType: 'umd'}), + node: { + __dirname: false, + __filename: false, + }, + optimization: { + splitChunks: false, + runtimeChunk: false, + }, + output: { + filename: '[name].js', + library: { + name, + type: 'umd', + umdNamedDefine: true, + }, + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { + from: '.', + to: '.', + globOptions: { + dot: true, + ignore: [ + 'dist', + 'node_modules', + ], + gitignore: true, + }, + info: { + minimized: true, + }, + }, + ], + }), + ], + resolve: { + alias: { + [name]: source, + }, + fallback: { + child_process: false, + fs: false, + path: R.resolve('path-browserify'), + process: R.resolve('process/browser'), + stream: false, + }, + }, + stats: { + colors: true, + errorDetails: true, + }, + target: 'node', + }); + const eslint = eslintConfigFn(flecks); + eslint.settings['import/resolver'].webpack = { + config: { + resolve: config.resolve, + }, + }; + config.plugins.push( + new ESLintPlugin({ + cache: true, + cwd: FLECKS_CORE_ROOT, + emitWarning: argv.mode !== 'production', + failOnError: argv.mode === 'production', + useEslintrc: false, + overrideConfig: eslint, + }), + ); + // Automatic entry registration. + files + .filter(resolveValidModulePath(source)) + .forEach((file) => { + const trimmed = join(dirname(file), basename(file, extname(file))); + config.entry[trimmed] = `${source}/${trimmed}`; + }); + // Test entry. + const testPaths = glob.sync(join(tests, '*.js')); + const platforms = flecks + ? flecks.platforms + : ['server']; + for (let i = 0; i < platforms.length; ++i) { + testPaths.push(...glob.sync(join(tests, `platforms/${platforms[i]}/*.js`))); + } + if (testPaths.length > 0) { + config.entry.test = testPaths; + } + return config; +}; diff --git a/packages/core/src/server/build/fleckspack.config.js b/packages/core/src/server/build/fleckspack.config.js new file mode 100644 index 0000000..cb2c4f2 --- /dev/null +++ b/packages/core/src/server/build/fleckspack.config.js @@ -0,0 +1,95 @@ +/* eslint-disable import/first */ +import 'source-map-support/register'; + +if ('production' !== process.env.NODE_ENV) { + try { + // eslint-disable-next-line global-require, import/no-unresolved + __non_webpack_require__('dotenv/config'); + } + // eslint-disable-next-line no-empty + catch (error) {} +} + +import intersectionBy from 'lodash.intersectionby'; + +import D from '../../debug'; +import Flecks from '../flecks'; + +const debug = D('@flecks/core/server/build/fleckspack.config.js'); +const debugSilly = debug.extend('silly'); + +const { + FLECKS_CORE_BUILD_LIST = '', + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; + +const buildList = FLECKS_CORE_BUILD_LIST + .split(',') + .map((name) => name.trim()) + .filter((e) => e); + +export default async (env, argv) => { + debug('bootstrapping flecks...'); + const flecks = Flecks.bootstrap(); + debug('bootstrapped'); + + debug('gathering configs'); + const targets = []; + Object.entries(flecks.invoke('@flecks/core.targets')) + .forEach(([fleck, fleckTargets]) => { + intersectionBy(fleckTargets, buildList.length ? buildList : fleckTargets) + .forEach((target) => { + targets.push([target, fleck]); + }); + }); + debug('building: %O', targets.map(([target]) => target)); + if (0 === targets.length) { + debug('no build configuration found! aborting...'); + await new Promise(() => {}); + } + const entries = await Promise.all(targets.map( + async ([target, fleck]) => { + const buildConfig = flecks.resolveBuildConfig( + [ + FLECKS_CORE_ROOT, + flecks.resolvePath(fleck), + ], + [ + `${target}.webpack.config.js`, + 'webpack.config.js', + ], + ); + const configFn = __non_webpack_require__(buildConfig); + if ('function' !== typeof configFn) { + debug(`'${ + target + }' build configuration expected function got ${ + typeof configFn + }! aborting...`); + return undefined; + } + return [target, await configFn(env, argv, flecks)]; + }, + )); + await Promise.all( + entries.map(async ([target, config]) => ( + flecks.invokeFlat('@flecks/core.build', target, config, env, argv) + )), + ); + const webpackConfigs = Object.fromEntries(entries); + await Promise.all(flecks.invokeFlat('@flecks/core.build.alter', webpackConfigs, env, argv)); + const enterableWebpackConfigs = Object.values(webpackConfigs) + .filter((webpackConfig) => { + if (!webpackConfig.entry) { + debug('webpack configurations %O had no entry... discarding', webpackConfig); + return false; + } + return true; + }); + if (0 === enterableWebpackConfigs.length) { + debug('no webpack configuration found! aborting...'); + await new Promise(() => {}); + } + debugSilly('webpack configurations %O', enterableWebpackConfigs); + return enterableWebpackConfigs; +}; diff --git a/packages/core/src/server/build/webpack.config.js b/packages/core/src/server/build/webpack.config.js deleted file mode 100644 index 585839f..0000000 --- a/packages/core/src/server/build/webpack.config.js +++ /dev/null @@ -1,84 +0,0 @@ -/* eslint-disable import/first */ -import 'source-map-support/register'; - -if ('production' !== process.env.NODE_ENV) { - try { - // eslint-disable-next-line global-require, import/no-unresolved - require('dotenv/config'); - } - // eslint-disable-next-line no-empty - catch (error) {} -} - -import flatten from 'lodash.flatten'; -import intersection from 'lodash.intersection'; -import neutrino from 'neutrino'; - -import D from '../../debug'; -import {targetNeutrino} from '../commands'; -import Flecks from '../flecks'; - -const debug = D('@flecks/core/build/webpack.config.js'); -const debugSilly = debug.extend('silly'); - -const { - FLECKS_CORE_BUILD_LIST = '', -} = process.env; - -const buildList = FLECKS_CORE_BUILD_LIST - .split(',') - .map((name) => name.trim()) - .filter((e) => e); - -export default (async () => { - debug('bootstrapping flecks...'); - const flecks = Flecks.bootstrap(); - debug('bootstrapped'); - - debug('gathering configs'); - let targets = flatten(flecks.invokeFlat('@flecks/core.targets')); - if (buildList.length > 0) { - targets = intersection(targets, buildList); - } - debug('building: %O', targets); - if (0 === targets.length) { - debug('no build configuration found! aborting...'); - await new Promise(() => {}); - } - const entries = await Promise.all(targets.map( - async (target) => [ - target, - await __non_webpack_require__(process.env[targetNeutrino(target)])(flecks), - ], - )); - await Promise.all( - entries.map(async ([target, config]) => ( - flecks.invokeFlat('@flecks/core.build', target, config) - )), - ); - const neutrinoConfigs = Object.fromEntries(entries); - await Promise.all(flecks.invokeFlat('@flecks/core.build.alter', neutrinoConfigs)); - const webpackConfigs = ( - await Promise.all( - Object.entries(neutrinoConfigs) - .map(async ([target, config]) => { - const webpackConfig = neutrino(config).webpack(); - await flecks.invokeFlat('@flecks/core.webpack', target, webpackConfig); - return webpackConfig; - }), - ) - ) - .filter((webpackConfig) => { - if (!webpackConfig.entry) { - debug('webpack configurations %O had no entry... discarding', webpackConfig); - return false; - } - return true; - }); - if (0 === webpackConfigs.length) { - debug('no webpack configuration found! aborting...'); - await new Promise(() => {}); - } - debugSilly('webpack configurations %O', webpackConfigs); - return webpackConfigs; -})(); diff --git a/packages/core/src/server/commands.js b/packages/core/src/server/commands.js index 7b248a5..b259086 100644 --- a/packages/core/src/server/commands.js +++ b/packages/core/src/server/commands.js @@ -37,41 +37,8 @@ export const spawnWith = (cmd, opts = {}) => { child.stdout.pipe(process.stdout); return child; }; -export const targetNeutrino = (target) => ( - `FLECKS_CORE_BUILD_TARGET_${ - target - .toUpperCase() - .replace(/[^A-Za-z0-9]/g, '_') - }_NEUTRINO` -); - -export const targetNeutrinos = (flecks) => { - const entries = Object.entries(flecks.invoke('@flecks/core.targets')); - const targetNeutrinos = {}; - for (let i = 0; i < entries.length; ++i) { - const [fleck, targets] = entries[i]; - targets - .forEach((target) => { - targetNeutrinos[targetNeutrino(target)] = flecks.resolveBuildConfig( - [ - FLECKS_CORE_ROOT, - flecks.resolvePath(fleck), - ], - [ - `${target}.neutrinorc.js`, - '.neutrinorc.js', - ], - ); - }); - } - return targetNeutrinos; -}; export default (program, flecks) => { - Object.entries(targetNeutrinos(flecks)) - .forEach(([key, value]) => { - process.env[key] = value; - }); const commands = { clean: { description: 'remove node_modules, lock file, build artifacts, then reinstall', @@ -112,10 +79,9 @@ export default (program, flecks) => { watch, } = opts; debug('Building...', opts); - const webpackConfig = flecks.buildConfig('webpack.config.js'); + const webpackConfig = flecks.buildConfig('fleckspack.config.js'); const cmd = [ 'npx', 'webpack', - '--colors', '--config', webpackConfig, '--mode', (production && !hot) ? 'production' : 'development', ...((watch || hot) ? ['--watch'] : []), @@ -124,7 +90,6 @@ export default (program, flecks) => { cmd, { env: { - ...targetNeutrinos(flecks), ...(target ? {FLECKS_CORE_BUILD_LIST: target} : {}), ...(hot ? {FLECKS_ENV_FLECKS_SERVER_hot: 'true'} : {}), }, @@ -159,7 +124,6 @@ export default (program, flecks) => { { env: { FLECKS_CORE_BUILD_TARGET: target, - ...targetNeutrinos(flecks), }, }, ); diff --git a/packages/core/src/server/flecks.js b/packages/core/src/server/flecks.js index bd707ee..0534bda 100644 --- a/packages/core/src/server/flecks.js +++ b/packages/core/src/server/flecks.js @@ -12,14 +12,13 @@ import { resolve, } from 'path'; -import compileLoader from '@neutrinojs/compile-loader'; import babelmerge from 'babel-merge'; import enhancedResolve from 'enhanced-resolve'; import {addHook} from 'pirates'; -import R from '../bootstrap/require'; import D from '../debug'; import Flecks from '../flecks'; +import R from '../require'; import Compiler from './compiler'; const { @@ -119,9 +118,14 @@ export default class ServerFlecks extends Flecks { if (!config) { throw new Error(`Unknown build config '${path}'`); } - const paths = []; - if (config.specifier) { - paths.push(config.specifier(specific)); + const paths = [`${specific}.${path}`]; + if ('specifier' in config) { + if (false === config.specifier) { + paths.pop(); + } + else { + paths.push(config.specifier(specific)); + } } paths.push(path); const roots = [config.root]; @@ -493,12 +497,14 @@ export default class ServerFlecks extends Flecks { } static resolveBuildConfig(resolver, roots, paths) { + const tried = []; for (let i = 0; i < roots.length; ++i) { const root = roots[i]; for (let j = 0; j < paths.length; ++j) { const path = paths[j]; const resolved = join(root, 'build', path); try { + tried.push(resolved); statSync(resolved); return resolved; } @@ -506,7 +512,7 @@ export default class ServerFlecks extends Flecks { catch (error) {} } } - throw new Error(`Couldn't resolve build file '${paths.pop()}'`); + throw new Error(`Couldn't resolve build file '${paths.pop()}', tried: ${tried.join(', ')}`); } resolvePath(path) { @@ -544,12 +550,7 @@ export default class ServerFlecks extends Flecks { return undefined; } - runtimeCompiler(resolver, runtime, neutrino, {additionalModuleDirs = [], allowlist = []} = {}) { - const {config} = neutrino; - // Pull the default compiler. - if (config.module.rules.has('compile')) { - config.module.rules.delete('compile'); - } + runtimeCompiler(resolver, runtime, config, {additionalModuleDirs = [], allowlist = []} = {}) { // Compile. const needCompilation = Object.entries(resolver) .filter(([fleck]) => this.constructor.fleckIsCompiled(resolver, fleck)); @@ -565,8 +566,7 @@ export default class ServerFlecks extends Flecks { : this.constructor.sourcepath(R.resolve(this.constructor.resolve(resolver, fleck))); alias = alias.endsWith('/index') ? alias.slice(0, -6) : alias; allowlist.push(fleck); - config.resolve.alias - .set(fleck, alias); + config.resolve.alias[fleck] = alias; debugSilly('%s runtime de-externalized %s, alias: %s', runtime, fleck, alias); }); // Set up compilation at each root. @@ -587,12 +587,23 @@ export default class ServerFlecks extends Flecks { // Augment the compiler with babel config from flecksrc. ...babelmerge.all(rcBabel.map(([, babel]) => babel)), }; - compileLoader({ - ignore: [sourceroot], - include: [sourceroot], - babel, - ruleId: `@flecks/${runtime}/runtime/compile[${root}]`, - })(neutrino); + config.module.rules.push( + { + test: /\.(m?jsx?)?$/, + include: [sourceroot], + use: [ + { + loader: R.resolve('babel-loader'), + options: { + cacheDirectory: true, + babelrc: false, + configFile: false, + ...babel, + }, + }, + ], + }, + ); }); } } diff --git a/packages/core/src/server/index.js b/packages/core/src/server/index.js index c355366..181bcdd 100644 --- a/packages/core/src/server/index.js +++ b/packages/core/src/server/index.js @@ -1,11 +1,11 @@ import {join} from 'path'; import {inspect} from 'util'; -import airbnb from '@neutrinojs/airbnb'; -import neutrino from 'neutrino'; +import ESLintPlugin from 'eslint-webpack-plugin'; +import webpack from 'webpack'; +import eslintConfigFn from './build/default.eslint.config'; import commands from './commands'; -import R from '../bootstrap/require'; const { FLECKS_CORE_ROOT = process.cwd(), @@ -22,46 +22,45 @@ export { default as commands, processCode, spawnWith, - targetNeutrino, - targetNeutrinos, } from './commands'; export {default as Flecks} from './flecks'; -export {default as fleck} from '../bootstrap/fleck'; -export {default as require} from '../bootstrap/require'; +export {default as require} from '../require'; export {JsonStream, transform} from './stream'; +export * from './webpack'; + +export {webpack}; export const hooks = { - '@flecks/core.build': (target, config, flecks) => { + '@flecks/core.build': (target, config, env, argv, flecks) => { const { 'eslint.exclude': exclude, profile, } = flecks.get('@flecks/core/server'); - if (-1 !== profile.indexOf(target)) { - config.use.push(({config}) => { - config - .plugin('profiler') - .use( - R.resolve('webpack/lib/debug/ProfilingPlugin'), - [{outputPath: join(FLECKS_CORE_ROOT, `profile.build-${target}.json`)}], - ); - }); + if (profile.includes(target)) { + config.plugins.push( + new webpack.debug.ProfilingPlugin({ + outputPath: join(FLECKS_CORE_ROOT, `profile.build-${target}.json`), + }), + ); } - if (-1 === exclude.indexOf(target)) { - const baseConfig = R(flecks.buildConfig('.eslint.defaults.js', target)); - const webpackConfig = neutrino(config).webpack(); - config.use.unshift( - airbnb({ - eslint: { - baseConfig: { - ...baseConfig, - settings: { - ...(baseConfig.settings || {}), - 'import/resolver': { - ...(baseConfig.settings['import/resolver'] || {}), - webpack: { - config: { - resolve: webpackConfig.resolve, - }, + if (exclude.includes(target)) { + const eslint = eslintConfigFn(flecks); + config.plugins.push( + new ESLintPlugin({ + cache: true, + cwd: FLECKS_CORE_ROOT, + emitWarning: argv.mode !== 'production', + failOnError: argv.mode === 'production', + useEslintrc: false, + overrideConfig: { + ...eslint, + settings: { + ...(eslint.settings || {}), + 'import/resolver': { + ...(eslint.settings['import/resolver'] || {}), + webpack: { + config: { + resolve: config.resolve, }, }, }, @@ -77,20 +76,20 @@ export const hooks = { */ 'babel.config.js', /** - * ESLint defaults. The default .eslintrc.js just reads from this file so that the build + * ESLint defaults. The default `eslint.config.js` just reads from this file so that the build * process can dynamically configure parts of ESLint. */ - ['.eslint.defaults.js', {specifier: (specific) => `${specific}.eslint.defaults.js`}], + 'default.eslint.config.js', /** * ESLint configuration. See: https://eslint.org/docs/user-guide/configuring/ */ - ['.eslintrc.js', {specifier: (specific) => `${specific}.eslintrc.js`}], + 'eslint.config.js', /** - * Neutrino build configuration. See: https://neutrinojs.org/usage/ + * Flecks webpack configuration. See: https://webpack.js.org/configuration/ */ - ['.neutrinorc.js', {specifier: (specific) => `${specific}.neutrinorc.js`}], + ['fleckspack.config.js', {specifier: false}], /** - * Webpack (v4) configuration. See: https://v4.webpack.js.org/configuration/ + * Webpack configuration. See: https://webpack.js.org/configuration/ */ 'webpack.config.js', ], diff --git a/packages/core/src/server/webpack.js b/packages/core/src/server/webpack.js new file mode 100644 index 0000000..eb5dbad --- /dev/null +++ b/packages/core/src/server/webpack.js @@ -0,0 +1,163 @@ +const {chmod} = require('fs'); +const {join} = require('path'); + +const babelmerge = require('babel-merge'); +const CopyPlugin = require('copy-webpack-plugin'); +const webpack = require('webpack'); +const nodeExternals = require('webpack-node-externals'); + +const D = require('../debug'); + +const { + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; + +const debug = D('@flecks/core/server/webpack'); +const debugSilly = debug.extend('silly'); +const source = join(FLECKS_CORE_ROOT, 'src'); +const tests = join(FLECKS_CORE_ROOT, 'test'); + +exports.banner = (options) => ( + new webpack.BannerPlugin({ + entryOnly: true, + raw: true, + ...options, + }) +); + +exports.copy = (options) => (new CopyPlugin(options)); + +exports.defaultConfig = (flecks, specializedConfig) => { + const extensions = ['.mjs', '.js', '.json', '.wasm']; + const merging = [ + { + plugins: ['@babel/plugin-syntax-dynamic-import'], + presets: [ + [ + '@babel/preset-env', + { + shippedProposals: true, + targets: { + esmodules: true, + node: 'current', + }, + }, + ], + ], + }, + ]; + if (flecks) { + extensions.push(...flecks.exts()); + merging.push({configFile: flecks.buildConfig('babel.config.js')}); + const rcBabel = flecks.babel(); + debugSilly('.flecksrc: babel: %j', rcBabel); + merging.push(...rcBabel.map(([, babel]) => babel)); + } + const babelConfig = babelmerge.all(merging); + const extensionsRegex = exports.regexFromExtensions(extensions); + const defaults = { + context: FLECKS_CORE_ROOT, + devtool: 'source-map', + entry: {}, + module: { + rules: [ + { + enforce: 'pre', + test: extensionsRegex, + use: ['source-map-loader'], + }, + { + include: [source, tests], + test: extensionsRegex, + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: true, + babelrc: false, + configFile: false, + ...babelConfig, + }, + }, + ], + }, + ], + }, + output: { + clean: true, + path: join(FLECKS_CORE_ROOT, 'dist'), + }, + plugins: [], + resolve: { + alias: {}, + extensions, + fallback: {}, + modules: [ + 'node_modules', + join(FLECKS_CORE_ROOT, 'node_modules'), + ], + }, + stats: { + colors: true, + errorDetails: true, + }, + }; + return 'function' === typeof specializedConfig + ? specializedConfig(defaults) + : { + ...defaults, + ...specializedConfig, + module: { + ...specializedConfig.module, + rules: [ + ...defaults.module.rules, + ...(specializedConfig.module?.rules || []), + ], + }, + output: { + ...defaults.output, + ...specializedConfig.output, + }, + plugins: [ + ...defaults.plugins, + ...(specializedConfig.plugins || []), + ], + resolve: { + ...defaults.resolve, + ...specializedConfig.resolve, + }, + stats: { + ...defaults.stats, + ...specializedConfig.stats, + }, + }; +}; + +// Include a shebang and set the executable bit.. +exports.executable = () => ([ + exports.banner({ + banner: '#!/usr/bin/env node', + include: /^cli\.js$/, + }), + new class Executable { + + // eslint-disable-next-line class-methods-use-this + apply(compiler) { + compiler.hooks.afterEmit.tapAsync( + 'Executable', + (compilation, callback) => { + chmod(join(FLECKS_CORE_ROOT, 'dist', 'cli.js'), 0o755, callback); + }, + ); + } + + }(), +]); + +exports.externals = nodeExternals; + +exports.regexFromExtensions = (exts) => ( + new RegExp(String.raw`(?:${exts.map((ext) => ext.replace('.', '\\.')).join('|')})$`) +); + +exports.webpack = webpack; diff --git a/packages/core/test/one/index.js b/packages/core/test/one/index.js index 329ea1b..bad679f 100644 --- a/packages/core/test/one/index.js +++ b/packages/core/test/one/index.js @@ -24,9 +24,9 @@ export const hooks = { O.foo *= 2; }, '@flecks/core/test/invoke-merge': () => ({foo: 69}), - '@flecks/core/test/invoke-merge-async': () => new Promise((resolve) => resolve({foo: 69})), + '@flecks/core/test/invoke-merge-async': () => new Promise((resolve) => { resolve({foo: 69}); }), '@flecks/core/test/invoke-merge-unique': () => ({foo: 69}), - '@flecks/core/test/invoke-merge-unique-async': () => new Promise((resolve) => resolve({foo: 69})), + '@flecks/core/test/invoke-merge-unique-async': () => new Promise((resolve) => { resolve({foo: 69}); }), '@flecks/core/test.middleware': () => (foo, next) => { // eslint-disable-next-line no-param-reassign foo.bar += 1; diff --git a/packages/core/test/two/index.js b/packages/core/test/two/index.js index 847dbe8..710b7c9 100644 --- a/packages/core/test/two/index.js +++ b/packages/core/test/two/index.js @@ -13,9 +13,9 @@ export const hooks = { }, 0); }), '@flecks/core/test/invoke-merge': () => ({bar: 420}), - '@flecks/core/test/invoke-merge-async': () => new Promise((resolve) => resolve({bar: 420})), + '@flecks/core/test/invoke-merge-async': () => new Promise((resolve) => { resolve({bar: 420}); }), '@flecks/core/test/invoke-merge-unique': () => ({foo: 69}), - '@flecks/core/test/invoke-merge-unique-async': () => new Promise((resolve) => resolve({foo: 69})), + '@flecks/core/test/invoke-merge-unique-async': () => new Promise((resolve) => { resolve({foo: 69}); }), '@flecks/core/test.middleware': () => (foo, next) => { // eslint-disable-next-line no-param-reassign foo.bar *= 2; diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 6912003..28de0f7 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/create-app + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/create-app + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/create-app diff --git a/packages/create-app/build/fleck.neutrinorc.js b/packages/create-app/build/fleck.neutrinorc.js deleted file mode 100644 index f3b3300..0000000 --- a/packages/create-app/build/fleck.neutrinorc.js +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -const {chmod} = require('fs'); -const {join} = require('path'); - -const banner = require('@neutrinojs/banner'); -const copy = require('@neutrinojs/copy'); - -module.exports = async (flecks) => { - // eslint-disable-next-line global-require - const config = await require('@flecks/fleck/server/build/fleck.neutrinorc')(flecks); - - config.use.push(banner({ - banner: '#!/usr/bin/env node', - include: /^cli\.js$/, - pluginId: 'shebang', - raw: true, - })); - - config.use.push(({config}) => { - config - .plugin('executable') - .use(class Executable { - - // eslint-disable-next-line class-methods-use-this - apply(compiler) { - compiler.hooks.afterEmit.tapAsync( - 'Executable', - (compilation, callback) => { - chmod(join(__dirname, '..', 'dist', 'cli.js'), 0o755, callback); - }, - ); - } - - }); - }); - - config.use.push( - copy({ - copyUnmodified: true, - patterns: [ - { - from: 'template', - to: 'template', - }, - ], - }), - ); - - return config; - -}; diff --git a/packages/create-app/build/fleck.webpack.config.js b/packages/create-app/build/fleck.webpack.config.js new file mode 100644 index 0000000..c0aaa47 --- /dev/null +++ b/packages/create-app/build/fleck.webpack.config.js @@ -0,0 +1,17 @@ +const {copy, executable} = require('@flecks/core/server'); +// eslint-disable-next-line import/no-extraneous-dependencies +const configFn = require('@flecks/fleck/server/build/fleck.webpack.config'); + +module.exports = async (env, argv, flecks) => { + const config = await configFn(env, argv, flecks); + config.plugins.push(...executable()); + config.plugins.push(copy({ + patterns: [ + { + from: 'template', + to: 'template', + }, + ], + })); + return config; +}; diff --git a/packages/create-app/package.json b/packages/create-app/package.json index f50c0db..f7faa13 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "bin": { "create-app": "./cli.js" }, @@ -28,12 +28,12 @@ "template" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "glob": "^7.2.0", "minimatch": "^5.0.1", "validate-npm-package-name": "^3.0.0" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/create-app/template/package.json.noconflict b/packages/create-app/template/package.json.noconflict index c1bea6e..1ec387e 100644 --- a/packages/create-app/template/package.json.noconflict +++ b/packages/create-app/template/package.json.noconflict @@ -9,11 +9,11 @@ "start": "DEBUG=@flecks*,flecks*,-@flecks/core/flecks* npm run dev" }, "dependencies": { - "@flecks/core": "^1.0.0", - "@flecks/server": "^1.0.0" + "@flecks/core": "^2.0.0", + "@flecks/server": "^2.0.0" }, "devDependencies": { - "@flecks/create-fleck": "^1.0.0", + "@flecks/create-fleck": "^2.0.0", "lerna": "^3.22.1" } } diff --git a/packages/create-fleck/CHANGELOG.md b/packages/create-fleck/CHANGELOG.md index b6a4a2e..376ffec 100644 --- a/packages/create-fleck/CHANGELOG.md +++ b/packages/create-fleck/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/create-fleck + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/create-fleck + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/create-fleck diff --git a/packages/create-fleck/build/fleck.neutrinorc.js b/packages/create-fleck/build/fleck.neutrinorc.js deleted file mode 100644 index f3b3300..0000000 --- a/packages/create-fleck/build/fleck.neutrinorc.js +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -const {chmod} = require('fs'); -const {join} = require('path'); - -const banner = require('@neutrinojs/banner'); -const copy = require('@neutrinojs/copy'); - -module.exports = async (flecks) => { - // eslint-disable-next-line global-require - const config = await require('@flecks/fleck/server/build/fleck.neutrinorc')(flecks); - - config.use.push(banner({ - banner: '#!/usr/bin/env node', - include: /^cli\.js$/, - pluginId: 'shebang', - raw: true, - })); - - config.use.push(({config}) => { - config - .plugin('executable') - .use(class Executable { - - // eslint-disable-next-line class-methods-use-this - apply(compiler) { - compiler.hooks.afterEmit.tapAsync( - 'Executable', - (compilation, callback) => { - chmod(join(__dirname, '..', 'dist', 'cli.js'), 0o755, callback); - }, - ); - } - - }); - }); - - config.use.push( - copy({ - copyUnmodified: true, - patterns: [ - { - from: 'template', - to: 'template', - }, - ], - }), - ); - - return config; - -}; diff --git a/packages/create-fleck/build/fleck.webpack.config.js b/packages/create-fleck/build/fleck.webpack.config.js new file mode 100644 index 0000000..c0aaa47 --- /dev/null +++ b/packages/create-fleck/build/fleck.webpack.config.js @@ -0,0 +1,17 @@ +const {copy, executable} = require('@flecks/core/server'); +// eslint-disable-next-line import/no-extraneous-dependencies +const configFn = require('@flecks/fleck/server/build/fleck.webpack.config'); + +module.exports = async (env, argv, flecks) => { + const config = await configFn(env, argv, flecks); + config.plugins.push(...executable()); + config.plugins.push(copy({ + patterns: [ + { + from: 'template', + to: 'template', + }, + ], + })); + return config; +}; diff --git a/packages/create-fleck/package.json b/packages/create-fleck/package.json index 3f95cba..f72394a 100644 --- a/packages/create-fleck/package.json +++ b/packages/create-fleck/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "bin": { "create-fleck": "./cli.js" }, @@ -26,10 +26,10 @@ "template" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@flecks/create-app": "^1.4.1" + "@flecks/core": "^2.0.3", + "@flecks/create-app": "^2.0.3" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/create-fleck/template/package.json.noconflict b/packages/create-fleck/template/package.json.noconflict index 20ddac5..360f005 100644 --- a/packages/create-fleck/template/package.json.noconflict +++ b/packages/create-fleck/template/package.json.noconflict @@ -15,9 +15,9 @@ "test" ], "dependencies": { - "@flecks/core": "^1.0.0" + "@flecks/core": "^2.0.0" }, "devDependencies": { - "@flecks/fleck": "^1.0.0" + "@flecks/fleck": "^2.0.0" } } diff --git a/packages/db/CHANGELOG.md b/packages/db/CHANGELOG.md index 5aa2cd5..7bed84b 100644 --- a/packages/db/CHANGELOG.md +++ b/packages/db/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/db + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/db + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/db diff --git a/packages/db/package.json b/packages/db/package.json index d3b1773..6c02d88 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "scripts": { "build": "flecks build", "clean": "flecks clean", @@ -23,11 +23,11 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "sequelize": "^6.3.5", "sqlite3": "^5.0.2" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/db/src/connection.js b/packages/db/src/connection.js index 28d63cb..5552501 100644 --- a/packages/db/src/connection.js +++ b/packages/db/src/connection.js @@ -53,7 +53,9 @@ export async function createDatabaseConnection(flecks) { } catch (error) { // eslint-disable-next-line no-await-in-loop - await new Promise((resolve) => setTimeout(resolve, 250)); + await new Promise((resolve) => { + setTimeout(resolve, 250); + }); } } const dependencies = {}; diff --git a/packages/docker/CHANGELOG.md b/packages/docker/CHANGELOG.md index 94bc6aa..bc5e314 100644 --- a/packages/docker/CHANGELOG.md +++ b/packages/docker/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/docker + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/docker + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/docker diff --git a/packages/docker/package.json b/packages/docker/package.json index c47b303..2b5b028 100644 --- a/packages/docker/package.json +++ b/packages/docker/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -24,10 +24,10 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "debug": "^4.3.3" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/docker/src/start-container.js b/packages/docker/src/start-container.js index 57ab9c9..62bf37f 100644 --- a/packages/docker/src/start-container.js +++ b/packages/docker/src/start-container.js @@ -79,7 +79,9 @@ export default async (flecks, key, config) => { while (await !containerIsRunning(name)) { debug("waiting for '%s' to start...", key); // eslint-disable-next-line no-await-in-loop - await new Promise((resolve) => setTimeout(resolve, 10)); + await new Promise((resolve) => { + setTimeout(resolve, 10); + }); } debug("'%s' started", key); if (config.hasConnected) { diff --git a/packages/dox/CHANGELOG.md b/packages/dox/CHANGELOG.md index b145f74..49b56dc 100644 --- a/packages/dox/CHANGELOG.md +++ b/packages/dox/CHANGELOG.md @@ -3,6 +3,49 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/dox + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/dox + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* hook dox ([aa78144](https://github.com/cha0s/flecks/commit/aa7814462801a9fef2324b8b5be231f288f23179)) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/dox diff --git a/packages/dox/package.json b/packages/dox/package.json index d77f91f..43d386b 100644 --- a/packages/dox/package.json +++ b/packages/dox/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -27,11 +27,11 @@ "@babel/core": "^7.17.2", "@babel/traverse": "^7.17.0", "@babel/types": "^7.17.0", - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "comment-parser": "^1.3.0", "glob": "^7.2.0" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/dox/src/generate.js b/packages/dox/src/generate.js index 719208e..e171d62 100644 --- a/packages/dox/src/generate.js +++ b/packages/dox/src/generate.js @@ -34,18 +34,31 @@ export const generateConfigPage = (configs) => { Object.entries(configs) .sort(([l], [r]) => (l < r ? -1 : 1)) .forEach(([fleck, configs]) => { - source.push(`## \`${fleck}\``); - source.push(''); + // source.push(`## \`${fleck}\``); + source.push('```javascript'); + source.push(`'${fleck}': {`); configs.forEach(({comment, config, defaultValue}) => { comment.split('\n').forEach((line) => { - source.push(`> ${line}`); + source.push(` // ${line}`); }); - source.push(''); - source.push('```javascript'); - source.push(`${config}: ${defaultValue}`); - source.push('```'); - source.push(''); + const value = defaultValue + .split('\n') + .map((line, i, array) => { + let output = ''; + if (array.length - 1 === i) { + output += ' '; + } + else if (0 !== i) { + output += ' '; + } + output += line.trim(); + return output; + }) + .join('\n'); + source.push(` ${config}: ${value}`); }); + source.push('}'); + source.push('```'); }); return source.join('\n'); }; diff --git a/packages/dox/src/parser.js b/packages/dox/src/parser.js index 21d5f26..ca7ad86 100644 --- a/packages/dox/src/parser.js +++ b/packages/dox/src/parser.js @@ -293,12 +293,12 @@ export const parseFile = async (filename, resolved, state) => { }; const fleckSources = async (path) => ( - new Promise((r, e) => ( + new Promise((r, e) => { glob( join(path, 'src', '**', '*.js'), (error, result) => (error ? e(error) : r(result)), - ) - )) + ); + }) ); export const parseFleckRoot = async (root, state) => { diff --git a/packages/electron/CHANGELOG.md b/packages/electron/CHANGELOG.md new file mode 100644 index 0000000..ed218d4 --- /dev/null +++ b/packages/electron/CHANGELOG.md @@ -0,0 +1,49 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://git.hq.cha0s.io/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/electron + + + + + +## [2.0.1](https://git.hq.cha0s.io/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/electron + + + + + +# [2.0.0](https://git.hq.cha0s.io/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* conditional electron inclusion ([a959722](https://git.hq.cha0s.io/cha0s/flecks/commits/a9597225ca250fd9acee28c3feb284a979ee3111)) +* doc ([9a5fb07](https://git.hq.cha0s.io/cha0s/flecks/commits/9a5fb07d81fea6b5bb915ef2efe5973c186392aa)) +* paths got broken somehow ([c7bbc48](https://git.hq.cha0s.io/cha0s/flecks/commits/c7bbc48d3a4c4db2b57c1002b73f4baac0b80172)) + + +### Features + +* electron ([67723d1](https://git.hq.cha0s.io/cha0s/flecks/commits/67723d1d356af94a1bbbc38c734722d4409ba057)) +* electron with start-server-webpack-plugin ([1ade829](https://git.hq.cha0s.io/cha0s/flecks/commits/1ade8294a1d825cfa4361daa245c50ff05f6fa79)) +* **electron:** devtools ([10d59e1](https://git.hq.cha0s.io/cha0s/flecks/commits/10d59e16edc6e8828c019fa728f19546a4c55042)) +* reopen closed ([11c61b3](https://git.hq.cha0s.io/cha0s/flecks/commits/11c61b3d7284cd8403660e71c314aba276244d8b)) +* webpack 5 support ([288b368](https://git.hq.cha0s.io/cha0s/flecks/commits/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) diff --git a/packages/electron/package.json b/packages/electron/package.json index e737f85..20a264f 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -1,6 +1,14 @@ { "name": "@flecks/electron", - "version": "1.4.1", + "repository": { + "type": "git", + "url": "https://github.com/cha0s/flecks.git", + "directory": "packages/electron" + }, + "publishConfig": { + "access": "public" + }, + "version": "2.0.3", "scripts": { "build": "flecks build", "clean": "flecks clean", @@ -16,12 +24,11 @@ "test" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@neutrinojs/banner": "^9.5.0", + "@flecks/core": "^2.0.3", "electron": "^18.0.1", "electron-devtools-installer": "^3.2.0" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/electron/src/server/index.js b/packages/electron/src/server/index.js index 84a30f6..d927c76 100644 --- a/packages/electron/src/server/index.js +++ b/packages/electron/src/server/index.js @@ -1,9 +1,8 @@ import {join} from 'path'; -import banner from '@neutrinojs/banner'; +import {banner} from '@flecks/core/server'; const { - FLECKS_CORE_ROOT = process.cwd(), NODE_ENV, } = process.env; @@ -19,12 +18,13 @@ async function createWindow(flecks) { export const hooks = { '@flecks/core.build': (target, config) => { if ('server' === target) { - config.use.push(banner({ - banner: "require('module').Module._initPaths();", - include: 'index.js', - pluginId: 'initPaths', - raw: true, - })); + config.plugins.push( + banner({ + // Bootstrap our `require()` magic. + banner: "require('module').Module._initPaths();", + include: 'index.js', + }), + ); } }, '@flecks/core.config': () => ({ @@ -55,15 +55,18 @@ export const hooks = { */ url: undefined, }), - '@flecks/core.webpack': (target, config) => { - const plugin = config.plugins.find(({pluginName}) => pluginName === 'StartServerPlugin'); - // Extremely hackish, c'est la vie. - if (plugin) { - const {exec} = plugin.options; - plugin.options.exec = (compilation) => { - plugin.options.args = [compilation.assets[exec].existsAt]; - return join(FLECKS_CORE_ROOT, 'node_modules', '.bin', 'electron'); - }; + '@flecks/core.build.alter': (configs) => { + const {server: config} = configs; + if (config) { + const plugin = config.plugins.find(({pluginName}) => pluginName === 'StartServerPlugin'); + // Extremely hackish, c'est la vie. + if (plugin) { + const {exec} = plugin.options; + plugin.options.exec = (compilation) => { + plugin.options.args = [join(config.output.path, compilation.getPath(exec))]; + return join('..', 'node_modules', '.bin', 'electron'); + }; + } } }, '@flecks/electron/server.initialize': async (electron, flecks) => { diff --git a/packages/fleck/CHANGELOG.md b/packages/fleck/CHANGELOG.md index 12d74bf..83b40c5 100644 --- a/packages/fleck/CHANGELOG.md +++ b/packages/fleck/CHANGELOG.md @@ -3,6 +3,50 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/fleck + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/fleck + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* mocha error propagation ([1f11aac](https://github.com/cha0s/flecks/commit/1f11aac027e0699b821c2bc9f31bdfe3fd61a2d0)) +* test fails -> nonzero process code ([1f01189](https://github.com/cha0s/flecks/commit/1f0118914393d8b16913aad25eef81aaadac4e68)) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/fleck diff --git a/packages/fleck/package.json b/packages/fleck/package.json index 611fd0e..4329116 100644 --- a/packages/fleck/package.json +++ b/packages/fleck/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "author": "cha0s", "license": "MIT", "bin": { @@ -22,8 +22,8 @@ }, "files": [ "build", - "server/build/fleck.neutrinorc.js", - "server/build/fleck.neutrinorc.js.map", + "server/build/fleck.webpack.config.js", + "server/build/fleck.webpack.config.js.map", "server.js", "server.js.map", "src", @@ -31,7 +31,7 @@ "test.js.map" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "babel-merge": "^3.0.0", "chokidar": "^3.5.3", "clear-module": "^4.1.2", diff --git a/packages/fleck/src/server/build/fleck.neutrinorc.js b/packages/fleck/src/server/build/fleck.neutrinorc.js deleted file mode 100644 index 7a2817a..0000000 --- a/packages/fleck/src/server/build/fleck.neutrinorc.js +++ /dev/null @@ -1,42 +0,0 @@ -const {join} = require('path'); - -const {D} = require('@flecks/core'); -const {fleck} = require('@flecks/core/server'); -const babelmerge = require('babel-merge'); -const glob = require('glob'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -const debug = D('@flecks/fleck/fleck.neutrino.js'); -const debugSilly = debug.extend('silly'); - -const config = require('../../../../core/src/bootstrap/fleck.neutrinorc'); - -module.exports = async (flecks) => { - // Compile. - const rcBabel = flecks.babel(); - debugSilly('.flecksrc: babel: %j', rcBabel); - config.use.push(fleck({ - babel: babelmerge.all([ - {configFile: flecks.buildConfig('babel.config.js')}, - ...rcBabel.map(([, babel]) => babel), - ]), - })); - config.use.push(({config}) => { - config.stats(flecks.get('@flecks/fleck/server.stats')); - }); - config.use.push(({config}) => { - // Test entrypoint. - const testPaths = glob.sync(join(FLECKS_CORE_ROOT, 'test/*.js')); - for (let i = 0; i < flecks.platforms.length; ++i) { - testPaths.push(...glob.sync(join(FLECKS_CORE_ROOT, `test/platforms/${flecks.platforms[i]}/*.js`))); - } - if (testPaths.length > 0) { - const testEntry = config.entry('test').clear(); - testPaths.forEach((path) => testEntry.add(path)); - } - }); - return config; -}; diff --git a/packages/fleck/src/server/build/fleck.webpack.config.js b/packages/fleck/src/server/build/fleck.webpack.config.js new file mode 100644 index 0000000..30cdb1a --- /dev/null +++ b/packages/fleck/src/server/build/fleck.webpack.config.js @@ -0,0 +1,7 @@ +const flecksConfigFn = require('@flecks/core/server/build/fleck.webpack.config'); + +module.exports = async (env, argv, flecks) => { + const config = await flecksConfigFn(env, argv, flecks); + config.stats = flecks.get('@flecks/fleck/server.stats'); + return config; +}; diff --git a/packages/fleck/src/server/commands.js b/packages/fleck/src/server/commands.js index 0e6df80..7813a68 100644 --- a/packages/fleck/src/server/commands.js +++ b/packages/fleck/src/server/commands.js @@ -50,7 +50,9 @@ export default (program, flecks) => { } catch (error) { // eslint-disable-next-line no-await-in-loop - await new Promise((resolve) => setTimeout(resolve, 50)); + await new Promise((resolve) => { + setTimeout(resolve, 50); + }); } } const runMocha = async () => { @@ -87,7 +89,9 @@ export default (program, flecks) => { } chokidar.watch(testLocation) .on('all', async () => { - await new Promise((resolve) => setTimeout(resolve, 50)); + await new Promise((resolve) => { + setTimeout(resolve, 50); + }); runMocha(); }); return new Promise(() => {}); diff --git a/packages/fleck/src/server/index.js b/packages/fleck/src/server/index.js index c88ff94..cf5c0a3 100644 --- a/packages/fleck/src/server/index.js +++ b/packages/fleck/src/server/index.js @@ -4,13 +4,11 @@ export const hooks = { '@flecks/core.commands': commands, '@flecks/core.config': () => ({ /** - * Webpack stats configuration when building fleck target. + * Webpack stats configuration. */ stats: { - children: false, - chunks: false, colors: true, - modules: false, + errorDetails: true, }, }), '@flecks/core.targets': () => ['fleck'], diff --git a/packages/governor/CHANGELOG.md b/packages/governor/CHANGELOG.md index 7c385ba..2faf6f5 100644 --- a/packages/governor/CHANGELOG.md +++ b/packages/governor/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/governor + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/governor + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/governor diff --git a/packages/governor/package.json b/packages/governor/package.json index 2dbcb63..b075b56 100644 --- a/packages/governor/package.json +++ b/packages/governor/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -26,12 +26,12 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@flecks/db": "^1.4.1", + "@flecks/core": "^2.0.3", + "@flecks/db": "^2.0.3", "rate-limiter-flexible": "^2.1.13", "redis": "^3.1.2" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index d46cb86..0f613d2 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -3,6 +3,51 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/react + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/react + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* avoid FOUC on dev ([18e2bb9](https://github.com/cha0s/flecks/commit/18e2bb9446b2ead51800f2dd2d094cbe8c6282f8)) + + +### Features + +* "wtf, you can't just take @babel/register, give it an actual API, and make it work simultaneously across multiple roots" ([82e22c3](https://github.com/cha0s/flecks/commit/82e22c3eef69f13b6b8645667d3362d49d3b3e6b)) +* **react:** configure in web's absence ([754646d](https://github.com/cha0s/flecks/commit/754646d4a1df63de44f91e5a3184ebd9c75afd95)) +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/react diff --git a/packages/react/build/.eslint.defaults.js b/packages/react/build/.eslint.defaults.js deleted file mode 100644 index 1eaac03..0000000 --- a/packages/react/build/.eslint.defaults.js +++ /dev/null @@ -1,5 +0,0 @@ -const config = require('@flecks/core/server/build/.eslint.defaults.js'); - -config.globals.window = true; - -module.exports = config; diff --git a/packages/react/package.json b/packages/react/package.json index c80aca7..8058efa 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -38,25 +38,23 @@ "router/server.js.map", "server.js", "server.js.map", - "src", - "style-loader.js", - "style-loader.js.map" + "src" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@flecks/web": "^1.4.1", - "@hot-loader/react-dom": "^17.0.1", - "@neutrinojs/react": "^9.4.0", + "@babel/preset-react": "^7.23.3", + "@flecks/core": "^2.0.3", + "@flecks/web": "^2.0.3", + "@hot-loader/react-dom": "^17.0.2", "babel-merge": "^3.0.0", "classnames": "^2.3.1", "history": "^5.3.0", "prop-types": "^15.7.2", "react": "^17.0.1", - "react-hot-loader": "^4.13.0", - "react-router-dom": "^6.2.1", - "redux-first-history": "^5.0.8" + "react-hot-loader": "^4.13.1", + "react-router-dom": "6.20.0", + "redux-first-history": "5.1.1" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/react/src/server.js b/packages/react/src/server.js index 2bd2d98..542af8f 100644 --- a/packages/react/src/server.js +++ b/packages/react/src/server.js @@ -3,22 +3,22 @@ import {augmentBuild} from '@flecks/web/server'; import ssr from './ssr'; export const hooks = { - '@flecks/core.build': (target, config, flecks) => { - // Resolution. - config.use.push(({config}) => { - config.resolve.alias - .set('react-native', 'react-native-web'); - config.resolve.extensions - .prepend('.web.js') - .prepend('.web.jsx'); - }); + /* eslint-disable no-param-reassign */ + '@flecks/core.build': (target, config, env, argv, flecks) => { + const isProduction = 'production' === argv.mode; + config.resolve.alias['react-native'] = 'react-native-web'; + config.resolve.alias['react-hot-loader'] = isProduction + ? 'react-hot-loader/dist/react-hot-loader.production' + : 'react-hot-loader/dist/react-hot-loader.development'; + config.resolve.extensions.unshift(...['.web.js', '.web.jsx']); // Augment the build on behalf of a missing `@flecks/web`. if (!flecks.fleck('@flecks/web/server')) { flecks.registerBuildConfig('postcss.config.js', {fleck: '@flecks/web/server'}); flecks.registerResolver('@flecks/web'); - augmentBuild(target, config, flecks); + augmentBuild(target, config, env, argv, flecks); } }, + /* eslint-enable no-param-reassign */ '@flecks/web/server.stream.html': (stream, req, flecks) => ( flecks.get('@flecks/react.ssr') ? ssr(stream, req, flecks) : stream ), diff --git a/packages/react/src/ssr.js b/packages/react/src/ssr.js index 6c203d8..e93c833 100644 --- a/packages/react/src/ssr.js +++ b/packages/react/src/ssr.js @@ -22,9 +22,15 @@ class Ssr extends Transform { const string = chunk .toString('utf8'); if (-1 !== string.indexOf('
')) { - const output = ReactDOMServer.renderToString( - React.createElement(await root(this.flecks, this.req)), - ); + let output; + try { + output = ReactDOMServer.renderToString( + React.createElement(await root(this.flecks, this.req)), + ); + } + catch (e) { + output = ''; + } this.push( string.replace( '
', diff --git a/packages/redis/CHANGELOG.md b/packages/redis/CHANGELOG.md index f1028ac..9109e3e 100644 --- a/packages/redis/CHANGELOG.md +++ b/packages/redis/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/redis + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/redis + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/redis diff --git a/packages/redis/package.json b/packages/redis/package.json index 9772921..9ba9061 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "scripts": { "build": "flecks build", "clean": "flecks clean", @@ -25,13 +25,13 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "@socket.io/redis-adapter": "7.1.0", "connect-redis": "^5.0.0", "express-session": "^1.17.1", "redis": "4.0.3" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/redux/CHANGELOG.md b/packages/redux/CHANGELOG.md index 537b8ae..278b6e9 100644 --- a/packages/redux/CHANGELOG.md +++ b/packages/redux/CHANGELOG.md @@ -3,6 +3,49 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/redux + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/redux + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* async for parity ([780fa43](https://github.com/cha0s/flecks/commit/780fa433e156fbc7adad0f97aaebd3c821f40dee)) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/redux diff --git a/packages/redux/build/.eslint.defaults.js b/packages/redux/build/.eslint.defaults.js deleted file mode 100644 index 1eaac03..0000000 --- a/packages/redux/build/.eslint.defaults.js +++ /dev/null @@ -1,5 +0,0 @@ -const config = require('@flecks/core/server/build/.eslint.defaults.js'); - -config.globals.window = true; - -module.exports = config; diff --git a/packages/redux/package.json b/packages/redux/package.json index e08e5a0..76de1f2 100644 --- a/packages/redux/package.json +++ b/packages/redux/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -28,7 +28,7 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "@hot-loader/react-dom": "^17.0.1", "@reduxjs/toolkit": "^1.5.0", "debug": "^4.3.3", @@ -37,6 +37,6 @@ "reduce-reducers": "^1.0.4" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/repl/CHANGELOG.md b/packages/repl/CHANGELOG.md index ac1e7d3..485274a 100644 --- a/packages/repl/CHANGELOG.md +++ b/packages/repl/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/repl + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/repl + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/repl diff --git a/packages/repl/package.json b/packages/repl/package.json index eecb8fa..ae6f9e8 100644 --- a/packages/repl/package.json +++ b/packages/repl/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "scripts": { "build": "flecks build", "clean": "flecks clean", @@ -23,11 +23,11 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", + "@flecks/core": "^2.0.3", "command-exists": "^1.2.9", "debug": "4.3.1" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/repl/src/repl.js b/packages/repl/src/repl.js index 5c04e7f..b86a0fa 100644 --- a/packages/repl/src/repl.js +++ b/packages/repl/src/repl.js @@ -62,7 +62,9 @@ export async function createReplServer(flecks) { } const socket = join(tmpdir(), 'flecks', id, 'repl', `${id}-${Date.now()}.sock`); flecks.set('$flecks/repl.socket', socket); - await new Promise((resolve) => netServer.listen(socket, resolve)); + await new Promise((resolve) => { + netServer.listen(socket, resolve); + }); debug('listening @ %s', socket); } diff --git a/packages/server/CHANGELOG.md b/packages/server/CHANGELOG.md index 18f2a39..5104a3e 100644 --- a/packages/server/CHANGELOG.md +++ b/packages/server/CHANGELOG.md @@ -3,6 +3,50 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/server + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/server + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* complex aliasing ([4ba2b51](https://github.com/cha0s/flecks/commit/4ba2b5113657f4426d8e976fe9a77d797378475a)) + + +### Features + +* awesomerific module resolution ([60c844d](https://github.com/cha0s/flecks/commit/60c844d58b294df0d9cf0be741266fdd8dd53a33)) +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/server diff --git a/packages/server/package.json b/packages/server/package.json index d655653..d2e75e7 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "license": "MIT", "scripts": { @@ -26,23 +26,17 @@ "index.js.map", "runtime.js", "runtime.js.map", - "server/build/server.neutrinorc.js", - "server/build/server.neutrinorc.js.map", + "server/build/server.webpack.config.js", + "server/build/server.webpack.config.js.map", "server.js", "server.js.map", "src" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@neutrinojs/banner": "^9.5.0", - "@neutrinojs/clean": "^9.5.0", - "@neutrinojs/start-server": "^9.5.0", - "debug": "^4.3.3", - "loader-utils": "^1.4.0", - "source-map-loader": "^1.1.3", - "webpack-node-externals": "2.5.2" + "@flecks/core": "^2.0.3", + "debug": "^4.3.3" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/server/src/index.js b/packages/server/src/index.js index 4a688d5..17ec408 100644 --- a/packages/server/src/index.js +++ b/packages/server/src/index.js @@ -13,12 +13,11 @@ export const hooks = { */ start: true, /** - * Webpack stats configuration when building server target. + * Webpack stats configuration. */ stats: { - chunks: false, colors: true, - modules: false, + errorDetails: true, }, }), }; diff --git a/packages/server/src/runtime.js b/packages/server/src/runtime.js index 7c632bb..8b32fdf 100644 --- a/packages/server/src/runtime.js +++ b/packages/server/src/runtime.js @@ -1,6 +1,4 @@ -const {getOptions} = require('loader-utils'); - module.exports = function FlecksRuntime() { - const {source} = getOptions(this); + const {source} = this.getOptions(); return source; }; diff --git a/packages/server/src/server/build/runtime.js b/packages/server/src/server/build/runtime.js index f422740..c97246b 100644 --- a/packages/server/src/server/build/runtime.js +++ b/packages/server/src/server/build/runtime.js @@ -1,81 +1,81 @@ const {realpath} = require('fs/promises'); const {join} = require('path'); -const {require: R} = require('@flecks/core/server'); +const {externals, require: R} = require('@flecks/core/server'); -module.exports = async (flecks) => { +module.exports = async (config, env, argv, flecks) => { const runtime = await realpath(R.resolve(join(flecks.resolve('@flecks/server'), 'runtime'))); - return (neutrino) => { - const {config, options} = neutrino; - const {resolver} = flecks; - // Inject flecks configuration. - const paths = Object.keys(resolver); - const source = [ - "process.env.FLECKS_CORE_BUILD_TARGET = 'server';", - 'module.exports = (async () => ({', - ` config: ${JSON.stringify(flecks.config)},`, - ' loadFlecks: async () => Object.fromEntries(await Promise.all([', - paths.map((path) => ` ['${path}', import('${path}')]`).join(',\n'), - ' ].map(async ([path, M]) => [path, await M]))),', - " platforms: ['server']", - '}))();', - ]; - // HMR. - source.push('if (module.hot) {'); - // Keep HMR junk out of our output path. - source.push(' const {unlink} = require("fs/promises");'); - source.push(' const {join} = require("path");'); - source.push(' let previousHash = __webpack_hash__;'); - source.push(' module.hot.addStatusHandler((status) => {'); - source.push(' if ("idle" === status) {'); - source.push(' require("glob")('); - source.push(` join('${options.output}', \`*\${previousHash}.hot-update.*\`),`); - source.push(' async (error, disposing) => {'); - source.push(' if (error) {'); - source.push(' throw error;'); - source.push(' return;'); - source.push(' }'); - source.push(' await Promise.all(disposing.map(unlink));'); - source.push(' },'); - source.push(' );'); - source.push(' previousHash = __webpack_hash__;'); - source.push(' }'); + const {resolver} = flecks; + // Inject flecks configuration. + const paths = Object.keys(resolver); + const source = [ + "process.env.FLECKS_CORE_BUILD_TARGET = 'server';", + 'module.exports = (async () => ({', + ` config: ${JSON.stringify(flecks.config)},`, + ' loadFlecks: async () => Object.fromEntries(await Promise.all([', + paths.map((path) => ` ['${path}', import('${path}')]`).join(',\n'), + ' ].map(async ([path, M]) => [path, await M]))),', + " platforms: ['server']", + '}))();', + ]; + // HMR. + source.push('if (module.hot) {'); + // Keep HMR junk out of our output path. + source.push(' const {unlink} = require("fs/promises");'); + source.push(' const {join} = require("path");'); + source.push(' let previousHash = __webpack_hash__;'); + source.push(' module.hot.addStatusHandler((status) => {'); + source.push(' if ("idle" === status) {'); + source.push(' require("glob")('); + source.push(` join('${config.output.path}', \`*\${previousHash}.hot-update.*\`),`); + source.push(' async (error, disposing) => {'); + source.push(' if (error) {'); + source.push(' throw error;'); + source.push(' return;'); + source.push(' }'); + source.push(' await Promise.all(disposing.map(unlink));'); + source.push(' },'); + source.push(' );'); + source.push(' previousHash = __webpack_hash__;'); + source.push(' }'); + source.push(' });'); + // Hooks for each fleck. + paths.forEach((path) => { + source.push(` module.hot.accept('${path}', async () => {`); + source.push(` global.flecks.refresh('${path}', require('${path}'));`); + source.push(` global.flecks.invoke('@flecks/core.hmr', '${path}');`); source.push(' });'); - // Hooks for each fleck. - paths.forEach((path) => { - source.push(` module.hot.accept('${path}', async () => {`); - source.push(` global.flecks.refresh('${path}', require('${path}'));`); - source.push(` global.flecks.invoke('@flecks/core.hmr', '${path}');`); - source.push(' });'); - }); - source.push('}'); - // Create runtime. - config.module - .rule(runtime) - .test(runtime) - .use('runtime') - .loader(runtime) - .options({ - source: source.join('\n'), - }); - const allowlist = [ - '@flecks/server/entry', - '@flecks/server/runtime', - /^@babel\/runtime\/helpers\/esm/, - ]; - config.resolve.alias - .set('@flecks/server/runtime$', runtime); - const nodeExternalsConfig = { - additionalModuleDirs: [], - allowlist, - }; - flecks.runtimeCompiler(flecks.resolver, 'server', neutrino, nodeExternalsConfig); - // Rewrite to signals for HMR. - if ('production' !== config.get('mode')) { - allowlist.push(/^webpack/); - } - // Externalize the rest. - const nodeExternals = R('webpack-node-externals'); - config.externals(nodeExternals(nodeExternalsConfig)); + }); + source.push('}'); + // Create runtime. + config.module.rules.push( + { + test: runtime, + use: [ + { + loader: runtime, + options: { + source: source.join('\n'), + }, + }, + ], + }, + ); + const allowlist = [ + '@flecks/server/entry', + '@flecks/server/runtime', + /^@babel\/runtime\/helpers\/esm/, + ]; + config.resolve.alias['@flecks/server/runtime$'] = runtime; + const nodeExternalsConfig = { + additionalModuleDirs: [], + allowlist, }; + flecks.runtimeCompiler(flecks.resolver, 'server', config, nodeExternalsConfig); + // Rewrite to signals for HMR. + if ('production' !== argv.mode) { + allowlist.push(/^webpack/); + } + // Externalize the rest. + config.externals = externals(nodeExternalsConfig); }; diff --git a/packages/server/src/server/build/server.neutrinorc.js b/packages/server/src/server/build/server.neutrinorc.js deleted file mode 100644 index f4eab42..0000000 --- a/packages/server/src/server/build/server.neutrinorc.js +++ /dev/null @@ -1,102 +0,0 @@ -const {join} = require('path'); - -const {require: R} = require('@flecks/core/server'); -const banner = require('@neutrinojs/banner'); -const clean = require('@neutrinojs/clean'); - -const runtime = require('./runtime'); -const startServer = require('./start'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -module.exports = async (flecks) => { - const { - hot, - nodeArgs, - start: isStarting, - } = flecks.get('@flecks/server'); - - const server = (neutrino) => { - const {config, options} = neutrino; - const isProduction = 'production' === config.get('mode'); - neutrino.use(banner()); - neutrino.use(clean({cleanStaleWebpackAssets: false})); - // Entrypoints. - config.context(options.root); - const entries = config.entry('index'); - if (!isProduction && hot) { - config - .plugin('hot') - .use(R.resolve('webpack/lib/HotModuleReplacementPlugin')); - entries.add('webpack/hot/signal'); - } - entries.add('@flecks/server/entry'); - // Fold in existing source maps. - config.module - .rule('maps') - .test(/\.js$/) - .enforce('pre') - .use('source-map-loader') - .loader('source-map-loader'); - // Resolution. - config.resolve.extensions - .merge([ - '.wasm', - ...options.extensions.map((ext) => `.${ext}`), - '.json', - ]); - // Reporting. - config.stats({ - ...flecks.get('@flecks/server.stats'), - warningsFilter: [ - /Failed to parse source map/, - ], - }); - // Outputs. - config.output - .path(options.output) - .libraryTarget('commonjs2'); - config.node - .set('__dirname', false) - .set('__filename', false); - config - .devtool('source-map') - .target('node'); - }; - - // Augment the application-starting configuration. - const start = (neutrino) => { - if (isStarting) { - neutrino.use(startServer({ - exec: 'index.js', - // Bail hard on unhandled rejections and report. - nodeArgs: [...nodeArgs, '--unhandled-rejections=strict', '--trace-uncaught'], - // HMR. - signal: !!hot, - })); - } - }; - - const config = { - options: { - output: 'dist', - root: FLECKS_CORE_ROOT, - }, - use: [ - server, - start, - ], - }; - - // Build the server runtime. - config.use.push(await runtime(flecks)); - - // Give the resolver a helping hand. - config.use.push(({config}) => { - config.resolve.modules.merge([join(FLECKS_CORE_ROOT, 'node_modules')]); - }); - - return config; -}; diff --git a/packages/server/src/server/build/server.webpack.config.js b/packages/server/src/server/build/server.webpack.config.js new file mode 100644 index 0000000..cb7601d --- /dev/null +++ b/packages/server/src/server/build/server.webpack.config.js @@ -0,0 +1,58 @@ +const { + banner, + defaultConfig, + webpack, +} = require('@flecks/core/server'); + +const runtime = require('./runtime'); +const startServer = require('./start'); + +module.exports = async (env, argv, flecks) => { + const { + hot, + nodeArgs, + start: isStarting, + } = flecks.get('@flecks/server'); + const config = defaultConfig(flecks, { + node: { + __dirname: false, + __filename: false, + }, + output: { + libraryTarget: 'commonjs2', + }, + plugins: [ + banner({banner: "require('source-map-support').install();"}), + ], + stats: { + ...flecks.get('@flecks/server.stats'), + warningsFilter: [ + /Failed to parse source map/, + ], + }, + target: 'node', + }); + const isProduction = 'production' === argv.mode; + // Entrypoints. + config.entry.index = []; + if (!isProduction && hot) { + config.plugins.push(new webpack.HotModuleReplacementPlugin()); + config.entry.index.push('webpack/hot/signal'); + } + config.entry.index.push('@flecks/server/entry'); + // Augment the application-starting configuration. + if (isStarting) { + config.plugins.push( + startServer({ + exec: 'index.js', + // Bail hard on unhandled rejections and report. + nodeArgs: [...nodeArgs, '--unhandled-rejections=strict', '--trace-uncaught'], + // HMR. + signal: !!hot, + }), + ); + } + // Build the server runtime. + await runtime(config, env, argv, flecks); + return config; +}; diff --git a/packages/server/src/server/build/start.js b/packages/server/src/server/build/start.js index 755a4c3..7ec0ee3 100644 --- a/packages/server/src/server/build/start.js +++ b/packages/server/src/server/build/start.js @@ -1,4 +1,5 @@ const cluster = require('cluster'); +const {join} = require('path'); class StartServerPlugin { @@ -30,10 +31,10 @@ class StartServerPlugin { } let entryPoint; if (!exec) { - entryPoint = compilation.assets[Object.keys(compilation.assets)[0]].existsAt; + entryPoint = compilation.getPath(Object.keys(compilation.assets)[0]); } else if (compilation.assets[exec]) { - entryPoint = compilation.assets[exec].existsAt; + entryPoint = compilation.getPath(exec); } else if ('string' === typeof exec) { entryPoint = exec; @@ -41,10 +42,7 @@ class StartServerPlugin { else { entryPoint = exec(compilation); } - this.startServer( - entryPoint, - callback, - ); + this.startServer(join(compiler.options.output.path, entryPoint), callback); }); compiler.hooks.shouldEmit.tap(pluginName, (compilation) => { const entryPoints = Object.keys(compilation.assets); @@ -84,17 +82,6 @@ class StartServerPlugin { } -module.exports = ({ - nodeArgs = [], - pluginId = 'start-server', - ...pluginOptions -} = {}) => ( - ({config, options}) => { - config - .plugin(pluginId) - .use( - StartServerPlugin, - [{...pluginOptions, nodeArgs: nodeArgs.concat(options.debug ? ['--inspect'] : [])}], - ); - } +module.exports = (pluginOptions = {}) => ( + new StartServerPlugin(pluginOptions) ); diff --git a/packages/socket/CHANGELOG.md b/packages/socket/CHANGELOG.md index 8c15084..9e00c6e 100644 --- a/packages/socket/CHANGELOG.md +++ b/packages/socket/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/socket + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/socket + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/socket diff --git a/packages/socket/build/.eslint.defaults.js b/packages/socket/build/.eslint.defaults.js deleted file mode 100644 index 1eaac03..0000000 --- a/packages/socket/build/.eslint.defaults.js +++ /dev/null @@ -1,5 +0,0 @@ -const config = require('@flecks/core/server/build/.eslint.defaults.js'); - -config.globals.window = true; - -module.exports = config; diff --git a/packages/socket/package.json b/packages/socket/package.json index 82c66bf..7c4bee1 100644 --- a/packages/socket/package.json +++ b/packages/socket/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -28,8 +28,8 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@flecks/react": "^1.4.1", + "@flecks/core": "^2.0.3", + "@flecks/react": "^2.0.3", "msgpack-lite": "^0.1.26", "proxy-addr": "^2.0.6", "schemapack": "^1.4.2", @@ -37,6 +37,6 @@ "socket.io-client": "^4.1.2" }, "devDependencies": { - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/socket/src/index.js b/packages/socket/src/index.js index ca8f6a5..4ccd8c4 100644 --- a/packages/socket/src/index.js +++ b/packages/socket/src/index.js @@ -5,7 +5,7 @@ import Refresh from './packet/refresh'; export {default as normalize} from './normalize'; export * from './hooks'; -export {default as Packet, Packer, ValidationError} from './packet'; +export {Packet, Packer, ValidationError} from './packet'; export const hooks = { '@flecks/core.starting': (flecks) => { diff --git a/packages/socket/src/packet/index.js b/packages/socket/src/packet/index.js index 96217b3..cf21f91 100644 --- a/packages/socket/src/packet/index.js +++ b/packages/socket/src/packet/index.js @@ -1,3 +1,3 @@ export {default as Packer} from './packer'; -export {default} from './packet'; +export {default as Packet} from './packet'; export {default as ValidationError} from './validation-error'; diff --git a/packages/socket/src/server/create-intercom.js b/packages/socket/src/server/create-intercom.js index 6dfe18e..ca5adf7 100644 --- a/packages/socket/src/server/create-intercom.js +++ b/packages/socket/src/server/create-intercom.js @@ -13,7 +13,9 @@ export default function createIntercom(sockets, transport) { ); }); responses.push( - await new Promise((resolve) => sockets.localIntercom({payload, type}, resolve)), + await new Promise((resolve) => { + sockets.localIntercom({payload, type}, resolve); + }), ); return responses; }; diff --git a/packages/user/CHANGELOG.md b/packages/user/CHANGELOG.md index 88194d2..00d1ca6 100644 --- a/packages/user/CHANGELOG.md +++ b/packages/user/CHANGELOG.md @@ -3,6 +3,45 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/user + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/user + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Features + +* UserRequired ([9b5f6f4](https://github.com/cha0s/flecks/commit/9b5f6f4818afaec76ee941c8d2c4795912234ee8)) +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/user diff --git a/packages/user/package.json b/packages/user/package.json index a7fc8e1..b998eb4 100644 --- a/packages/user/package.json +++ b/packages/user/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -34,9 +34,9 @@ "src" ], "dependencies": { - "@flecks/core": "^1.4.1", - "@flecks/react": "^1.4.1", - "@flecks/redux": "^1.4.1", + "@flecks/core": "^2.0.3", + "@flecks/react": "^2.0.3", + "@flecks/redux": "^2.0.3", "bcrypt": "^5.0.0", "express": "^4.17.1", "express-session": "1.17.1", @@ -45,6 +45,6 @@ }, "devDependencies": { "@babel/preset-react": "^7.12.10", - "@flecks/fleck": "^1.4.1" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/user/src/packets/logout.js b/packages/user/src/packets/logout.js index cf7a54d..78ea238 100644 --- a/packages/user/src/packets/logout.js +++ b/packages/user/src/packets/logout.js @@ -5,7 +5,9 @@ export default (flecks) => { static respond(packet, {req}) { req.logout(); - return new Promise((r, e) => req.session.save((error) => (error ? e(error) : r()))); + return new Promise((r, e) => { + req.session.save((error) => (error ? e(error) : r())); + }); } static validate(packet, {req}) { diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index ed0cfed..86ece36 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -3,6 +3,51 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22) + + +### Bug Fixes + +* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741)) + + + + + +## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22) + +**Note:** Version bump only for package @flecks/web + + + + + +## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22) + +**Note:** Version bump only for package @flecks/web + + + + + +# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22) + + +### Bug Fixes + +* avoid FOUC on dev ([18e2bb9](https://github.com/cha0s/flecks/commit/18e2bb9446b2ead51800f2dd2d094cbe8c6282f8)) + + +### Features + +* html template specifier ([5791c7a](https://github.com/cha0s/flecks/commit/5791c7a89433f16c1efea045a00ab488975c6dab)) +* per-entry styles ([d43316a](https://github.com/cha0s/flecks/commit/d43316a43635ea19338a6a1ce917f9b2d308c977)) +* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c)) + + + + + ## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19) **Note:** Version bump only for package @flecks/web diff --git a/packages/web/build/.eslint.defaults.js b/packages/web/build/.eslint.defaults.js deleted file mode 100644 index 1eaac03..0000000 --- a/packages/web/build/.eslint.defaults.js +++ /dev/null @@ -1,5 +0,0 @@ -const config = require('@flecks/core/server/build/.eslint.defaults.js'); - -config.globals.window = true; - -module.exports = config; diff --git a/packages/web/build/fleck.neutrinorc.js b/packages/web/build/fleck.neutrinorc.js deleted file mode 100644 index 9efcda7..0000000 --- a/packages/web/build/fleck.neutrinorc.js +++ /dev/null @@ -1,46 +0,0 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -const copy = require('@neutrinojs/copy'); -const styleLoader = require('@neutrinojs/style-loader'); -const nodeExternals = require('webpack-node-externals'); - -module.exports = async (flecks) => { - // eslint-disable-next-line import/no-extraneous-dependencies, global-require - const config = await require('@flecks/fleck/server/build/fleck.neutrinorc')(flecks); - config.use.push(({config}) => { - config.entryPoints.delete('server/build/entry'); - config.entryPoints.delete('server/build/template'); - config.entryPoints.delete('server/build/tests'); - config.externals(nodeExternals({ - allowlist: ['mocha/mocha.css'], - importType: 'umd', - })); - }); - config.use.push(styleLoader({ - extract: { - enabled: false, - }, - style: { - injectType: 'lazyStyleTag', - }, - })); - config.use.push( - copy({ - copyUnmodified: true, - patterns: [ - { - from: 'src/server/build/entry.js', - to: 'server/build/entry.js', - }, - { - from: 'src/server/build/template.ejs', - to: 'server/build/template.ejs', - }, - { - from: 'src/server/build/tests.js', - to: 'server/build/tests.js', - }, - ], - }), - ); - return config; -}; diff --git a/packages/web/build/fleck.webpack.config.js b/packages/web/build/fleck.webpack.config.js new file mode 100644 index 0000000..fa828a0 --- /dev/null +++ b/packages/web/build/fleck.webpack.config.js @@ -0,0 +1,34 @@ +const {copy, externals} = require('@flecks/core/server'); +// eslint-disable-next-line import/no-extraneous-dependencies +const configFn = require('@flecks/fleck/server/build/fleck.webpack.config'); + +module.exports = async (env, argv, flecks) => { + // eslint-disable-next-line import/no-extraneous-dependencies, global-require + const config = await configFn(env, argv, flecks); + delete config.entry['server/build/entry']; + delete config.entry['server/build/template']; + delete config.entry['server/build/tests']; + config.externals = externals({ + allowlist: ['mocha/mocha.css'], + importType: 'umd', + }); + config.plugins.push( + copy({ + patterns: [ + { + from: 'src/server/build/entry.js', + to: 'server/build/entry.js', + }, + { + from: 'src/server/build/template.ejs', + to: 'server/build/template.ejs', + }, + { + from: 'src/server/build/tests.js', + to: 'server/build/tests.js', + }, + ], + }), + ); + return config; +}; diff --git a/packages/web/package.json b/packages/web/package.json index 81d7060..e69dab0 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -8,7 +8,7 @@ "publishConfig": { "access": "public" }, - "version": "1.4.1", + "version": "2.0.3", "main": "index.js", "scripts": { "build": "flecks build", @@ -32,10 +32,10 @@ "server/build/template.ejs", "server/build/tests.js", "server/build/tests.js.map", - "server/build/web.neutrinorc.js", - "server/build/web.neutrinorc.js.map", - "server/build/web-vendor.neutrinorc.js", - "server/build/web-vendor.neutrinorc.js.map", + "server/build/web.webpack.config.js", + "server/build/web.webpack.config.js.map", + "server/build/web-vendor.webpack.config.js", + "server/build/web-vendor.webpack.config.js.map", "src", "tests.js", "tests.js.map" @@ -43,35 +43,33 @@ "dependencies": { "@babel/parser": "^7.17.0", "@babel/types": "^7.17.0", - "@flecks/core": "^1.4.1", - "@neutrinojs/dev-server": "^9.5.0", - "@neutrinojs/font-loader": "^9.5.0", - "@neutrinojs/html-loader": "^9.5.0", - "@neutrinojs/html-template": "^9.5.0", - "@neutrinojs/image-loader": "^9.5.0", - "@neutrinojs/style-loader": "^9.5.0", - "add-asset-html-webpack-plugin": "^5.0.1", + "@flecks/core": "^2.0.3", + "@webpack-cli/serve": "^2.0.5", + "add-asset-html-webpack-plugin": "^6.0.0", "autoprefixer": "^9.8.6", - "before-build-webpack": "^0.2.12", + "before-build-webpack": "^0.2.13", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", + "clean-webpack-plugin": "4.0.0", "compression": "^1.7.4", + "css-loader": "^6.8.1", "express": "^4.17.1", "glob": "^7.2.0", - "html-webpack-plugin": "^4.5.0", + "html-loader": "^4.2.0", + "html-webpack-plugin": "^5.5.3", "http-proxy": "^1.17.0", - "loader-utils": "^1.4.0", "lodash.flatten": "^4.4.0", + "mini-css-extract-plugin": "^2.7.6", "mocha": "^8.3.2", "postcss-loader": "4.2.0", "react-dev-utils": "12.0.0", "sass": "^1.49.9", "sass-loader": "10.2.0", - "source-map-loader": "^1.1.3", - "webpack": "^4", - "webpack-dev-server": "^3.11.0", - "webpack-node-externals": "2.5.2" + "stream-browserify": "^3.0.0", + "style-loader": "^3.3.3", + "webpack-dev-server": "^4.15.1" }, "devDependencies": { - "@flecks/fleck": "^1.4.1", - "@neutrinojs/copy": "^9.4.0" + "@flecks/fleck": "^2.0.3" } } diff --git a/packages/web/src/runtime.js b/packages/web/src/runtime.js index 7c632bb..8b32fdf 100644 --- a/packages/web/src/runtime.js +++ b/packages/web/src/runtime.js @@ -1,6 +1,4 @@ -const {getOptions} = require('loader-utils'); - module.exports = function FlecksRuntime() { - const {source} = getOptions(this); + const {source} = this.getOptions(); return source; }; diff --git a/packages/web/src/server/augment-build.js b/packages/web/src/server/augment-build.js index 2666593..6715045 100644 --- a/packages/web/src/server/augment-build.js +++ b/packages/web/src/server/augment-build.js @@ -1,55 +1,92 @@ -import fontLoader from '@neutrinojs/font-loader'; -import imageLoader from '@neutrinojs/image-loader'; -import styleLoader from '@neutrinojs/style-loader'; +import {regexFromExtensions} from '@flecks/core/server'; +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; -const augmentBuild = (target, config, flecks) => { - config.use.push((neutrino) => { - const isProduction = 'production' === neutrino.config.get('mode'); - const extract = {}; - const style = {}; - if ('server' === target) { - extract.enabled = false; - style.injectType = 'lazyStyleTag'; +const augmentBuild = (target, config, env, argv, flecks) => { + const isProduction = 'production' === argv.mode; + let finalLoader; + switch (target) { + case 'fleck': { + finalLoader = {loader: MiniCssExtractPlugin.loader}; + config.plugins.push(new MiniCssExtractPlugin({filename: '[name].css'})); + break; } - if ('web' === target) { - extract.enabled = isProduction; - style.injectType = 'styleTag'; + case 'server': { + finalLoader = {loader: 'style-loader', options: {injectType: 'lazyStyleTag'}}; + break; } - if ('fleck' === target) { - extract.enabled = true; - extract.plugin = { - filename: '[name].css', - }; + case 'web': { + if (isProduction) { + finalLoader = {loader: MiniCssExtractPlugin.loader}; + config.plugins.push(new MiniCssExtractPlugin()); + } + else { + finalLoader = {loader: 'style-loader', options: {injectType: 'styleTag'}}; + } + break; } - neutrino.use( - styleLoader({ - extract, - modules: { - localIdentName: isProduction ? '[hash]' : '[path][name]__[local]', + default: break; + } + const buildOneOf = (test, loaders, cssOptions = {}) => ({ + test, + use: [ + finalLoader, + { + loader: 'css-loader', + options: { + ...cssOptions, + importLoaders: loaders.length, }, - style, - test: /\.(c|s[ac])ss$/, - modulesTest: /\.module\.(c|s[ac])ss$/, - loaders: [ - { - loader: 'postcss-loader', - useId: 'postcss', - options: { - postcssOptions: { - config: flecks.buildConfig('postcss.config.js'), - }, - }, - }, - { - loader: 'sass-loader', - useId: 'sass', - }, - ], - }), - ); + }, + ...loaders, + 'source-map-loader', + ], + }); + const stylesWithModulesRule = (extensions, loaders) => ({ + oneOf: [ + // `.module.*` must match first. + buildOneOf( + regexFromExtensions(extensions.map((ext) => `module${ext}`)), + loaders, + { + modules: { + localIdentName: isProduction ? '[hash]' : '[path][name]__[local]', + }, + }, + ), + buildOneOf( + regexFromExtensions(extensions), + loaders, + ), + ], + }); + const postcss = { + loader: 'postcss-loader', + options: { + postcssOptions: { + config: flecks.buildConfig('postcss.config.js'), + }, + }, + }; + // Originally separated because Sass can't handle incoming source maps, but probably more + // performant with 3rd-party CSS anyway. + config.module.rules.push(stylesWithModulesRule(['.css'], [postcss])); + config.module.rules.push(stylesWithModulesRule(['.sass', '.scss'], [postcss, 'sass-loader'])); + // Fonts. + config.module.rules.push({ + generator: { + filename: 'assets/[hash][ext][query]', + }, + test: /\.(eot|ttf|woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, + type: 'asset', + }); + // Images. + config.module.rules.push({ + generator: { + filename: 'assets/[hash][ext][query]', + }, + test: /\.(ico|png|jpg|jpeg|gif|svg|webp)(\?v=\d+\.\d+\.\d+)?$/, + type: 'asset', }); - config.use.push(fontLoader()); - config.use.push(imageLoader()); }; export default augmentBuild; diff --git a/packages/web/src/server/build/dev-server.js b/packages/web/src/server/build/dev-server.js deleted file mode 100644 index abbdb97..0000000 --- a/packages/web/src/server/build/dev-server.js +++ /dev/null @@ -1,27 +0,0 @@ -const devServer = require('@neutrinojs/dev-server'); - -module.exports = (flecks) => (neutrino) => { - const { - devHost, - devPort, - devPublic, - devStats, - port, - public: $$public, - } = flecks.get('@flecks/web/server'); - neutrino.use(devServer({ - historyApiFallback: { - disableDotRule: true, - }, - hot: false, - host: devHost, - port: devPort || (port + 1), - public: devPublic || $$public, - stats: { - ...devStats, - warningsFilter: [ - /Failed to parse source map/, - ], - }, - })); -}; diff --git a/packages/web/src/server/build/runtime.js b/packages/web/src/server/build/runtime.js index 2b6e698..0f13d0a 100644 --- a/packages/web/src/server/build/runtime.js +++ b/packages/web/src/server/build/runtime.js @@ -10,7 +10,7 @@ const glob = require('glob'); const debug = D('@flecks/web/runtime'); -module.exports = async (flecks) => { +module.exports = async (config, env, argv, flecks) => { debug('bootstrapping flecks...'); const webFlecks = Flecks.bootstrap({ platforms: ['client', '!server'], @@ -55,119 +55,117 @@ module.exports = async (flecks) => { ) .filter((filename) => !!filename); const runtime = await realpath(R.resolve(join(webFlecks.resolve('@flecks/web'), 'runtime'))); - const tests = await realpath(R.resolve( - join(webFlecks.resolve('@flecks/web'), 'server', 'build', 'tests'), - )); - const testsSource = (await readFile(tests)).toString(); - return (neutrino) => { - const {config} = neutrino; - const {resolver} = webFlecks; - const isProduction = 'production' === config.get('mode'); - const paths = Object.entries(resolver); - const source = [ - 'module.exports = (update) => (async () => ({', - " config: window[Symbol.for('@flecks/web.config')],", - ' flecks: Object.fromEntries(await Promise.all([', - paths - .map(([path]) => [ - ' [', - ` '${path}',`, - ` import('${path}').then((M) => (update(${paths.length}, '${path}'), M)),`, - ' ]', - ].join('\n')) - .join(',\n'), - ' ].map(async ([path, M]) => [path, await M]))),', - " platforms: ['client'],", - '}))();', - '', - ]; - // HMR. - source.push('if (module.hot) {'); - paths.forEach(([path]) => { - source.push(` module.hot.accept('${path}', async () => {`); - source.push(` const updatedFleck = require('${path}');`); - source.push(` window.flecks.refresh('${path}', updatedFleck);`); - source.push(` window.flecks.invoke('@flecks/core.hmr', '${path}', updatedFleck);`); - source.push(' });'); - }); - source.push('}'); - source.push(''); - // Create runtime. - config.module - .rule(runtime) - .test(runtime) - .use('runtime/web') - .loader(runtime) - .options({ - source: source.join('\n'), + const {resolver} = webFlecks; + const isProduction = 'production' === argv.mode; + const paths = Object.entries(resolver); + const source = [ + 'module.exports = (update) => (async () => ({', + " config: window[Symbol.for('@flecks/web.config')],", + ' flecks: Object.fromEntries(await Promise.all([', + paths + .map(([path]) => [ + ' [', + ` '${path}',`, + ` import('${path}').then((M) => (update(${paths.length}, '${path}'), M)),`, + ' ]', + ].join('\n')) + .join(',\n'), + ' ].map(async ([path, M]) => [path, await M]))),', + " platforms: ['client'],", + '}))();', + '', + ]; + // HMR. + source.push('if (module.hot) {'); + paths.forEach(([path]) => { + source.push(` module.hot.accept('${path}', async () => {`); + source.push(` const updatedFleck = require('${path}');`); + source.push(` window.flecks.refresh('${path}', updatedFleck);`); + source.push(` window.flecks.invoke('@flecks/core.hmr', '${path}', updatedFleck);`); + source.push(' });'); + }); + source.push('}'); + source.push(''); + // Create runtime. + config.module.rules.push({ + test: runtime, + use: [ + { + loader: runtime, + options: { + source: source.join('\n'), + }, + }, + ], + }); + config.resolve.alias['@flecks/web/runtime$'] = runtime; + flecks.runtimeCompiler(webFlecks.resolver, 'web', config); + // Aliases. + const aliases = webFlecks.aliases(); + if (Object.keys(aliases).length > 0) { + Object.entries(aliases) + .forEach(([from, to]) => { + config.resolve.alias[from] = to; }); - config.resolve.alias - .set('@flecks/web/runtime$', runtime); - flecks.runtimeCompiler(webFlecks.resolver, 'web', neutrino); - // Aliases. - const aliases = webFlecks.aliases(); - if (Object.keys(aliases).length > 0) { - Object.entries(aliases) - .forEach(([from, to]) => { - config.resolve.alias - .set(from, to); - }); - } - // Styles. - const entries = config.entry('index'); - styles.forEach((style) => { - entries.add(style); - }); - // Tests. - if (!isProduction) { - const testPaths = []; - roots.forEach(([fleck, root]) => { - testPaths.push(...( - glob.sync(join(root, 'test/*.js')) - .map((path) => [fleck, path]) - )); - for (let i = 0; i < webFlecks.platforms.length; ++i) { - testPaths.push( - ...( - glob.sync(join(root, `test/platforms/${webFlecks.platforms[i]}/*.js`)) - .map((path) => [fleck, path]) - ), - ); - } - }); - config.module - .rule(tests) - .test(tests) - .use('runtime/test') - .loader(runtime) - .options({ - source: testsSource.replace( - "await import('@flecks/web/tests');", - [ - 'const tests = {};', - Object.entries( - testPaths - .reduce( - (r, [fleck, path]) => ({ - ...r, - [fleck]: [...(r[fleck] || []), `require('${path}');`], - }), - {}, - ), - ) - .map( - ([original, paths]) => ( - [ - `describe('${original}', () => {`, - ` ${paths.join('\n ')}`, - '});', - ].join('\n') - ), - ).join('\n'), - 'await Promise.all(Object.values(tests));', - ].join('\n'), + } + // Styles. + config.entry.index.push(...styles); + // Tests. + if (!isProduction) { + const testPaths = []; + roots.forEach(([fleck, root]) => { + testPaths.push(...( + glob.sync(join(root, 'test/*.js')) + .map((path) => [fleck, path]) + )); + for (let i = 0; i < webFlecks.platforms.length; ++i) { + testPaths.push( + ...( + glob.sync(join(root, `test/platforms/${webFlecks.platforms[i]}/*.js`)) + .map((path) => [fleck, path]) ), - }); - } - }; + ); + } + }); + const tests = await realpath(R.resolve( + join(webFlecks.resolve('@flecks/web'), 'server', 'build', 'tests'), + )); + const testsSource = (await readFile(tests)).toString(); + config.module.rules.push({ + test: tests, + use: [ + { + loader: runtime, + options: { + source: testsSource.replace( + "await import('@flecks/web/tests');", + [ + 'const tests = {};', + Object.entries( + testPaths + .reduce( + (r, [fleck, path]) => ({ + ...r, + [fleck]: [...(r[fleck] || []), `require('${path}');`], + }), + {}, + ), + ) + .map( + ([original, paths]) => ( + [ + `describe('${original}', () => {`, + ` ${paths.join('\n ')}`, + '});', + ].join('\n') + ), + ).join('\n'), + 'await Promise.all(Object.values(tests));', + ].join('\n'), + ), + }, + }, + ], + }); + } }; diff --git a/packages/web/src/server/build/template.ejs b/packages/web/src/server/build/template.ejs index 0e86ab7..cfcb63a 100644 --- a/packages/web/src/server/build/template.ejs +++ b/packages/web/src/server/build/template.ejs @@ -5,11 +5,10 @@ <%= htmlWebpackPlugin.options.title %> - <% if (styleFile) { %> - - <% } %> + <%= htmlWebpackPlugin.tags.headTags %> + <% styleFiles.forEach(({content, href}) => { %> + + <% }); %>
diff --git a/packages/web/src/server/build/wait-for-manifest.js b/packages/web/src/server/build/wait-for-manifest.js index 3b4046f..1f18b9c 100644 --- a/packages/web/src/server/build/wait-for-manifest.js +++ b/packages/web/src/server/build/wait-for-manifest.js @@ -17,7 +17,9 @@ class WaitForManifestPlugin extends WebpackBeforeBuildPlugin { } catch (error) { // eslint-disable-next-line no-await-in-loop - await new Promise((resolve) => setTimeout(resolve, 1000)); + await new Promise((resolve) => { + setTimeout(resolve, 1000); + }); } } }, ['beforeCompile']); diff --git a/packages/web/src/server/build/web-vendor.neutrinorc.js b/packages/web/src/server/build/web-vendor.neutrinorc.js deleted file mode 100644 index 8fdf559..0000000 --- a/packages/web/src/server/build/web-vendor.neutrinorc.js +++ /dev/null @@ -1,79 +0,0 @@ -const {join} = require('path'); - -const {require: R} = require('@flecks/core/server'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -module.exports = async (flecks) => { - const config = { - options: { - output: join( - FLECKS_CORE_ROOT, - 'node_modules', - '.cache', - 'flecks', - ), - root: FLECKS_CORE_ROOT, - }, - use: [ - ({config, options}) => { - const dll = flecks.get('@flecks/web/server.dll'); - if (dll.length > 0) { - // Build the library and manifest. - config.context(options.root); - const entries = config.entry('index').clear(); - dll.forEach((module) => { - entries.add(module); - }); - config - .plugin('dll') - .use( - R.resolve('webpack/lib/DllPlugin'), - [ - { - context: options.root, - path: join(options.output, 'web-vendor.manifest.json'), - name: 'flecks_web_vendor', - }, - ], - ); - // Output. - config - .devtool('cheap-module-source-map'); - config.output - .path(options.output) - .library('flecks_web_vendor') - .filename('web-vendor.js'); - config.node - .set('fs', 'empty'); - // Resolution. - config.resolve.extensions - .merge([ - '.wasm', - ...options.extensions.map((ext) => `.${ext}`), - '.json', - ]); - config.module - .rule('mjs') - .test(/\.mjs$/) - .include - .add(/node_modules/) - .end() - .type('javascript/auto'); - config.resolve.modules - .merge([join(FLECKS_CORE_ROOT, 'node_modules')]); - // Reporting. - config.stats({ - ...flecks.get('@flecks/web/server.stats'), - warningsFilter: [ - /Failed to parse source map/, - ], - }); - } - }, - ], - }; - return config; -}; diff --git a/packages/web/src/server/build/web-vendor.webpack.config.js b/packages/web/src/server/build/web-vendor.webpack.config.js new file mode 100644 index 0000000..d8089fc --- /dev/null +++ b/packages/web/src/server/build/web-vendor.webpack.config.js @@ -0,0 +1,56 @@ +const {join} = require('path'); + +const {defaultConfig, require: R, webpack} = require('@flecks/core/server'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); + +const { + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; + +module.exports = async (env, argv, flecks) => { + const config = defaultConfig(flecks, { + output: { + clean: false, + path: join(FLECKS_CORE_ROOT, 'node_modules', '.cache', '@flecks', 'web', 'vendor'), + library: 'flecks_web_vendor', + filename: 'web-vendor.js', + }, + plugins: [ + // `config.clean` wipes out the manifest... + new CleanWebpackPlugin({ + cleanStaleWebpackAssets: false, + }), + new webpack.ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + process: 'process/browser', + }), + ], + resolve: { + fallback: { + child_process: false, + fs: false, + path: R.resolve('path-browserify'), + process: R.resolve('process/browser'), + stream: false, + }, + }, + stats: { + warningsFilter: [ + /Failed to parse source map/, + ], + ...flecks.get('@flecks/web/server.stats'), + }, + }); + const dll = flecks.get('@flecks/web/server.dll'); + if (dll.length > 0) { + // Build the library and manifest. + config.entry.index = dll; + config.plugins.push( + new webpack.DllPlugin({ + path: join(config.output.path, 'manifest.json'), + name: 'flecks_web_vendor', + }), + ); + } + return config; +}; diff --git a/packages/web/src/server/build/web.neutrinorc.js b/packages/web/src/server/build/web.neutrinorc.js deleted file mode 100644 index e887500..0000000 --- a/packages/web/src/server/build/web.neutrinorc.js +++ /dev/null @@ -1,201 +0,0 @@ -const {dirname, join} = require('path'); -const {realpath} = require('fs/promises'); - -const {require: R} = require('@flecks/core/server'); -const htmlLoader = require('@neutrinojs/html-loader'); -const htmlTemplate = require('@neutrinojs/html-template'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); -const {EnvironmentPlugin} = require('webpack'); - -const devServer = require('./dev-server'); -const runtime = require('./runtime'); -const WaitForManifestPlugin = require('./wait-for-manifest'); - -const { - FLECKS_CORE_ROOT = process.cwd(), -} = process.env; - -module.exports = async (flecks) => { - // Build configuration. - const build = async () => { - const root = await realpath( - dirname(R.resolve(join(flecks.resolve('@flecks/web'), 'package.json'))), - ); - return (neutrino) => { - const {config, options} = neutrino; - const isProduction = 'production' === config.get('mode'); - // Environment. - config - .plugin('environment') - .use(EnvironmentPlugin, [{ - FLECKS_CORE_BUILD_TARGET: 'web', - }]); - // Entrypoints. - const {output: originalOutput} = options; - options.mains.index = join(root, 'server', 'build', 'entry'); - options.mains.tests = { - entry: join(root, 'server', 'build', 'tests'), - title: 'Testbed', - }; - options.output = join(originalOutput, flecks.get('@flecks/web/server.output')); - // Load HTML. - neutrino.use(htmlLoader()); - Object.entries(options.mains).forEach(([name, mainsConfig]) => { - const {entry, ...htmlTemplateConfig} = mainsConfig; - config.entry(name).add(entry); - neutrino.use( - htmlTemplate({ - chunks: [name], - filename: `${name}.html`, - inject: false, - pluginId: `html-${name}`, - template: flecks.buildConfig('template.ejs', name), - templateParameters: (compilation, assets, assetTags, options) => { - let styleFile; - const styleChunk = compilation.chunks.find((chunk) => ( - chunk.chunkReason?.match(/split chunk \(cache group: styles\)/) - )); - if (isProduction && styleChunk) { - const modules = styleChunk.getModules(); - const styleFileHref = join( - compilation.options.output.publicPath, - styleChunk.files.find((file) => file.match(/\.css$/)), - ); - styleFile = { - href: styleFileHref, - content: ( - modules - .filter((module) => 'css/mini-extract' === module.type) - .map(({content}) => content).join('\n') - ), - }; - } - return { - compilation, - webpackConfig: compilation.options, - htmlWebpackPlugin: { - tags: assetTags, - files: assets, - options, - }, - styleFile, - }; - }, - ...htmlTemplateConfig, - }), - ); - }); - // Install source-map-support and fold in existing source maps. - config.entry('index') - .add('source-map-support'); - config.module - .rule('maps') - .test(/\.js$/) - .enforce('pre') - .use('source-map-loader') - .loader('source-map-loader'); - // Optimization. - config.optimization - .minimize(isProduction) - .splitChunks({ - chunks: 'all', - name: !isProduction, - cacheGroups: { - styles: { - name: !isProduction, - test: /\.(c|s[ac])ss$/, - chunks: 'all', - enforce: true, - priority: 100, - }, - }, - }) - .runtimeChunk('single'); - // Output. - config.output - .chunkFilename(isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js') - .path(options.output) - .publicPath('/') - .filename(isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js'); - config - .devtool(isProduction ? 'source-map' : 'cheap-module-source-map') - .target('web'); - config.node - .set('Buffer', true) - .set('fs', 'empty') - .set('tls', 'empty') - .set('__dirname', false) - .set('__filename', false); - // Resolution. - config.resolve.extensions - .merge([ - '.wasm', - ...options.extensions.map((ext) => `.${ext}`), - '.json', - ]); - config.resolve.modules - .merge([join(FLECKS_CORE_ROOT, 'node_modules')]); - // Reporting. - config.stats({ - ...flecks.get('@flecks/web/server.stats'), - warningsFilter: [ - /Failed to parse source map/, - ], - }); - // Inline the main entrypoint (nice for FCP). - config - .plugin('inline-chunks') - .use(InlineChunkHtmlPlugin, [HtmlWebpackPlugin, [/^assets\/index(\.[^.]*)?\.js$/]]); - const dll = flecks.get('@flecks/web/server.dll'); - if (!isProduction && dll.length > 0) { - const manifest = join( - FLECKS_CORE_ROOT, - 'node_modules', - '.cache', - 'flecks', - 'web-vendor', - ); - config - .plugin('wait-for-manifest') - .use(WaitForManifestPlugin, [`${manifest}.manifest.json`]); - config - .plugin('dll') - .use( - R.resolve('webpack/lib/DllReferencePlugin'), - [ - { - context: FLECKS_CORE_ROOT, - manifest: `${manifest}.manifest.json`, - }, - ], - ); - config - .plugin('include-dll') - .use( - R.resolve('add-asset-html-webpack-plugin'), - [ - { - filepath: `${manifest}.js`, - }, - ], - ); - } - }; - }; - // Neutrino configuration. - const config = { - options: { - output: 'dist', - root: FLECKS_CORE_ROOT, - }, - use: [ - await build(), - ], - }; - // Configure dev server. - config.use.push(devServer(flecks)); - // Build the client runtime. - config.use.push(await runtime(flecks)); - return config; -}; diff --git a/packages/web/src/server/build/web.webpack.config.js b/packages/web/src/server/build/web.webpack.config.js new file mode 100644 index 0000000..aa64e7a --- /dev/null +++ b/packages/web/src/server/build/web.webpack.config.js @@ -0,0 +1,190 @@ +const {join} = require('path'); + +const { + defaultConfig, + regexFromExtensions, + require: R, + webpack, +} = require('@flecks/core/server'); +const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); + +const runtime = require('./runtime'); +const WaitForManifestPlugin = require('./wait-for-manifest'); + +const { + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; + +module.exports = async (env, argv, flecks) => { + const { + devHost, + devPort, + devStats, + port, + } = flecks.get('@flecks/web/server'); + const isProduction = 'production' === argv.mode; + const plugins = [ + // Environment. + new webpack.EnvironmentPlugin({ + FLECKS_CORE_BUILD_TARGET: 'web', + }), + new webpack.ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + process: 'process/browser', + }), + // Inline the main entrypoint (nice for FCP). + new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/^assets\/index(\.[^.]*)?\.js$/]), + ]; + // DLL + const dll = flecks.get('@flecks/web/server.dll'); + if (!isProduction && dll.length > 0) { + const manifest = join(FLECKS_CORE_ROOT, 'node_modules', '.cache', '@flecks', 'web', 'vendor'); + plugins.push(new WaitForManifestPlugin(join(manifest, 'manifest.json'))); + plugins.push( + new webpack.DllReferencePlugin({ + manifest: join(manifest, 'manifest.json'), + }), + ); + plugins.push( + new AddAssetHtmlPlugin({ + filepath: join(manifest, 'web-vendor.js'), + outputPath: '/assets', + publicPath: '/assets', + }), + ); + } + const entry = {}; + [ + ['index', { + entry: '@flecks/web/server/build/entry', + }], + ['tests', { + entry: '@flecks/web/server/build/tests', + title: 'Testbed', + }], + ] + .forEach(([name, mainsConfig]) => { + const {entry: entryPoint, ...htmlTemplateConfig} = mainsConfig; + // @todo source maps working? + entry[name] = [entryPoint]; + plugins.push(new HtmlWebpackPlugin({ + appMountId: 'root', + chunks: [name], + filename: `${name}.html`, + inject: false, + lang: 'en', + template: flecks.buildConfig('template.ejs', name), + templateParameters: (compilation, assets, assetTags, options) => { + const styleFiles = []; + const styleChunk = Array.from(compilation.chunks).find((chunk) => ( + chunk.chunkReason?.match(/split chunk \(cache group: styles\)/) + )); + if (isProduction && styleChunk) { + for (let i = 0; i < assets.css.length; ++i) { + const asset = compilation.assets[assets.css[i].substring(1)]; + if (asset) { + styleFiles.push({content: asset.source(), href: assets.css[i]}); + assetTags.headTags = assetTags.headTags + .filter(({attributes}) => attributes?.href !== assets.css[i]); + } + } + } + return { + compilation, + webpackConfig: compilation.options, + htmlWebpackPlugin: { + tags: assetTags, + files: assets, + options, + }, + styleFiles, + }; + }, + ...htmlTemplateConfig, + })); + }); + // @todo dynamic extensions + const styleExtensionsRegex = regexFromExtensions(['.css', '.sass', '.scss']); + const config = defaultConfig(flecks, { + devServer: { + compress: false, + devMiddleware: { + stats: { + ...devStats, + warningsFilter: [ + /Failed to parse source map/, + ], + }, + }, + historyApiFallback: { + disableDotRule: true, + }, + hot: false, + host: devHost, + port: devPort || (port + 1), + }, + devtool: 'source-map', + entry, + module: { + rules: [ + // HTML. + { + test: /\.html$/, + use: ['html-loader'], + }, + // Fold in existing source maps. + { + enforce: 'pre', + test: styleExtensionsRegex, + use: ['source-map-loader'], + }, + ], + }, + optimization: { + minimize: isProduction, + runtimeChunk: 'single', + splitChunks: { + cacheGroups: { + styles: { + chunks: 'all', + enforce: true, + priority: 100, + test: styleExtensionsRegex, + }, + }, + chunks: 'all', + ...(isProduction ? {name: false} : undefined), + }, + }, + output: { + chunkFilename: isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js', + filename: isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js', + path: join(FLECKS_CORE_ROOT, 'dist', flecks.get('@flecks/web/server.output')), + publicPath: '/', + }, + plugins, + resolve: { + fallback: { + buffer: R.resolve('buffer'), + child_process: false, + fs: false, + path: R.resolve('path-browserify'), + process: R.resolve('process/browser'), + stream: R.resolve('stream-browserify'), + zlib: R.resolve('browserify-zlib'), + }, + }, + stats: { + ...flecks.get('@flecks/web/server.stats'), + warningsFilter: [ + /Failed to parse source map/, + ], + }, + target: 'web', + }); + // Build the client runtime. + await runtime(config, env, argv, flecks); + return config; +}; diff --git a/packages/web/src/server/http.js b/packages/web/src/server/http.js index ee66b1d..3303af5 100644 --- a/packages/web/src/server/http.js +++ b/packages/web/src/server/http.js @@ -79,12 +79,26 @@ export const createHttpServer = async (flecks) => { }); proxy.on('error', (error, req, res) => { if (res instanceof ServerResponse) { + debug('webpack-dev-server proxy failed, got: %s', error.message); + if ('ECONNREFUSED' === error.code) { + debug('retrying in 1 second...'); + setTimeout(() => { + proxy.web(req, res, {selfHandleResponse: true}); + }, 1000); + return; + } res.status(502).end('Bad Gateway (WDS)'); } }); - app.all('*', (req, res) => proxy.web(req, res, {selfHandleResponse: true})); - httpServer.on('upgrade', (req, socket, head) => proxy.ws(req, socket, head)); - httpServer.on('close', () => proxy.close()); + app.all('*', (req, res) => { + proxy.web(req, res, {selfHandleResponse: true}); + }); + httpServer.on('upgrade', (req, socket, head) => { + proxy.ws(req, socket, head); + }); + httpServer.on('close', () => { + proxy.close(); + }); } else { // Serve the document root, sans index. diff --git a/packages/web/src/server/index.js b/packages/web/src/server/index.js index 413829d..d2fdbd4 100644 --- a/packages/web/src/server/index.js +++ b/packages/web/src/server/index.js @@ -18,18 +18,19 @@ export {augmentBuild}; export const hooks = { '@flecks/core.build': augmentBuild, - '@flecks/core.build.alter': async (neutrinoConfigs, flecks) => { + '@flecks/core.build.alter': async (configs, env, argv, flecks) => { // Don't build if there's a fleck target. - if (neutrinoConfigs.fleck && !flecks.get('@flecks/web/server.forceBuildWithFleck')) { + if (configs.fleck && !flecks.get('@flecks/web/server.forceBuildWithFleck')) { // eslint-disable-next-line no-param-reassign - delete neutrinoConfigs.web; + delete configs.web; return; } + const isProduction = 'production' === argv.mode; // Only build vendor in dev. - if (neutrinoConfigs['web-vendor']) { - if (process.argv.find((arg) => 'production' === arg)) { + if (configs['web-vendor']) { + if (isProduction) { // eslint-disable-next-line no-param-reassign - delete neutrinoConfigs['web-vendor']; + delete configs['web-vendor']; } // Only build if something actually changed. const dll = flecks.get('@flecks/web/server.dll'); @@ -38,8 +39,10 @@ export const hooks = { FLECKS_CORE_ROOT, 'node_modules', '.cache', - 'flecks', - 'web-vendor.manifest.json', + '@flecks', + 'web', + 'vendor', + 'manifest.json', ); let timestamp = 0; try { @@ -63,7 +66,7 @@ export const hooks = { } if (timestamp > latest) { // eslint-disable-next-line no-param-reassign - delete neutrinoConfigs['web-vendor']; + delete configs['web-vendor']; } else if (timestamp > 0) { await unlink(manifest); @@ -71,7 +74,7 @@ export const hooks = { } } // Bail if there's no web build. - if (!neutrinoConfigs.web) { + if (!configs.web) { return; } // Bail if the build isn't watching. @@ -80,10 +83,10 @@ export const hooks = { } // Otherwise, spawn `webpack-dev-server` (WDS). const cmd = [ - 'npx', 'webpack-dev-server', + 'npx', 'webpack', 'serve', '--mode', 'development', '--hot', - '--config', flecks.buildConfig('webpack.config.js'), + '--config', flecks.buildConfig('fleckspack.config.js'), ]; spawnWith( cmd, @@ -95,7 +98,7 @@ export const hooks = { ); // Remove the build config since we're handing off to WDS. // eslint-disable-next-line no-param-reassign - delete neutrinoConfigs.web; + delete configs.web; }, '@flecks/core.build.config': () => [ /** @@ -136,10 +139,8 @@ export const hooks = { * (webpack-dev-server) Webpack stats output. */ devStats: { - assets: false, - chunks: false, colors: true, - modules: false, + errorDetails: true, }, /** * Modules to externalize using `webpack.DllPlugin`. @@ -166,13 +167,11 @@ export const hooks = { */ public: 'localhost:32340', /** - * Webpack stats configuration when building HTTP target. + * Webpack stats configuration. */ stats: { - children: false, - chunks: false, colors: true, - modules: false, + errorDetails: true, }, /** * Proxies to trust.